Hej alla!
Har haft en HC2 i många år som (tyvärr) gav upp för ett par veckor sedan så jag hade inget annat val än att uppgradera till HC3.
Till min förtvivlan så upptäcker jag att Virtual Devices numera heter Quick App och har ett helt annat sått att kodas....
Jag är ingen programmerare och kan i bästa fall klippa och klistra in kod som någon annan skapat.
Jag skulle behöva hjälp (från scratch) med att skapa ett antal Quick Apps som kan skicka http-kommandon till mina kameror för att aktivera rörelsesensorer.
I http form ser de ut så här:
Aktivera på en Foscam kamera
http://192.168.x.xxx/set_alarm.cgi?moti ... d=password
Deaktivera på en Foscam kamera
http://192.168.x.xxx/set_alarm.cgi?moti ... d=password
Aktivera på en Axis-kamera
http://192.168.1.xxx/axis-cgi/virtualin ... s=password
Deaktivera på en Axis-kamera
http://192.168.1.xxx/axis-cgi/virtualin ... s=password
Vore oerhört tacksam om någon kunde förbarma sig över mig och mina bristande programmeringskunskaper.
Jag kommer att vara dig/er evigt tacksam.
mvh
Lasse Hedh
Hjälp med Quick App
Sorry, jag verkar inte få ladda upp ngn attachment.
Skapa en QA av typ "com.fibaro.binarySwitch" och klistra in kodan nedan.
(osäker på hur du identifiera dig, password i URLen?)
QA:an kommer att ha en on och en off knapp och går även att använda från blockscener.
Skapa en QA av typ "com.fibaro.binarySwitch" och klistra in kodan nedan.
(osäker på hur du identifiera dig, password i URLen?)
QA:an kommer att ha en on och en off knapp och går även att använda från blockscener.
Code: Select all
local baseURL = "http://192.168.1.xxx/"
local activate = "axis-cgi/virtualin ... s=password"
local deactivate = "axis-cgi/virtualin ... s=password"
local function sendCommand(cmd)
net.HTTPClient():request(baseURL..cmd,{
options = { method = "GET" },
success = function(resp) quickApp:debug("Success",json.encode(resp)) end,
error = function(err) quickApp:error(err) end
})
end
function QuickApp:turnOn()
self:debug("activating")
sendCommand(activate)
self:updateProperty("value",true)
self:updateProperty("status",true)
end
function QuickApp:turnOff()
self:debug("deactivating")
sendCommand(deactivate)
self:updateProperty("value",false)
self:updateProperty("status",false)
end
function QuickApp:onInit()
self:debug(self.name,self.id)
end
Tusen tack!
I den ena så skickades credentials i HTTP-strängen. I den andra användes
SetBasicAuthentication.
Jag ska kolla på din kod i morgon.
Har sökt med ljus och lykta efter exempel på kod för HTTP, men det är väldigt tunt, både här och på Fibaros forum.
I min tidigare VD så ut så här.
FSC = Net.FHttp("192.168.x.xxx",80)
response = FSC:GET("/set_alarm.cgi?motion_armed=1&user=USER&pwd=PASSWORD")
fibaro:log(response)
Och så här:
AXISC = Net.FHttp("192.168.1.126",80)
AXISC:setBasicAuthentication("root","pass")
response = AXISC:GET("/axis-cgi/virtualinput/activate.cgi?schemaversion=1&port=1")
Mvh
I den ena så skickades credentials i HTTP-strängen. I den andra användes
SetBasicAuthentication.
Jag ska kolla på din kod i morgon.
Har sökt med ljus och lykta efter exempel på kod för HTTP, men det är väldigt tunt, både här och på Fibaros forum.
I min tidigare VD så ut så här.
FSC = Net.FHttp("192.168.x.xxx",80)
response = FSC:GET("/set_alarm.cgi?motion_armed=1&user=USER&pwd=PASSWORD")
fibaro:log(response)
Och så här:
AXISC = Net.FHttp("192.168.1.126",80)
AXISC:setBasicAuthentication("root","pass")
response = AXISC:GET("/axis-cgi/virtualinput/activate.cgi?schemaversion=1&port=1")
Mvh
Code: Select all
-- For axis
local user = "root"
local password = "pass"
local baseURL = "http://192.168.1.126/"
local activate = "axis-cgi/virtualinput/activate.cgi?schemaversion=1&port=1"
local deactivate = "axis-cgi/virtualinput/deactivate.cgi?schemaversion=1&port=1"
-- For FS
--[[
local user = nil
local password = nil
local baseURL = "http://192.168.x.xxx/"
local activate = "/set_alarm.cgi?motion_armed=1&user=USER&pwd=PASSWORD"
local deactivate = "/set_alarm.cgi?motion_armed=0&user=USER&pwd=PASSWORD"
--]]
local function base64encode(data)
__assert_type(data,"string" )
local bC='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
return ((data:gsub('.', function(x)
local r,b='',x:byte() for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c=0
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
return bC:sub(c+1,c+1)
end)..({ '', '==', '=' })[#data%3+1])
end
local function basicAuthorization(user,password) return "Basic "..base64encode(user..":"..password) end
local function sendCommand(cmd)
net.HTTPClient():request(baseURL..cmd,{
options = {
method = "GET",
headers = { ['Authorization'] = quickApp.creds }
},
success = function(resp) quickApp:debug("Success",json.encode(resp)) end,
error = function(err) quickApp:error(err) end
})
end
function QuickApp:turnOn()
self:debug("activating")
sendCommand(activate)
self:updateProperty("value",true)
self:updateProperty("status",true)
end
function QuickApp:turnOff()
self:debug("deactivating")
sendCommand(deactivate)
self:updateProperty("value",false)
self:updateProperty("status",false)
end
function QuickApp:onInit()
self:debug(self.name,self.id)
if password then
self.creds = basicAuthorization(user,password)
end
end
Anropet lägger till en 'Authorization' header i http anropet. Värdet av den är en textsträng "user:password", men den får inte vara i klartext utan kodat i base64 - en sorts "fattigmanskryptering" för att inte skicka lösenord i klartext i headern. Fördelen är att man slipper lösenordet i själva URLen så man slipper ha den synlig i koden - speciellt ett problem med länkar i html sidor (webbläsaren kan då lägga till headern när den skickar requested)
Tack igen!
Nu har jag kollat båda dina förslag till kod.
Jag vill inte kopiera rätt av utan vill förstå och sedan skapa min egen. Det är enda sättet för mig att lära mig något.
Det går framåt men jag saknar ett kraftfull debug-kommando. Ett generellt kommande som jag kan använda när jag tragglar mig framåt och där jag ser i loggen exakt vad QA-gör, rad för rad, men också vad jag får för svar från enheterna jag kommunicerar med. Finns det ett sådant?
Hittills så har jag bara fått det att fungera om jag skickar hela kommandot som en enda sträng eftersom kameran också kräver att jag lägger till port 80.
Nästa steg är att se om jag kan bygga ett kommando genom att lägga ihop variabler (som du gjort i ditt exempel). Hittills har det inte varit så lyckosamt eftersom jag inte ser vad QA skickar till kameran och inte heller vad kameran returnerar för svar.
Om man använder en browser för att skicka kommandot så får man ett svar tillbaka.
I sin enklaste form (från Foscam kameran) är det bara ett ”ok.”.
Axis sköter det med lite mer finess och skickar ett svar på flera rader.
Men än en gång, tack för att du tar dig tid.
Lev väl
Lasse Hedh
Nu har jag kollat båda dina förslag till kod.
Jag vill inte kopiera rätt av utan vill förstå och sedan skapa min egen. Det är enda sättet för mig att lära mig något.
Det går framåt men jag saknar ett kraftfull debug-kommando. Ett generellt kommande som jag kan använda när jag tragglar mig framåt och där jag ser i loggen exakt vad QA-gör, rad för rad, men också vad jag får för svar från enheterna jag kommunicerar med. Finns det ett sådant?
Hittills så har jag bara fått det att fungera om jag skickar hela kommandot som en enda sträng eftersom kameran också kräver att jag lägger till port 80.
Nästa steg är att se om jag kan bygga ett kommando genom att lägga ihop variabler (som du gjort i ditt exempel). Hittills har det inte varit så lyckosamt eftersom jag inte ser vad QA skickar till kameran och inte heller vad kameran returnerar för svar.
Om man använder en browser för att skicka kommandot så får man ett svar tillbaka.
I sin enklaste form (från Foscam kameran) är det bara ett ”ok.”.
Axis sköter det med lite mer finess och skickar ett svar på flera rader.
Men än en gång, tack för att du tar dig tid.
Lev väl
Lasse Hedh
Om du har tillgång till PC/Mac kan du använda min HC3 emulator for att koda dina QAs.
Jag utvecklar alla mina QAs dessa dagar i min emulator (inkl. koden till ditt exempel)
https://forum.fibaro.com/topic/55045-ti ... ator-tqae/
Fördelen är att man kodar i en riktig IDE med debugger (ZeroBrane studio) och kan steppa genom koden och sätta brytpunkter (ex. se vad som kommer tillbaka från ett http request)
Jag utvecklar alla mina QAs dessa dagar i min emulator (inkl. koden till ditt exempel)
https://forum.fibaro.com/topic/55045-ti ... ator-tqae/
Fördelen är att man kodar i en riktig IDE med debugger (ZeroBrane studio) och kan steppa genom koden och sätta brytpunkter (ex. se vad som kommer tillbaka från ett http request)
Last edited by jang on 17 Oct 2021, 18:12, edited 1 time in total.
Hej igen
Nu har jag ägnat stora delar av helgen till programmering utan att nå hela vägen fram.
Foscam kamerorna var inget problem då de accepterar alla credentials i URL:en.
Värre är det med styrningen av AXIS kamerorna, samma problem jag hade 2014 när jag skulle skriva den första VD:n för HC2. Då löste sig problemet med hjälp av SetBasicAuthentication som tyvärr inte fungerar i en QA.
Så här ser min senaste kod ut. Den är inte kopierad rakt av eftersom jag som sagt vill lära mig något också.
Snäll, kan du inte ta en titt på den med dina professionella programmerarögon och försöka lista ut var jag går vilse någonstans, fär fungerar gör den inte. Få bara Error 401 hela tiden.
Jag har lagt in några "print" här och där för att se vad variablerna innehåller, ett sätt för mig att förstå.
Just nu misstänker jag att headern inte är helt korrekt, men jag hittar inget sätt att se vad den innehåller.
Som du ser så är koden för turnOff ofullständig men jag har fokuserat på turnOn....
Kommer att vara dig evigt tacksam om du hittar var jag gått vilse.
Mvh
Lasse H
Nu har jag ägnat stora delar av helgen till programmering utan att nå hela vägen fram.
Foscam kamerorna var inget problem då de accepterar alla credentials i URL:en.
Värre är det med styrningen av AXIS kamerorna, samma problem jag hade 2014 när jag skulle skriva den första VD:n för HC2. Då löste sig problemet med hjälp av SetBasicAuthentication som tyvärr inte fungerar i en QA.
Så här ser min senaste kod ut. Den är inte kopierad rakt av eftersom jag som sagt vill lära mig något också.
Snäll, kan du inte ta en titt på den med dina professionella programmerarögon och försöka lista ut var jag går vilse någonstans, fär fungerar gör den inte. Få bara Error 401 hela tiden.
Jag har lagt in några "print" här och där för att se vad variablerna innehåller, ett sätt för mig att förstå.
Just nu misstänker jag att headern inte är helt korrekt, men jag hittar inget sätt att se vad den innehåller.
Som du ser så är koden för turnOff ofullständig men jag har fokuserat på turnOn....
Code: Select all
-- Binary switch type should handle actions turnOn, turnOff
-- To update binary switch state, update property "value" with boolean
local function base64encode(data)
__assert_type(data,"string" )
local bC='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
return ((data:gsub('.', function(x)
local r,b='',x:byte() for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c=0
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
return bC:sub(c+1,c+1)
end)..({ '', '==', '=' })[#data%3+1])
end
local function basicAuthorization(user,password) return "Basic "..base64encode(user..":"..password)
end
function QuickApp:turnOn()
self:debug("binary switch turned on")
self:updateProperty("value", true)
http:request(httpAddress ..activateURL,{options={method="GET"},
headers={['Authorization']=quickApp.creds},
success=function(response)
QuickApp:debug("Va fan",json.encode(response))
print(response.status)
print(response.data)
self:updateView("label1_1", "text", "Aktiverad")
end,
error=function(message)
print("ERROR:",message)
end
})
print(self.creds)
print(quickApp.creds)
print(method)
print(headers)
end
function QuickApp:turnOff()
self:debug("binary switch turned off")
self:updateProperty("value", false)
http:request(httpAddress ..activateURL,{options={method="GET"},
success=function(response)
print(response.status)
print(response.data)
self:updateView("label1_1", "text", "Aktiverad")
end,
error=function(message)
print("ERROR:",message)
end
})http:request(httpAddress ..deactivateURL,{options={method="GET"},
success=function(response)
print(response.status)
print(response.data)
self:updateView("label1_1", "text", "Deaktiverad")
end,
error=function(message)
print("ERROR:",message)
end
})
end
function QuickApp:onInit()
local user="root"
local password="pass"
self:debug("onInit")
self:debug(self.name,self.id)
http=net.HTTPClient({timeout=3000})
httpAddress="http://192.168.1.202/"
activateURL="axis-cgi/virtualinput/activate.cgi?schemaversion=1&port=1"
deactivateURL="axis-cgi/virtualinput/deactivate.cgi?schemaversion=1&port=1"
if password
then
self.creds=basicAuthorization(user,password)
end
print(httpAddress..activateURL)
print(httpAddress..deactivateURL)
end
Kommer att vara dig evigt tacksam om du hittar var jag gått vilse.
Mvh
Lasse H
Ngt i den här stilen
Det finns lite olika stilar. Antingen lägger du alla variabler i QuickApp objektet och accessar de med self.<variabelnamn> inuti alla function QuickApp:... som du kodar.
Eller så deklarera du dom 'local' i början av koden.
Du kan inte access QuickApp:debug(...). Du måste använda self:debug(...) eller quickApp:debug(...) som är en global variabel som är samma som 'self'.
Ditt största problem var att options argumentet till :request var fel så att credentials hamnade fel.
Code: Select all
_=loadfile and loadfile("TQAE.lua"){
user="admin", pwd="admin", host="192.168.1.57",
}
-- Binary switch type should handle actions turnOn, turnOff
-- To update binary switch state, update property "value" with boolean
local function base64encode(data)
__assert_type(data,"string" )
local bC='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
return ((data:gsub('.', function(x)
local r,b='',x:byte() for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c=0
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
return bC:sub(c+1,c+1)
end)..({ '', '==', '=' })[#data%3+1])
end
local function basicAuthorization(user,password)
return "Basic "..base64encode(user..":"..password)
end
function QuickApp:turnOn()
self:debug("binary switch turned on")
self:updateProperty("value", true)
self.http:request(self.httpAddress ..self.activateURL,{
options={
method="GET",
headers={['Authorization']=self.creds}
},
success=function(response)
self:debug("Va fan",json.encode(response))
self:debug(response.status)
self:debug(response.data)
self:updateView("label1_1", "text", "Aktiverad")
end,
error=function(message)
self:error(message)
end
})
end
function QuickApp:turnOff()
self:debug("binary switch turned off")
self:updateProperty("value", false)
self.http:request(self.httpAddress ..self.deactivateURL,{
options={
method="GET",
headers={['Authorization']=self.creds}
},
success=function(response)
self:debug(response.status)
self:debug(response.data)
self:updateView("label1_1", "text", "Deaktiverad")
end,
error=function(message)
self:error(message)
end
})
end
function QuickApp:onInit()
local user="root"
local password="pass"
self:debug("onInit")
self:debug(self.name,self.id)
self.http=net.HTTPClient({timeout=3000})
self.httpAddress="http://192.168.1.202/"
self.activateURL="axis-cgi/virtualinput/activate.cgi?schemaversion=1&port=1"
self.deactivateURL="axis-cgi/virtualinput/deactivate.cgi?schemaversion=1&port=1"
if password
then
self.creds=basicAuthorization(user,password)
end
self:debug(self.httpAddress..self.activateURL)
self:debug(self.httpAddress..self.deactivateURL)
end
Eller så deklarera du dom 'local' i början av koden.
Du kan inte access QuickApp:debug(...). Du måste använda self:debug(...) eller quickApp:debug(...) som är en global variabel som är samma som 'self'.
Ditt största problem var att options argumentet till :request var fel så att credentials hamnade fel.