Z-Wave Forum Allt om Z-wave och hemkontroll

VD - json mot Lundix SPC Gateway

av martinlundgren80 » 18 maj 2017, 09:06

Hej,
Jag försöker göra en VD för att hämta och ändra information på Lundix SPC Gateway men får det inte att fungera.
Problemet tror jag ligger i att json-filen som man får från gatewayen verkar ha 2 nivåer på informationen.
json filen ser ut enl. nedan:

{"status":"success","data":{"area":[{"id":"1","name":"XXXXXXXX","mode":"0","last_set_time":"1488720661","last_unset_time":"1489388579","last_unset_user_id":"3","last_unset_user_name":"XXXXXXXX","last_alarm":"1489237927","not_ready_set":"1002"}]}}

Jag vill där hämta (GET) samt ändra (PUT) värdet på "mode", men den vill inte känna igen fibaro:debug(jsonTable.mode) enligt koden nedan. Beror det på att den ligger inom [ och då ska hämtas på något annat sätt?

Skriver jag istället ut status, fibaro:debug(jsonTable.status) så år jag svaret successs vilket är korrekt.

Kod: Markera allt
local thisdevice = fibaro:getSelfId()
local ip = fibaro:getValue(thisdevice, 'IPAddress')
local port = fibaro:getValue(thisdevice, 'TCPPort')
local httpSession = Net.FHttp(ip, port);
response, status, errorCode = httpSession:GET('/spc/area/1/mode')
--response = httpSession:GET('/spc/area/1')

fibaro:debug("Response = "..response)
fibaro:debug("Status = "..status)
fibaro:debug("ErrorCode = "..errorCode)

jsonTable = json.decode(response)
fibaro:debug(jsonTable.mode)
martinlundgren80
Ny medlem
 
Inlägg: 18
Blev medlem: 03 jan 2016, 15:31

av pos » 18 maj 2017, 10:28

Du får nog ändra..

fibaro:debug("Response = "..response)
till
fibaro:debug('Response = '.. json.encode(response))


Peo
pos
Medlem
 
Inlägg: 71
Blev medlem: 03 feb 2017, 02:20

av martinlundgren80 » 18 maj 2017, 11:00

pos skrev:Du får nog ändra..

fibaro:debug("Response = "..response)
till
fibaro:debug('Response = '.. json.encode(response))


Peo

Tack för snabbt svar men fibaro:debug("Response = "..response) fungerar som det ska och skriver ut response i json-format.
Problemet är att jag vill komma åt "mode" i det svaret.
fibaro:debug(jsonTable.mode) borde ge mig svaret 0 precis som på samma sätt som fibaro:debug(jsonTable.status) ger svaret success. Men det gör det inte och jag antar att det beror på att "mode" ligger inom [] och därmed inte kan läsas av genom jsonTable.mode utan måste göras på annat sätt.

Så frågan är vad man ska skriva för att hämta "mode"?
martinlundgren80
Ny medlem
 
Inlägg: 18
Blev medlem: 03 jan 2016, 15:31

av pos » 19 maj 2017, 02:16

Hej

Här har du ett exempel på detta som jag tror du fick i pm av mig fast inbakad i en större kodmassa.


En sån här....
Kod: Markera allt
{
  "name": "DCFG_ICONS",
  "value": "AWAY:1006",
  "readOnly": false,
  "isEnum": true,
  "enumValues": [
    "AWAY:1006",
    "DISARMED:1007",
    "DSCENGINEICON:1001",
    "LOGGERDEVICON:1004",
    "PRESENTERDEVICON:1002",
    "STAY:1008",
    "UNKNOWN:1003",
    "ZEROENTRYAWAY:1",
    "ZEROENTRYSTAY:1"
  ],
  "created": 1495047824,
  "modified": 1495052775
}





Kan du parsa så här...

Kod: Markera allt
if fibaro:getGlobalValue('DSC_P1_ArmedStatus') ~= nil then
      HOST = Net.FHttp("127.0.0.1",11111);
      response ,status, err = HOST:GET('/api/globalVariables/DCFG_ICONS');
      local jsonTable = json.decode("[" .. response .. "]");
      table = jsonTable[1].enumValues   
      for index,value in pairs(table) do
            if string.match(value, '^AWAY') then
                  AWAY, AWAY_NUM = table[tonumber(index)]:match("([^:]+):([^:]+)")
            end         
            if string.match(value, '^STAY') then
                  STAY, STAY_NUM = table[tonumber(index)]:match("([^:]+):([^:]+)")
            end         
            if string.match(value, "ZEROENTRYAWAY") then
                  ZEROENTRYAWAY, ZEROENTRYAWAY_NUM = table[tonumber(index)]:match("([^:]+):([^:]+)")
            end         
            if string.match(value, "ZEROENTRYSTAY") then
                  ZEROENTRYSTAY, ZEROENTRYSTAY_NUM = table[tonumber(index)]:match("([^:]+):([^:]+)")
            end   
            if string.match(value, "DISARMED") then
                  DISARMED, DISARMED_NUM = table[tonumber(index)]:match("([^:]+):([^:]+)") 
            end
            if string.match(value, "UNKNOWN") then
                  UNKNOWN, UNKNOWN_NUM = table[tonumber(index)]:match("([^:]+):([^:]+)")
            end
      end
      if tonumber(fibaro:getGlobalValue('DSC_P1_ArmedStatus')) ==  0 then
            if AWAY_NUM ~= nil then fibaro:call(fibaro:getSelfId(), "setProperty", "currentIcon", AWAY_NUM); end
      elseif tonumber(fibaro:getGlobalValue('DSC_P1_ArmedStatus')) == 1 then
            if STAY_NUM ~= nil then fibaro:call(fibaro:getSelfId(), "setProperty", "currentIcon", STAY_NUM); end
      elseif tonumber(fibaro:getGlobalValue('DSC_P1_ArmedStatus')) == 2 then
            if ZEROENTRYAWAY_NUM ~= nil then fibaro:call(fibaro:getSelfId(), "setProperty", "currentIcon", ZEROENTRYAWAY_NUM); end
      elseif tonumber(fibaro:getGlobalValue('DSC_P1_ArmedStatus')) == 3 then
            if ZEROENTRYSTAY_NUM ~= nil then fibaro:call(fibaro:getSelfId(), "setProperty", "currentIcon", ZEROENTRYSTAY_NUM); end
      elseif tonumber(fibaro:getGlobalValue('DSC_P1_ArmedStatus')) == 4 then
            if DISARMED_NUM ~= nil then fibaro:call(fibaro:getSelfId(), "setProperty", "currentIcon", DISARMED_NUM); end
      elseif tonumber(fibaro:getGlobalValue('DSC_P1_ArmedStatus')) == 5 then
            if UNKNOWN_NUM ~= nil then fibaro:call(fibaro:getSelfId(), "setProperty", "currentIcon", UNKNOWN_NUM); end
      end
end
pos
Medlem
 
Inlägg: 71
Blev medlem: 03 feb 2017, 02:20

av gol » 19 maj 2017, 17:03

Hej Martin!
Du är inne på rätt spår men eftersom area är en array så ska du parsa den så här:

Kod: Markera allt
local ip = fibaro:getValue(thisdevice, 'IPAddress')
local port = fibaro:getValue(thisdevice, 'TCPPort')
local httpSession = Net.FHttp(ip, port);
response, status, errorCode = httpSession:GET('/spc/area/1/mode')
--response = httpSession:GET('/spc/area/1')

fibaro:debug("Response = "..response)
fibaro:debug("Status = "..status)
fibaro:debug("ErrorCode = "..errorCode)

jsonTable = json.decode(response)
if jsonTable.status == 'success' then
    if jsonTable.data.area and #jsonTable.data.area > 0 then
       for i = 1, #jsonTable.data.area do  -- loop all areas
          local area = jsonTable.data.area[i]
          fibaro:debug(area.id, area.name. area.mode)
       end
    else                             -- if area is not an array we come here
       local area = jsonTable.data.area
       fibaro.debug(area.id, area.name, area.mode)
    end
end


Har inte testat koden så det kan eventuellt finnas något fel men jag tror du ändå fattar principen.

//Göran
gol
Medlem
 
Inlägg: 27
Blev medlem: 30 apr 2014, 08:00

av KristianO » 19 maj 2017, 23:29

Nyfiken men vad styr "mode"?


Sent from my iPhone using Tapatalk
KristianO
Medlem
 
Inlägg: 435
Blev medlem: 10 mar 2014, 09:50

av martinlundgren80 » 22 maj 2017, 10:57

Tack! Ska testa detta lite och se ifall jag löser det.

Mode är larmstatus:
0 – area is unset
1 – area is part set A
2 – area is part set B
3 – area is full set
martinlundgren80
Ny medlem
 
Inlägg: 18
Blev medlem: 03 jan 2016, 15:31

av KristianO » 22 maj 2017, 12:39

Ok, då blir jag mer nyfiken. Du använder ett Siemens spc som sätter denna status? Varför vill du "tweaka" denna "mode"?


Sent from my iPhone using Tapatalk
KristianO
Medlem
 
Inlägg: 435
Blev medlem: 10 mar 2014, 09:50

av martinlundgren80 » 22 maj 2017, 13:07

Tack gol!
Fick det att fungera efter några små justeringar, så min kod ut ser nu ut som nedan...

Nu kommer ju den riktiga frågan då... Hur gör jag för att larma, alltså ändra mode?
Antar att det blir en omvänd procedur och PUT istället eller räcker det med att göra enl. denna raden?
response, status, errorCode = httpSession:PUT("/area/1/set")



Kod: Markera allt
local thisdevice = fibaro:getSelfId()
local ip = fibaro:getValue(thisdevice, 'IPAddress')
local port = fibaro:getValue(thisdevice, 'TCPPort')
local httpSession = Net.FHttp(ip, port);
response, status, errorCode = httpSession:GET('/spc/area')

fibaro:debug("Response = "..response)
fibaro:debug("Status = "..status)
fibaro:debug("ErrorCode = "..errorCode)

jsonTable = json.decode(response)
fibaro:debug("Status = "..jsonTable.status)
if jsonTable.status == 'success' then
if jsonTable.data.area and #jsonTable.data.area > 0 then
for i = 1, #jsonTable.data.area do  -- loop all areas
local area = jsonTable.data.area[i]
fibaro:debug("ID = "..area.id)
fibaro:debug("Name = "..area.name)
fibaro:debug("Mode = "..area.mode)
if((area.mode) == '0')
  then
    fibaro:call(thisdevice, "setProperty", "ui.Status.value", "Avlarmat");
elseif((area.mode) == '1')
  then
    fibaro:call(thisdevice, "setProperty", "ui.Status.value", "Skalskydd + ÖV");
elseif((area.mode) == '2')
  then
    fibaro:call(thisdevice, "setProperty", "ui.Status.value", "Skalskydd");
elseif((area.mode) == '3')
  then
    fibaro:call(thisdevice, "setProperty", "ui.Status.value", "Larmat");
end
    end 
else                             -- if area is not an array we come here
local area = jsonTable.data.area
fibaro:debug(area.id, area.name, area.mode)
end
end
Senast redigerad av martinlundgren80 22 maj 2017, 16:04, redigerad totalt 1 gång.
martinlundgren80
Ny medlem
 
Inlägg: 18
Blev medlem: 03 jan 2016, 15:31

av martinlundgren80 » 22 maj 2017, 14:22

Hej Kristian,
Jag har för avsikt att kunna larma av/på från HC2:an.

Larma av när t.ex. följande sker:
när bilen kommer hem, Volvo On Call
när jag (min telefon) kommer hem, iCloud Geolocation
När jag låser upp Yale Doorman, uppkopplade mot Verisure
m.m.

Mvh
Martin




KristianO skrev:Ok, då blir jag mer nyfiken. Du använder ett Siemens spc som sätter denna status? Varför vill du "tweaka" denna "mode"?


Sent from my iPhone using Tapatalk
martinlundgren80
Ny medlem
 
Inlägg: 18
Blev medlem: 03 jan 2016, 15:31

av KristianO » 22 maj 2017, 15:11

Ok, så lumix bryggan funkar åt båda håll? Dvs om lumix får mode "unset" så slås mitt larm av? Är ute efter att vid avlarmning av mitt garage (idlock lås) så skall det larmas av.


Sent from my iPhone using Tapatalk
KristianO
Medlem
 
Inlägg: 435
Blev medlem: 10 mar 2014, 09:50

av martinlundgren80 » 23 maj 2017, 09:07

Kör jag koden nedan så får jag svaret 200 vilket borde tyda på att det är OK?
Men det händer ingenting, inte ens i loggen på SPC att något sker.
Var gör jag fel?

[DEBUG] 09:02:45: Status = 200

Kod: Markera allt
 
  local thisdevice = fibaro:getSelfId()
  local ip = fibaro:getValue(thisdevice, 'IPAddress')
  local port = fibaro:getValue(thisdevice, 'TCPPort')
  local httpSession = Net.FHttp(ip, port);

  jsonTable = { }
  jsonString = json.encode(jsonTable)

response, status, errorCode = httpSession:PUT("/area/1/set_a", jsonString)

fibaro:debug("Response = "..response)
fibaro:debug("Status = "..status)
fibaro:debug("ErrorCode = "..errorCode)
martinlundgren80
Ny medlem
 
Inlägg: 18
Blev medlem: 03 jan 2016, 15:31

av gol » 23 maj 2017, 23:12

Som du vet rekommenderar jag alltid att man har både kryptering och Digest-autentiseringen påslagen för ökad IT-säkerhet, speciellt för kommandon mot larmet. Senast jag kollade så kunde dock Fibaro HC2 inte hantera Digest-autensiering men däremot kan du säkert använda https.

Med detta sagt... Kommandot ska vara /spc/area/1/set_a
Om du ändå inte får det att fungera bör du kolla:
1) Att du får status "success" i response.
2) Att du tillåter kommandon via EDP i SPC-larmet
3) Att du inte är i Engineer-mode i SPC-larmet när du testar
4) Att du inte har några öppna sektioner eller något annat som förreglar att du ändrar "mode"

//Göran .
gol
Medlem
 
Inlägg: 27
Blev medlem: 30 apr 2014, 08:00

av martinlundgren80 » 24 maj 2017, 11:03

Återigen tack!!
Ibland är man blind... Det var /spc/ som jag hade missat...
Givetvis så ska det på lite säkerhet men när jag håller på att testa är det smidigt för att se att allt fungerar.
Nu kan jag bygga lite automation som larmar på/av vid olika scenarion, tack Göran!

För svar till KristianO så fungerar Lundix Gatewayen åt båda håll, både hämta information men också ändra...
Full dokumentation om API:t finner du på länken nedan:
http://www.lundix.se/wp-content/uploads/2014/05/SPC-Web-Gateway-Specification-version-1.0.pdf

Mvh
Martin

gol skrev:Som du vet rekommenderar jag alltid att man har både kryptering och Digest-autentiseringen påslagen för ökad IT-säkerhet, speciellt för kommandon mot larmet. Senast jag kollade så kunde dock Fibaro HC2 inte hantera Digest-autensiering men däremot kan du säkert använda https.

Med detta sagt... Kommandot ska vara /spc/area/1/set_a
Om du ändå inte får det att fungera bör du kolla:
1) Att du får status "success" i response.
2) Att du tillåter kommandon via EDP i SPC-larmet
3) Att du inte är i Engineer-mode i SPC-larmet när du testar
4) Att du inte har några öppna sektioner eller något annat som förreglar att du ändrar "mode"

//Göran .
martinlundgren80
Ny medlem
 
Inlägg: 18
Blev medlem: 03 jan 2016, 15:31

av martinlundgren80 » 24 maj 2017, 12:02

Larmpanel_HC2.JPG
Larmpanel_HC2
martinlundgren80
Ny medlem
 
Inlägg: 18
Blev medlem: 03 jan 2016, 15:31

av KristianO » 24 maj 2017, 14:11

Sweet! Tänker att jag skulle kunna trigga en scene när jag låser upp min ytterdörr som triggar avlarmning av Hemnet.
Kör med idlock som är zwave anslutna. Nu gäller det bara att hitta en trigger från låset när låset blir upplåst.


Sent from my iPhone using Tapatalk
KristianO
Medlem
 
Inlägg: 435
Blev medlem: 10 mar 2014, 09:50

av gol » 24 maj 2017, 19:19

martinlundgren80 skrev:
Larmpanel_HC2.JPG

Snyggt Martin!
Skulle vara fint om du även lyckas utnyttja websockets-API:t så får du dessutom allt händelsestyrt så att du slipper polla.
//Göran
gol
Medlem
 
Inlägg: 27
Blev medlem: 30 apr 2014, 08:00

av KristianO » 07 jun 2017, 22:35

Om man istället gör en scene för att åstadkomma SSL (HTTPS) så borde väl detta funka?

Kod: Markera allt
--[[
%% properties
%% events
%% globals
--]]

local url = "https://<ip>:8088/spc/area/1/set"
local auth = "Basic user:pwd in base64"

--function httpRequest(url,auth)
  local http = net.HTTPClient()
http:request(url, {
    options = {
        method = 'PUT',
        headers = {
            ['Authorization'] = auth
        }
    },
    success = function(response) fibaro:debug(response.data) end,
    error = function(err) fibaro:debug("Error: " ..err) end
})
--end 


KristianO
Medlem
 
Inlägg: 435
Blev medlem: 10 mar 2014, 09:50

Dustin

Återgå till Fibaro Home Center 2