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


Changing http request from HC2 VD to HC3 QuickApp ("Robonect"- modul for Husqvarner Automower)


Speedo67

Recommended Posts

Hello guys,

 

for the first: english ist not my first language - sorry!

 

I have on HC2 a running VD to integrate a ROBONECT-modul (www.robonect.de) on HC2. Now, i am a owner of a HC3 (5.110.15) and i will change the request to HC3 Quickapp.
The running code on VD  for get a http request for status looks like this:

-----------------------------------------------------------------------------------------------------------------------------------------

-- Setze Verbindungsdaten
-- hole ip adresse aus virtuellem modul
local selfId = fibaro:getSelfId()
local mowerIP = fibaro:get(selfId, "IPAddress")
local mowerPort = fibaro:get(selfId, "TCPPort")
local versuche = 3
-- setze variable MOWER aus IP und Logindaten
MOWER = Net.FHttp(mowerIP)
MOWER:setBasicAuthentication("xxxx","xxxx")
--check Onlinestatus
local function _ping(retry)
    fibaro:call(selfId, "setProperty", "ui.OLStatus.value", "Starte Online-Check")
    fibaro:sleep(500)
    retry = retry or 0
    local tcpSocket = Net.FTcpSocket(mowerIP, mowerPort)
    tcpSocket:setReadTimeout(250)
    --fibaro:debug('Suche..., versuche #' .. retry .. ' bitte warten...')
    fibaro:sleep(250)
    local bytes, errorCode = tcpSocket:write('ping')

    if errorCode == 0 then
        return true
    else
        if retry < versuche then
        --fibaro:debug('Nicht gefunden, erneut versuchen, bitte warten...')
        fibaro:sleep(500);
    return _ping(retry + 1)
end
    return false
end
end

local f, result = pcall(_ping)

if (f) then
    if (result == true) 

    then
        fibaro:debug(mowerIP.. ':' .. mowerPort .. ' wurde gefunden,')
 
        fibaro:call(selfId, "setProperty", "ui.OLStatus.value", "Mower ist Online");
        fibaro:debug("Status wird abgefragt");

        fibaro:debug("Status online - starte Abfragen");
    else
        fibaro:debug(mowerIP.. ':' .. mowerPort .. ' wurde nicht gefunden.')
        fibaro:call(selfId, "setProperty", "ui.OLStatus.value", "Mower ist Offline")
        fibaro:debug("Status des Automower wird aufgrund mangelnder Erreichbarkeit nicht abgefragt")
        fibaro:debug("Status wurde nicht abgefragt, warte für 5 Minuten)");
        fibaro:sleep(300000)
    end

else
    fibaro:debug('Error: ' .. f)
end

 
-- geting info about specific device
  response = MOWER:GET("/json?cmd=status")
 --fibaro:debug(response) 
-- decoding json string to table
  extractedjson = json.decode(response)

-- "status/battery": "Battery Status"
-- "status/duration": "Mode Duration"
-- "status/hours": "Hours"
-- "status/mode": "Mode"
-- "status/status": "Status"
-- "timer/status": "Timer Status"

  battery = extractedjson.status.battery
  duration = extractedjson.status.duration
  hours = extractedjson.status.hours
  AM_Status = extractedjson.status.status
  AM_Mode = extractedjson.status.mode
  AM_Timer = extractedjson.timer.status
 -- Error_ = extractedjson.error.status


--fibaro:debug(battery.."%")
--fibaro:debug(duration.."s")
--fibaro:debug(hours.."h")
--fibaro:debug(AM_Status)
--fibaro:debug(AM_Mode)
--fibaro:debug(AM_Timer)
--fibaro:debug(Error_)


  fibaro:call(selfId, "setProperty", "ui.LabelBatterystatus.value",(battery).." %");
 
  fibaro:call(selfId, "setProperty", "ui.LabelModeDuration.value",(duration).." s");
   
  fibaro:call(selfId, "setProperty", "ui.LabelHours.value",(hours).."h");
 
  --fibaro:call(selfId, "setProperty", "ui.LabelMode.value",(AM_Mode));

  --fibaro:call(selfId, "setProperty", "ui.LabelStatus.value",(AM_Status));

  --fibaro:call(selfId, "setProperty", "ui.LabelTimer.value",(AM_Timer));

 
--fibaro:debug("Status Auswertung gestartet") 
--fibaro:debug("Autmowerstatus = "..AM_Status)
fibaro:call(selfId, "setProperty", "ui.LabelStatus.value","Check Mowerstatus");
fibaro:sleep(500)
if (AM_Status == 17) then
  fibaro:call(selfId, "setProperty", "ui.LabelStatus.value"," Automower schläft");
  fibaro:call(selfId, "setProperty", "currentIcon","1013");
  fibaro:log("Status: Automower schläft")
  fibaro:setGlobal("MowerStatus", "sleeping")
  --fibaro:debug("Automower schläft")
elseif (AM_Status == 1) then
  fibaro:call(selfId, "setProperty", "ui.LabelStatus.value"," Automower parkt/hat gestoppt");
   fibaro:call(selfId, "setProperty", "currentIcon","1017");
  fibaro:log("Status: Automower parkt")
  --fibaro:debug("Automower parkt")
  fibaro:setGlobal("MowerStatus", "parking")
elseif (AM_Status == 2) then
  fibaro:call(selfId, "setProperty", "ui.LabelStatus.value"," Automower mäht");
   fibaro:call(selfId, "setProperty", "currentIcon","1010");
  fibaro:log("Status: Automower mäht")
  --fibaro:debug("Automower mäht")
  fibaro:setGlobal("MowerStatus", "mowing")
elseif (AM_Status == 3) then
  fibaro:call(selfId, "setProperty", "ui.LabelStatus.value"," Automower sucht die Ladestation");
   fibaro:call(selfId, "setProperty", "currentIcon","1014");
  fibaro:log("Status: Automower sucht die Ladestation")
  --fibaro:debug("Automower sucht die Ladestation")
  fibaro:setGlobal("MowerStatus", "searching")
elseif (AM_Status == 4) then
  fibaro:call(selfId, "setProperty", "ui.LabelStatus.value"," Automower lädt");
   fibaro:call(selfId, "setProperty", "currentIcon","1016");
  fibaro:log("Status: Automower lädt")
  --fibaro:debug("Automower lädt")
  fibaro:setGlobal("MowerStatus", "charging")
elseif (AM_Status == 5) then
  fibaro:call(selfId, "setProperty", "ui.LabelStatus.value"," Automower sucht (manuell umsetzen)");
  fibaro:call(selfId, "setProperty", "currentIcon","1015");
  fibaro:log("Status: Automower sucht (manuell umsetzen)")
  --fibaro:debug("Automower sucht (manuell umsetzen)")
elseif (AM_Status == 7) then
  fibaro:call(selfId, "setProperty", "ui.LabelStatus.value"," Fehlerstatus");
  fibaro:log("Status: Fehlerstatus")
  --fibaro:debug("Fehlerstatus")
elseif (AM_Status == ? then
  fibaro:call(selfId, "setProperty", "ui.LabelStatus.value"," Schleifensignal verloren");
   fibaro:call(selfId, "setProperty", "currentIcon","1012");
  fibaro:log("Status: Automower Schleifensignal verloren")
  --fibaro:debug("Automower Schleifensignal verloren")
  fibaro:setGlobal("MowerStatus", "lost_signal")
else
  fibaro:call(selfId, "setProperty", "ui.LabelState.value"," Error");
  fibaro:log("Status: Ladefehler")
  --fibaro:debug("Ladefehler")
end 
  
fibaro:setGlobal("AM_Status", AM_Status);
fibaro:call(selfId, "setProperty", "ui.LabelMode.value","Check Mowermodus");

fibaro:sleep(500);


--fibaro:debug("Modus Auswertung gestartet")

if (AM_Mode == 0) then
  fibaro:call(selfId, "setProperty", "ui.LabelMode.value"," Auto");
  fibaro:log("Mode: Auto")
  --fibaro:debug("Auto")
    fibaro:setGlobal("MowerMode", "Auto")
elseif (AM_Mode == 1) then
  fibaro:call(selfId, "setProperty", "ui.LabelMode.value"," Manuell");
  fibaro:log("Mode: Manuell")
  --fibaro:debug("Manuell")
  fibaro:setGlobal("MowerMode", "Man")
elseif (AM_Mode == 2) then
  fibaro:call(selfId, "setProperty", "ui.LabelMode.value"," Home");
  fibaro:log("Mode: Home")
  --fibaro:debug("Home")
  fibaro:setGlobal("MowerMode", "Home")
else
  fibaro:call(selfId, "setProperty", "ui.LabelMode.value"," Error");
  fibaro:log("Mode: Fehler")
  fibaro:debug("Fehler")
end

  fibaro:setGlobal("AM_Mode", AM_Mode);
fibaro:call(selfId, "setProperty", "ui.LabelTimer.value","Check Timermodus");

fibaro:sleep(500);


--fibaro:debug("Timer Auswertung gestartet")

if (AM_Timer == 0) then
  fibaro:call(selfId, "setProperty", "ui.LabelTimer.value"," Deaktiviert");
  fibaro:log("Timer: Deaktiviert")
  --fibaro:debug("Deaktiviert")
elseif (AM_Timer == 1) then
  fibaro:call(selfId, "setProperty", "ui.LabelTimer.value"," Auto");
  fibaro:log("Timer: Auto")
  fibaro:debug("Auto")
elseif (AM_Timer == 2) then
  fibaro:call(selfId, "setProperty", "ui.LabelTimer.value"," Standby");
  fibaro:log("Timer: Standby")
  fibaro:debug("Standby")
else
  fibaro:call(selfId, "setProperty", "ui.LabelTimer.value"," Error");
  fibaro:log("Timer: Fehler")
  fibaro:debug("Fehler")

end 

  fibaro:setGlobal("AM_Timer", AM_Timer);

----------------------------------------------------------------------------------------------------------------------

on a webbrowser i get a complete status with this:

http://<user>:<password>@<ip>:<port>/json?cmd=status


{"name": "MowerReiche", "id": "10AD57", "status": {"status": 17, "distance": 0, "stopped": false, "duration": 42067, "mode": 2, "battery": 100, "hours": 2604}, "timer": {"status": 0, "next": {"date": "2022-07-07", "time": "10:00:00", "unix": 1657188000}}, "blades": {"quality": 84, "hours": 22, "days": 15}, "wlan": {"signal": -89}, "health": {"temperature": 24, "humidity": 28}, "clock": {"date": "2022-07-07", "time": "08:20:55", "unix": 1657182055}, "successful": true}

 

My code for HC3 QuickApp to get a status-info:

---------------------------------------------------------------------------------------------------------------------

local self
local function setSelf(qa) self = qa end
 
function Base64(data)
    local b='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 < 6then return '' end
        local c=0
        for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0end
        return b:sub(c+1,c+1)
    end)..({ '''==''=' })[#data%3+1])
end
 
function QuickApp:onInit()
    self:debug("onInit")
    setSelf(self)
    self:debug("onInit")
    ip = self:getVariable("ip")
    port = tonumber(self:getVariable("port"))
    self.sock = net.TCPSocket()
    usr = Base64(self:getVariable("user"))
    pwd = Base64(self:getVariable("pwd"))
    address = "http://"..usr..":"..pwd.."@"..ip..":"..port.."/json?cmd=status"
    self:command(address)
end
 
function QuickApp:command(address)
 
self.http = net.HTTPClient({timeout=3000})
print(address)
    self.http:request(address, {
        options={
            headers = { 
                Accept = "application/json"
            },
            checkCertificate = false,
            method = 'GET'
        },
        
        success = function(response)
            self:debug("response status:", response.status) 
            --self:debug("headers:", response.headers["Content-Type"]) 
            local data = json.decode(response.data)
        end,
        error = function(error)
            self:debug('error: ' .. json.encode(error))
        end
    }) 
end

--------------------------------------------------------------------------------------------------------------------
 
I try for hours, but every time i get a "401" response.

What notation can solve this?

 

 

 

Link to comment
Share on other sites

  • 2 weeks later...

Try this, it could work...

Please login or register to see this code.

 

Link to comment
Share on other sites

  • Topic Author
  • Hello @jgab, thank you so much! Now response-status is 200. If you left a little bit time, what was my mistake?
    In addition i publish the final QA in the forum.

    Thanks once more! 

    Link to comment
    Share on other sites

    1 hour ago, Speedo67 said:

    Hello @jgab, thank you so much! Now response-status is 200. If you left a little bit time, what was my mistake?
    In addition i publish the final QA in the forum.

    Thanks once more! 

    You can't encode the user/pwd in the url. You needed to provide the authorisation header with basic authorisation credential.

    Link to comment
    Share on other sites

    • 3 weeks later...
  • Topic Author
  • Hello @jgab i need once more your support. In my project to change VD from HC2 to QA in HC3 for ROBONECT i can't receive data from the web-server. I only get  "nil" on this code (see also your post earlier, i use your proposal code 1:1):
     

     success = function(response)
                self:debug("response status:", response.status) 
                --self:debug("headers:", response.headers["Content-Type"]) 
                local data = json.decode(response.data)  
                self:debug(data)
    output:

    [13.08.2022] [09:31:26] [DEBUG] [QUICKAPP764]: onInit
    [13.08.2022] [09:31:34] [TRACE] [QUICKAPP764]: UIEvent: {"values":[null],"elementName":"button1","deviceId":764,"eventType":"onReleased"}
    [13.08.2022] [09:31:34] [DEBUG] [QUICKAPP764]: response status: 200
    [13.08.2022] [09:31:34] [DEBUG] [QUICKAPP764]: nil


    attached once again the output for a web-request

    Thanks in advance for input to fix my problem!

    Please login or register to see this attachment.

    Link to comment
    Share on other sites

    Start by logging the full response - then we see what we have to work with...

    Please login or register to see this code.

     

    Link to comment
    Share on other sites

  • Topic Author
  • Hello @jgab this is the result:

    [13.08.2022] [10:32:20] [DEBUG] [QUICKAPP764]: onInit
    [13.08.2022] [10:32:22] [TRACE] [QUICKAPP764]: UIEvent: {"elementName":"button1","values":[null],"deviceId":764,"eventType":"onReleased"}
    [13.08.2022] [10:32:23] [DEBUG] [QUICKAPP764]: response status: 200
    [13.08.2022] [10:32:23] [DEBUG] [QUICKAPP764]: {"status":200,"data":"","headers":{"Connection":"close","Content-Length":"0","Cache-Control":"no-cache","Content-Type":"application\/json","Server":"FHDR"}}

    Link to comment
    Share on other sites

  • Topic Author
  • Hello @jgab , i know, i'm a little bit flashy, but can you please take once more a look at my problem? Thanks in advance!

    Link to comment
    Share on other sites

    On 8/13/2022 at 10:33 AM, Speedo67 said:

    Hello @jgab this is the result:
    [13.08.2022] [10:32:23] [DEBUG] [QUICKAPP764]: {"status":200,"data":"","headers":{"Connection":"close","Content-Length":"0","Cache-Control":"no-cache","Content-Type":"application\/json","Server":"FHDR"}}

    Well, you are obviously not getting any response. I'm a bit surprised that you get the 200 status. 

     

    What is the full URL when you do a web request? (that succeeds)

    Link to comment
    Share on other sites

  • Topic Author
  • Hello @jgab this request gives a full dataset of status:

    http://user:[email protected]/json?cmd=status


    Please login or register to see this image.

    /monthly_2022_08/image.png.d4ee97fac42b380b0b0f5f22350fa14f.png" />

    Please login or register to see this attachment.


    image.png.9f3e261e25e7d4a6317b1ec22ed8842b.png

    Link to comment
    Share on other sites

    What if you add the missing headers to the http request?

    Please login or register to see this code.

     

    I wonder if the "upgrade-insecure-requests" is a sign that the call should be an https request.

    Could you also try to change the url to be 

    Please login or register to see this code.

    ...if the extra headers don't help.

    Link to comment
    Share on other sites

  • Topic Author
  • Hello @jgab thank you very much for your reply. Unfortunaly there ist still "nil" at the data-response. The https request gives a ERR_CONNECTION_TIMED_OUT...

    Link to comment
    Share on other sites

    What happens if you do your own http request with tcpsocket?

    Please login or register to see this code.

     

    Link to comment
    Share on other sites

  • Topic Author
  • Hello @jgab this code brings only
    [27.08.2022] [16:37:40] [DEBUG] [QUICKAPP898]: onInit

    [27.08.2022] [16:37:40] [DEBUG] [QUICKAPP898]: http://192.168.178.150:80/json?cmd=status

    [27.08.2022] [16:37:40] [DEBUG] [QUICKAPP898]: ""

    [27.08.2022] [16:37:40] [ERROR] [QUICKAPP898]: nil

     

    If i add "realm" in the codeline

    self.credentials = "Basic realm"..Base64(self:getVariable("user")..":"..self:getVariable("password"))
    then the result changing:
    [27.08.2022] [16:42:16] [DEBUG] [QUICKAPP898]: onInit
    [27.08.2022] [16:42:16] [DEBUG] [QUICKAPP898]: http://192.168.178.150:80/json?cmd=status
    [27.08.2022] [16:42:16] [DEBUG] [QUICKAPP898]: ""
    [27.08.2022] [16:42:16] [DEBUG] [QUICKAPP898]: Success: Cache-Control: no-cache WWW-Authenticate: Basic realm= "MowerReiche (Robonect Hx+)" Set-Cookie: Login=; Max-Age=31536000; HttpOnly
     
    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
    Reply to this topic...

    ×   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...