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

Json encode / decode question


Question

I want to use a construction in my hometable like for example

 

local HT = { light1 = { fib_id = 211, hue_id = 7  },
                     light2 = { fib_id = 227, hue_id = 12 },
                   }
HT.ftoh  = { [ HT.light1.fib_id ] = HT.light1.hue_id,
                    [ HT.light2.fib_id ] = HT.light2.hue_id,
                   }

 

When i test fibaro:debug( HT.ftoh[ 227 ] ) it gives the expected value 12.

 

I want to use this in a couple of VD's with generic code for hue lights, but when i test local HT2 = fibaro.decode( fibaro.encode( HT ) ) then
fibaro:debug( HT2.ftoh[ 227 ] ) gives un expected NIL result.

 

fibaro:debug( HT2.ftoh[ "227" ] ) does give the correct result 12 so the original key index 227 is now a string.

 

Is this normal behaviour of the json.encode / json.decode functions or is this a bug ?

Edited by Alex de Bruin
Changed : to .
Link to post
Share on other sites

13 answers to this question

Recommended Posts

  • 0

the correct syntax is:

 

jsonTable = json.decode(jsonString)
and

jsonString = json.encode(jsonTable )

 

Enjoy coding :-D

Link to post
Share on other sites
  • 0
  • Inquirer
  • 24 minutes ago, Bodyart said:

    the correct syntax is:

     

    jsonTable = json.decode(jsonString)
    and

    jsonString = json.encode(jsonTable )

     

     

    My problem is that when i say

     

    jsonStringX = json.encode( jsonTableX)

    and then

    jsonTableY = json.decode(jsonStringX)

     

    then jsonTableY is not the same as the original jsonTableX

    Link to post
    Share on other sites
    • 0

    when i try this code:

    Please login or register to see this code.

    then i get:

    Please login or register to see this image.

    /monthly_2020_03/afbeelding.png.159614b253ab034b285a8358aab3f783.png" />

     

    so the HT2 is exact same as HT, but you didn't define HT2.ftoh, only HT.ftoh......

    Edited by Bodyart
    Link to post
    Share on other sites
    • 0

    Hi, I do have an issue than may come from the same situation.

     

    I've created in a scene a naming table for all my devices ID, rooms and so on and json.encode it into a global variable.

    From the scene, i can then json.decode the variable and check that i can access my data. fine.

     

    From a QA, i can't json.decode this global variable : "/5.3/json/util.lua:55: bad argument #1 to 'for iterator' (table expected, got number)"

    trying numerous other expression format, i sometime get error return that let me think that data are not classified anymore, preventing from using them.

     

    a little bit lost also...

     

    any code angel ? :)

     

    Link to post
    Share on other sites
    • 0
  • Inquirer
  • 1 hour ago, Bodyart said:

    so the HT2 is exact same as HT, but you didn't define HT2.ftoh, only HT.ftoh......

     

    I did define the HT.ftoh before encoding so it's part of the original table. After decoding it's part of the new HT2 table

     

    Please login or register to see this image.

    /monthly_2020_03/Knipsel.PNG.f20e1bce452a8c1fe679ec17e192a382.PNG" />

     

    As you can see the original { [211]=7,[227]=12} is encoded as {"211":7,"227":12}

    Edited by Alex de Bruin
    Link to post
    Share on other sites
    • 0
    3 hours ago, Alex de Bruin said:

    I want to use a construction in my hometable like for example

     

    local HT = { light1 = { fib_id = 211, hue_id = 7  },
                         light2 = { fib_id = 227, hue_id = 12 },
                       }
    HT.ftoh  = { [ HT.light1.fib_id ] = HT.light1.hue_id,
                        [ HT.light2.fib_id ] = HT.light2.hue_id,
                       }

     

    When i test fibaro:debug( HT.ftoh[ 227 ] ) it gives the expected value 12.

     

    I want to use this in a couple of VD's with generic code for hue lights, but when i test local HT2 = fibaro.decode( fibaro.encode( HT ) ) then
    fibaro:debug( HT2.ftoh[ 227 ] ) gives un expected NIL result.

     

    fibaro:debug( HT2.ftoh[ "227" ] ) does give the correct result 12 so the original key index 227 is now a string.

     

    Is this normal behaviour of the json.encode / json.decode functions or is this a bug ?

    This is totally normal.

    In both cases this is a string.

     Your definition using square brackets appends the value to string and json.encode function converts this to actual string.

    HT.ftoh  = { [ HT.light1.fib_id ] = HT.light1.hue_id,
                        [ HT.light2.fib_id ] = HT.light2.hue_id,
                       }

    You can print and see they are the same in json.encode

    print(json.encode(HT))
      HT2=json.decode(json.encode(HT))
    print(json.encode(HT2))

    Edited by cag014
    Link to post
    Share on other sites
    • 0
  • Inquirer
  • 36 minutes ago, cag014 said:

    This is totally normal.

    In both cases this is a string.

     

    But why then HT.ftoh[ 227 ] = 12 before encoding and HT2.ftoh[ 227 ] = nil after encoding and decoding.

    Edited by Alex de Bruin
    Link to post
    Share on other sites
    • 0
    1 minute ago, Alex de Bruin said:

    But why then HT.ftoh[ 227 ] = 12 before encoding and HT2.ftoh[ 227 ] = nil after encoding and decoding.

    json.encode converts the value to string, so json.decode gets back string value

    Link to post
    Share on other sites
    • 0
    9 minutes ago, cag014 said:

    json.encode converts the value to string, so json.decode gets back string value

     

    Which is kind of faulty.

    It's a sparse array so a correct encoder should give an error like "invalid table: mixed or invalid key types"

    Which the json encoder in scenes on the HC3 does, but not the json encoder in QA's on the HC3 (and not the HC2 scene version either)

    If you don't get back what you encode when you decode it's not an encoder/decoder... it's something else.

    It's possible to fool the json encoder on the HC2 too if you do a long sequential array 1,2,3,4,5...80 and then suddenly make huge holes...

    Link to post
    Share on other sites
    • 0
  • Inquirer
  • 17 minutes ago, jgab said:

    If you don't get back what you encode when you decode it's not an encoder/decoder... it's something else.

     

    Thank you jgab, i agree.

    It may be normal behaviour, but it should not be.

     

    I use this table construction in my hometable and it's correct table usage according to the lua manual.

     

    My purpose was to use the table in VD's where i use the selfID as an index to the corresponding hue id and was wondering why it did not work.

    • Like 1
    Link to post
    Share on other sites
    • 0
    9 minutes ago, Alex de Bruin said:

     

    Thank you jgab, i agree.

    It may be normal behaviour, but it should not be.

     

    I use this table construction in my hometable and it's correct table usage according to the lua manual.

     

    My purpose was to use the table in VD's where i use the selfID as an index to the corresponding hue id and was wondering why it did not work.

     

    To be more specific:

    In json it is a difference between an array [...] and a key-value table {key:value}

    Lua is a bit more .... "flexible"

     

    Try this on the HC2.

    Please login or register to see this code.

    and you get an json array as expected '["A1","A2",...]'

    If you instead do

    Please login or register to see this code.

    suddenly the encoder decides that it's a key-value table and you get '{"1"="A1","2"="A2",...."100"="HUPP"}'

    Nice try but this does not make sense and creates strange bugs...

    A strict (professional) json encoder tells the user that this can't be encoded  - actually I believe that some of the better ones can be told to be a bit relax and accept holes in arrays - but don't know what they do then... but changing the data types of the elements in the struct is a no-no.

     

    Link to post
    Share on other sites
    • 0
  • Inquirer
  • OK, that"s clear. I then have to use tostring(fibaro:getSelfId()) as the index in the decoded table or find a more elegant solution.

     

    Thanks to all contributors to the subject.

    Link to post
    Share on other sites
    • 0
    8 minutes ago, Alex de Bruin said:

    OK, that"s clear. I then have to use tostring(fibaro:getSelfId()) as the index in the decoded table or find a more elegant solution.

    yes indeed and maybe define that 211 as a string because that's what it will be after a decode

     

    I am a bit late to the party but I could not resist writing a little program to make this issue more visible...

     

    Please login or register to see this code.

    Result

     

    Please login or register to see this code.

    It is a game of "Can you spot the difference?" :D

     

    Nice one!

    Link to post
    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...