JSON – hur man kan hantera JSON – kort intro

Börjar med att erkänna det direkt: Jag är inte van användare av JSON i HC2an – jag har helt enkelt aldrig haft behovet så det har inte kommit mig för att titta på det således. Men nu var det ju så att någon ställde en fråga, och ja nyfiken som man är, så började jag titta lite på det hela.

Till att börja med, JSON fungerar bäst i VD (Virtuel Device), eftersom de två funktioner man vill åt enbart finns aktiva i VDs:
– json.decode – Konvertera en JSON lista till en tabell
– json.encode – Konvertera en tabell till en JSON lista

Så låt oss börja med: Vad är en JSON? eh? Wikipedia on JSON

JSON or JavaScript Object Notation, is an open standard format that uses human-readable text to transmit data objects consisting of attribute–value pairs. It is used primarily to transmit data between a server and web application, as an alternative to XML.

Aha – ett sätt att kommunicera mellan olika object i en datormiljö, och göra det i ren läsbar text och ingen superkonstig kod.

I Fibaro HC2 finns ett antal JSON rutiner som man kommer åt via API du kan läsa om dom här:
Beta API – http Commands

För denna lilla guide kommer jag använda just den första:

http:///api/rooms

Som i mitt fall, med tolv rum (nåja), ger en lista i denna stil:

[{“id”:1,”name”:”Sovrum”,”sectionID”:1,”icon”:””,”defaultSensors”:{“temperature”:118,”humidity”:0,”light”:119},”defaultThermostat”:99,”sortOrder”:5},{“id”:2,”name”:”Arbetsrum”,”sectionID”:1,”icon”:”room_luxurychair”,”defaultSensors”:{“temperature”:52,”humidity”:53,”light”:54},”defaultThermostat”:124,”sortOrder”:6},{“id”:3,”name”:”Kök”,”sectionID”:1,”icon”:”room_kitchen”,”defaultSensors”:{“temperature”:0,”humidity”:0,”light”:0},”defaultThermostat”:0,”sortOrder”:3},{“id”:4,”name”:”Matsal”,”sectionID”:1,”icon”:”room_jadalnia”,”defaultSensors”:{“temperature”:138,”humidity”:0,”light”:139},”defaultThermostat”:125,”sortOrder”:2},{“id”:5,”name”:”Vardagsrum”,”sectionID”:1,”icon”:”room_cinema”,”defaultSensors”:{“temperature”:103,”humidity”:0,”light”:104},”defaultThermostat”:0,”sortOrder”:1},{“id”:6,”name”:”Badrum”,”sectionID”:1,”icon”:”room_laundry”,”defaultSensors”:{“temperature”:0,”humidity”:0,”light”:0},”defaultThermostat”:0,”sortOrder”:7},{“id”:7,”name”:”Garderob”,”sectionID”:1,”icon”:”room_polkabuty”,”defaultSensors”:{“temperature”:0,”humidity”:0,”light”:0},”defaultThermostat”:0,”sortOrder”:8},{“id”:8,”name”:”Hall”,”sectionID”:1,”icon”:”room_kapelusz”,”defaultSensors”:{“temperature”:0,”humidity”:0,”light”:0},”defaultThermostat”:0,”sortOrder”:4},{“id”:9,”name”:”Balkong”,”sectionID”:1,”icon”:”room_drzwiwejsciowe”,”defaultSensors”:{“temperature”:62,”humidity”:63,”light”:0},”defaultThermostat”:0,”sortOrder”:9},{“id”:10,”name”:”Scener”,”sectionID”:2,”icon”:”room_sofa”,”defaultSensors”:{“temperature”:0,”humidity”:0,”light”:0},”defaultThermostat”:0,”sortOrder”:10},{“id”:11,”name”:”Diverse”,”sectionID”:3,”icon”:”room_guest”,”defaultSensors”:{“temperature”:0,”humidity”:0,”light”:0},”defaultThermostat”:0,”sortOrder”:11},{“id”:13,”name”:”Bevakning”,”sectionID”:2,”icon”:”room_pioro”,”defaultSensors”:{“temperature”:0,”humidity”:0,”light”:0},”defaultThermostat”:0,”sortOrder”:12}]

Måste ju säga att listan inte ser sådär direkt lättläst ut – men mycket kan vi i alla fall se:
För varje rad (som är bruten på minst två rader när ni läser denna text) så finns “id”, “name” osv. Och när man ser ovanstående i t.ex. en web läsare, så kan man lätt förundras över vad det är…

I vilket fall, en JSON lista kan inte rakt av hanteras inne i LUA, och till på köpet stöds vara funktionerna inne i VD’s så det är inte lika lätt som tidigare att bara “kasta in koden” i en scen. Man börjar med att skapa en VD (ja jag vet, jag har inte skrivit om det – än….). Och så skapar man förslagsvis en knapp och skriver sin LUA kod i knappen.

Om vi tar exemplet ovan med api/rooms, så kommer början av koden se ut något i stil med detta:

local ROOMS = Net.FHttp("192.168.1.131",80);
ROOMS:setBasicAuthentication("admin","xxx")

response ,status, errorCode = ROOMS:GET("/api/rooms");

Nej jag tänker inte gå igenom koden ovan – acceptera att den kommer att köra api’n som skapar JSON listan.

För att klara av att jobba med JSON listan, så måste vi alltså börja med att konvertera den till ett format som lättare hanterar listan, och det blir då till en vanlig tabell variabel. Förslagsvis såhär:

jsonTable = json.decode(response);

Okej – så nu har vi en tabell istället och kan börja titta på det mera logiskt. T.ex. kan vi ta reda på hur många rum det finns i detta fallet:

function fn_TableLength(T)
   local count = 0
   for _ in pairs(T) do count = count + 1 end
   return count
end

local NumberOfRooms = fn_TableLength(jsonTable);

Funktionen ovan känner ni igen från del 2.2 i denna guide – den räknar snabbt ut hur många rader det finns i tabellen, dvs 12 i detta exempel:

fibaro:debug("Antal rum: "..NumberOfRooms);

Men om man vill titta i tabellen så måste man alltså hoppa runt mha index. Ett sätt är att som i förra delen helt enkelt skapa en loop och lista allt:

for loop = 1, NumberOfRooms do
   fibaro:debug("ID: "..jsonTable[loop].id.." Namn rum "..loop..": "..jsonTable[loop].name);
end

Och det är ju trevligt.

Men om man vill åt den tredje raden i listan, så blir det alltså:

fibaro:debug("ID: "..jsonTable[3].id.." Namn rum "..loop..": "..jsonTable[3].name);

Observera alltså siffran 3 istf variabeln “loop” – man måste alltså inte använda en for-loop, utan man kan direkt titta i listan.

Exakt vad man skall använda ovanstående till kan man ju undra, man kommer t.ex. åt rummets namn på andra sätt:

fibaro:getRoomName(fibaro:getRoomID(i))

Men mer om det lite senare, när vi tittar lite på alarm och hur man kan nyttja det i LUA.