Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


  • 0

Decode data from http:request


FonsBrand

Question

I try to get some data from a http:request in a LUA scene.

 

I have the following code:

local strLonoID = fibaro:getGlobalValue ("LonoID");
print ("LonoID = ", strLonoID)
local Temp1 = fibaro:getGlobalValue ("LonoTemp1");
print ("LonoTemp1 = ", Temp1)


local http = net.HTTPClient()  
    http:request('http://lonobox.com/api/index.php?id=100003523', {
    success = function(current)
    --fibaro:debug(json.encode(current))                        --werkt
    if current.status == 200 then
        print('Data Receiving: ', current.status)           -- werkt
        print('CurrentData: ', current.data)                -- werkt
        local result = json.decode(current.data)
        print ('Result :', result)
        --Local temp2 = result.(["CurrentData"]["200003523"]["temperature"])
        --local temp2 = result.200003523.temperature
        --print ('Temp2 :', temp2)
        
        --
        else
        fibaro:debug(current.status)
        end
    end
    })

 

and i have as output:

[DEBUG] 17:13:32: LonoID = 100003523
[DEBUG] 17:13:32: LonoTemp1 = 2
[DEBUG] 17:13:32: Data Receiving: 200
[DEBUG] 17:13:32: CurrentData: [[],{"200003523":{"temperature":"23.2","humidity":"46"}},{"400004105":{"wind-speed":"0.2","wind-gust":"1.5","wind-direction":"SE"}},{"100003523":{"barometer":"1014"}}]
[DEBUG] 17:13:32: Result : table: 0x9c98200

 

I want to store the values in global variables.
I do not know how to proceed from here.

 

Thx in advance.

Fons

Edited by FonsBrand
grammatical update
Link to comment
Share on other sites

15 answers to this question

Recommended Posts

  • 0

You can use fibaro:setGlobal('your global var',result.(["CurrentData"]["200003523"]["temperature"]) );

Or are you not able to extract the spesific values you want? If so it is useful to use a json decoder(jason parser online etc) to have a better look at "where" the values are.

Should be something like this: local humidity = result.2000003523.humidity

 

 

Regards Morten

Edited by mortesan
Link to comment
Share on other sites

  • 0
  • Inquirer
  • Thanks Morten for your reaction.

     

    It is intended that I can save the parameters below in a Globalvariable.

    ----

    This is the output of JSON via POSTMAN:

    [
        [],
        {
            "200003523": {
                "temperature": "29.1",
                "humidity": "44"
            }
        },
        {
            "400004105": {
                "wind-speed": "0",
                "wind-gust": "1.3",
                "wind-direction": "ESE"
            }
        },
        {
            "100003523": {
                "barometer": "1020"
            }
        }
    ]

    ----

    But I do not know how to filter these variables from that JSON table.
    If I try the different commands below, I get either an error message or a nil value.

     

    local temp2 = result.(["CurrentData"]["200003523"]["temperature"])
    local temp2 = result.200003523.temperature

     

    If I put the values from the JSON table on probability in a local variable, then I can save them with the following commands in a global variable.

    fibaro:setGlobal("LonoTemp1", temp1);

    fibaro:setGlobal("LonoBaro1", baro1);
    fibaro:setGlobal("LonoHum1", humi1);
    fibaro:setGlobal("LonoRain1", rain1);
    fibaro:setGlobal("LonoWindDir1", windd1);
    fibaro:setGlobal("LonoWindSpeed1", winds1);

     

    Link to comment
    Share on other sites

    • 0

    You could try the following: 

    local temp2 = tostring(result[0].2000003523.temperature)

     

    Here is an example from a scene that I use, where i fetch the current price info:

     

    local result = json.decode(resp.result);

     

    The table:

     {"data":{"viewer":{"homes":[{"currentSubscription":{"priceInfo":{"current":{"total":0.4538,"energy":0.363,"tax":0.0908,"startsAt":"2018-05-24T05:00:00+02:00"}}}}]}}}

     

    I then put the value in a global var: 

    fibaro:setGlobal('Strompris', result.data.viewer.homes[1].currentSubscription.priceInfo.current.total);

     

    Maybe this could help you figure it out.

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • Hi Morten,

     

    I have tried your suggestion:

    local temp2 = tostring(result[0].200003523.temperature)

     

    but get an error message:
    [DEBUG] 06:19:49: [1;31m2018-05-25 06:19:49.817821 [ fatal] Unknown exception: /opt/fibaro/scenes/149.lua:24: malformed number near '.200003523.'

     

    I have been playing around with different values, but without success.

     

    Regards Fons.

    Edited by FonsBrand
    Link to comment
    Share on other sites

    • 0

    It's a bit tricky, because the records itself are in a table (so "a table in a table"). Try this...

     

    Please login or register to see this code.

     

    The actual structure of your data looks like this (all key/value pairs):

     

    Please login or register to see this code.

    So, for sake of completeness, this will work:

     

    Please login or register to see this code.

    But I guess there is no guarantee that this particular measurement will always be in [2] I do not think it can be used.

    • Like 1
    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • Hi

    Please login or register to see this link.

     

    Thank You.

    With your directions I made a working code.

     

    Also Morten thanks for your input.

     

    All Regards!

     

    Fons

    =====================================

    --[[
    %% properties
    %% events
    %% globals
    --]]


    local http = net.HTTPClient()  
            http:request('http://lonobox.com/api/index.php?id=100003523', {
            success = function(current)
        
            fibaro:debug(json.encode(current))                    --werkt
            if current.status == 200 then
           --print('Status Receiving: ', current.status)           -- 200 OK
            
            local data = current.data
           --print('CurrentData: ', data)                                     -- Data
            
            local table = json.decode(current.data)               -- Table
            --print ('Result :', table)
                 
            -- Turn the JSON data into a table structure
            t=json.decode(data)
           -- print ('t :', t)                                                          

            --getLonoBox tries to find "fieldName" under
            --a dataset "recordId" in the table "data"
            function getLonoBox(data,recordId,fieldName)
                  for _,record in ipairs(data) do
                    for k,v in pairs(record) do
                          if k==recordId then
                            return v[fieldName]
                          end
                    end
                  end
            end
            local strbaro = getLonoBox(t,"100003523", "barometer")
            print ('strbaro :', strbaro)          
            local strTemp = getLonoBox(t,"200003523", "temperature")
            print ('strTemp :', strTemp)        
            local strHumid = getLonoBox(t,"200003523", "humidity")
            print ('strHumid :', strHumid)
            local strWinD =  getLonoBox(t,"400004105", "wind-direction")
            print ('strWinD :', strWinD)
            local strWinS =  getLonoBox(t,"400004105", "wind-speed")
            print ('strWinS :', strWinS)
            local strWinG =  getLonoBox(t,"400004105", "wind-gust")        
            print ('strWinG :', strWinG)        
          
            fibaro:setGlobal("LonoBaro1", strbaro);
            fibaro:setGlobal("LonoTemp1", strTemp);
            fibaro:setGlobal("LonoHum1", strHumid);
            --fibaro:setGlobal("LonoRain1", rain1);
            fibaro:setGlobal("LonoWindDir1", strWinD);
            fibaro:setGlobal("LonoWindSpeed1", strWinS);
            fibaro:setGlobal("LonoWindGust1", strWinG);
            else
            fibaro:debug(current.status)
            end
        end
    })

     

    ========================

    The only thing where I am now looking for is, how to retrieve the date from the header?

     

     [DEBUG] 22:12:28: {"headers":{"X-Varnish":"6419305","Via":"1.1 varnish-v4","Server":"Apache\/2.4.33 (Ubuntu)","Age":"0","Content-Length":"166","Accept-Ranges":"bytes","Content-Type":"text\/html; charset=UTF-8","Date":"Fri, 25 May 2018 20:11:31 GMT","Connection":"close","Vary":"Accept-Encoding"},"status":200,"data":"[[],{\"200003523\":{\"temperature\":\"22.4\",\"humidity\":\"66\"}},{\"400004105\":{\"wind-speed\":\"0\",\"wind-gust\":\"0.7\",\"wind-direction\":\"NNE\"}},{\"100003523\":{\"barometer\":\"1019\"}}]"}

     

    Regards,

    Fons

    Edited by FonsBrand
    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • The only thing where I am now looking for is, how to retrieve the date from the header?

     

     [DEBUG] 22:12:28: {"headers":{"X-Varnish":"6419305","Via":"1.1 varnish-v4","Server":"Apache\/2.4.33 (Ubuntu)","Age":"0","Content-Length":"166","Accept-Ranges":"bytes","Content-Type":"text\/html; charset=UTF-8","Date":"Fri, 25 May 2018 20:11:31 GMT","Connection":"close","Vary":"Accept-Encoding"},"status":200,"data":"[[],{\"200003523\":{\"temperature\":\"22.4\",\"humidity\":\"66\"}},{\"400004105\":{\"wind-speed\":\"0\",\"wind-gust\":\"0.7\",\"wind-direction\":\"NNE\"}},{\"100003523\":{\"barometer\":\"1019\"}}]"}

      

    Regards,

    Fons

    Link to comment
    Share on other sites

    • 0

    Assuming you still use

      success = function(current)

     

    As in your previous post, then this should do the trick

      print ("Date:", current.headers.Date)

     

    If this works, you can always thank me by clicking the "like" button on my post(s). It's a hobby, and the "likes" really make me happy...

    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • 2 hours ago, petergebruers said:

    Assuming you still use

      success = function(current)

     

    As in your previous post, then this should do the trick

      print ("Date:", current.headers.Date) 

     

    If this works, you can always thank me by clicking the "like" button on my post(s). It's a hobby, and the "likes" really make me happy...

     

    Hi petergebruers,

     

    the print command works but I want to store it in a variable.

    Local strDate = print ("Date:", current.headers.Date) <- is not working

    Local strDate = print (current.headers.Date)               <- is not working

    Local strDate = (current.headers.Date)                        <- is not working

     

     

    Regards,

    Fons

    Edited by FonsBrand
    Link to comment
    Share on other sites

    • 0

    Hmm. The last one should work. I cannot run your scene, so I have to simulate it, and for me this works:

     

    (this is runnable code)

     

    Please login or register to see this code.

     

    If that does not work.. can you tell me what this does if you paste this code instead of that strDate (so the line where you want to retrieve that date):

     

    Please login or register to see this code.

    For my simulated data, the output looks similar (but not exactly the same) to this:

     

    Please login or register to see this code.

    As you might have guessed, it starts at the top of the table named "current" and displays the structure and contents.

     

    You see:

      k=headers, then k=Date

    so the field you are interested in should be:

      current.headers.Date

     

    Good luck!

     

    • Like 1
    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • Hi petergebruers,

     

    I have tried your code, but I do not get any output.

     

    The code

    =================================

    --[[
    %% properties
    %% events
    %% globals
    time5min
    --]]
    local currentDate = os.date("*t");  -- start time5min
    if (((tonumber(os.date("%H%M")) >= tonumber(string.format("%02d%02d", "00", "00")) and tonumber(os.date("%H%M")) <= tonumber(string.format("%02d%02d", "23", "59"))) and (math.floor(os.time()/60)-math.floor(1421017200/60))%1 == 0 )) then

    local http = net.HTTPClient() 
      http:request('http://lonobox.com/api/index.php?id=100003523', {
      success = function(current)
     
          --fibaro:debug(json.encode(current))    -- OK
      if current.status == 200 then
             --print('Status Receiving: ', current.status)     -- 200 OK
           
         local data = current.data
             --print('CurrentData: ', data)     -- Data
           
          local table = json.decode(current.data)    -- Table
             --print ('Result :', table)
                
      function printTbl (tbl,prefix)     -- OK
        if not tbl then print("table is nil") return end
         prefix = prefix or ""
         for k, v in pairs(tbl) do
           print(string.format("%sk=%s, v=%s",prefix,tostring(k),tostring(v)))
           if type(v) == "table" then
              printTbl(v, prefix.." ")
           end
         end
      end
      printTbl(current)
             
            print ("Date:", current.headers.Date)     -- OK
             local strDate = current.headers.Date      -- NOK

             Print ('Date :', strDate)     -- NOK 
             
             
      -- Turn the JSON data into a table structure
      t=json.decode(data)     -- OK
             --print ('t :', t)

      --getLonoBox tries to find "fieldName" under
      --a dataset "recordId" in the table "data"
      function getLonoBox(data,recordId,fieldName)  -- OK
         for _,record in ipairs(data) do
           for k,v in pairs(record) do
              if k==recordId then
                return v[fieldName]
              end
           end
         end
      end

     
     local strbaro = getLonoBox(t,"100003523", "barometer")  -- OK
     --print ('strbaro: ', strbaro)         
     local strTemp = getLonoBox(t,"200003523", "temperature") -- OK
     --print ('strTemp: ', strTemp)       
     local strHumid = getLonoBox(t,"200003523", "humidity")  -- OK
     --print ('strHumid: ', strHumid)
     local strWinD =  getLonoBox(t,"400004105", "wind-direction") -- OK
     --print ('strWinD: ', strWinD)
     local strWinS =  getLonoBox(t,"400004105", "wind-speed") -- OK
     --print ('strWinS: ', strWinS)
     local strWinG =  getLonoBox(t,"400004105", "wind-gust")      -- OK  
     --print ('strWinG: ', strWinG)       
      
            fibaro:setGlobal("LonoBaro1", strbaro);    -- OK
            fibaro:setGlobal("LonoTemp1", strTemp);    -- OK
            fibaro:setGlobal("LonoHum1", strHumid);    -- OK
            --fibaro:setGlobal("LonoRain1", rain1);    -- OK
            fibaro:setGlobal("LonoWindDir1", strWinD);   -- OK
            fibaro:setGlobal("LonoWindSpeed1", strWinS);   -- OK
            fibaro:setGlobal("LonoWindGust1", strWinG);   -- OK
      else
            fibaro:debug(current.status)
            end
     end
    })
      fibaro:call(248, "pressButton", "update")    -- OK
      --print("Button 1 Pressed")
    end  -- end time5min

    =========================

     

    The Debug screen

    =========================

    DEBUG 04:47:53: k=status, v=200"},
    DEBUG 04:47:53: k=data, v=[{\"200003523\":{\"temperature\":\"17\",\"humidity\":\"88\"}},{\"400004105\":{\"wind-speed\":\"0\",\"wind-gust\":\"0.9\",\"wind-direction\":\"SW\"}},{\"100003523\":{\"barometer\":\"1018\"}}]
    DEBUG 04:47:53: k=headers, v=table: 0x9eeb338
    DEBUG 04:47:53: k=X-Varnish, v=8547242
    DEBUG 04:47:53: k=Content-Type, v=text/html; charset=UTF-8
    DEBUG 04:47:53: k=Date, v=Sat, 02 Jun 2018 02:45:10 GMT
    DEBUG 04:47:53: k=Via, v=1.1 varnish-v4
    DEBUG 04:47:53: k=Content-Length, v=160
    DEBUG 04:47:53: k=Connection, v=close
    DEBUG 04:47:53: k=Vary, v=Accept-Encoding
    DEBUG 04:47:53: k=Accept-Ranges, v=bytes
    DEBUG 04:47:53: k=Server, v=Apache/2.4.33 (Ubuntu)
    DEBUG 04:47:53: k=Age, v=0
    DEBUG 04:47:53: Date: Sat, 02 Jun 2018 02:45:10 GMT
    DEBUG 04:47:53: [1;31m2018-06-02 04:47:53.617764 [  fatal] LUA error: /opt/fibaro/scenes/149.lua:40: attempt to call global 'Print' (a nil value)

    =============================================

     

    It is strange, with the command  print ("Date:", current.headers.Date), you get output Date: Sat, 02 Jun 2018 02:45:10 GMT, but as soon as you want to put this value in a variable, local strDate = current.headers.Date , you get a nil value.

     

    Regards,

    Fons

    Edited by FonsBrand
    Link to comment
    Share on other sites

    • 0

    Almost there!

     

    Lua is case sensitive (although it looks a bit like BASIC which is not case sensitive if I remember correctly).

     

    You get:

      LUA error: /opt/fibaro/scenes/149.lua:40: attempt to call global 'Print' (a nil value)

     

    Because you wrote:

      Print ('Date :', strDate)

     

    Try "print" instead.

     

    BTW you'll see most users do not use "print" at all, but in this case it is very convenient... The more standard way:

     

      fibaro:debug("Date:\t"..strDate)

     

    The syntax is different, but it has the same result. print can take any number of arguments, and separates the output by inserting tabs. fibaro:debug takes a single argument. So to get the same effect I add the \t = "tab" and concatenate the strings.

     

    EDIT: The error message might confuse you. It says: "..... Print (a nil value). You think: "ah, it cannot print nil values" but that is not what it says. It tells you the variable "Print" is a nil value, and you cannot call it. Lua does NOT have named functions. Lua only has variables, and they can point to a function. 

    Edited by petergebruers
    • Like 1
    Link to comment
    Share on other sites

    • 0
  • Inquirer
  • Yes that was it,

    2 hours ago, petergebruers said:

    Because you wrote:

      Print ('Date :', strDate)

     

    Try "print" instead.

    Now I get the date.

    Please login or register to see this code.

    Fons

     

    Link to comment
    Share on other sites

    • 0

    Happens to me all the time...

     

    Have fun with automation!

    • Like 1
    Link to comment
    Share on other sites

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest
    Answer this question...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    ×
    ×
    • Create New...