[Solved] http request, json device list empty

Discussions about RaZberry - Z-Wave board for Raspberry computer
Post Reply
billyboy
Posts: 61
Joined: 16 Mar 2013 21:33

[Solved] http request, json device list empty

Post by billyboy »

I use Python from a other app to get the device states from the razberry server.
I added authentication to get it working again with newer rc versions. This worked but now I have updated my Raspberry and Razberry, but in the the json response, the device list is empty.

{"data":{"structureChanged":true,"updateTime":1437159527,"devices":[]},"code":200,"message":"200 OK","error":null}

If I request the same url after login in the browser I get the complete device list.

I don't get e error code like 401 or 404.

Is something changed?
Last edited by billyboy on 28 Jul 2015 10:13, edited 1 time in total.
Mike Yeager
Posts: 160
Joined: 03 May 2014 07:02

Re: http request, json device list empty

Post by Mike Yeager »

I'm upgrading from v1.7.0 and used to use the command:

http://127.0.0.1:8083/ZWaveAPI/data/0

to retrieve the JSON data from ZWay. Once I upgraded, I got a message that simply read "Bad ZWaveAPI request". I'm sure that something has changed and I'm working my way through looking for documentation, but I would greatly appreciate a quick fix.

I saw a lot of neat stuff in the new version and I'd love to be able to get in and figure some of it out but I need to be able to access the API in order to do so.

OK, so I managed to get this to work again. Apparently the API is a little more sensitive to capitalization now. The data had to be Data.... Now I can get back to work!!!
billyboy
Posts: 61
Joined: 16 Mar 2013 21:33

Re: http request, json device list empty

Post by billyboy »

sdh
Posts: 66
Joined: 25 Feb 2014 11:37

Re: http request, json device list empty

Post by sdh »

Domoticz is not working with z-way anymore. Any idea what changes need to be done on domoticz side. The current code looks like this:

Code: Select all

const std::string CRazberry::GetControllerURL()
{
	std::stringstream sUrl;
	if (m_username=="")
		sUrl << "http://" << m_ipaddress << ":" << m_port << "/ZWaveAPI/Data/" << m_updateTime;
	else
		sUrl << "http://"  << m_username << ":" << m_password << "@" << m_ipaddress << ":" << m_port << "/ZWaveAPI/Data/" << m_updateTime;
	return sUrl.str();
}

const std::string CRazberry::GetRunURL(const std::string &cmd)
{
	std::stringstream sUrl;
	if (m_username=="")
		sUrl << "http://" << m_ipaddress << ":" << m_port << "/ZWaveAPI/Run/" << cmd;
	else
		sUrl << "http://"  << m_username << ":" << m_password << "@" << m_ipaddress << ":" << m_port << "/ZWaveAPI/Run/" << cmd;
	return sUrl.str();
}
billyboy
Posts: 61
Joined: 16 Mar 2013 21:33

Re: http request, json device list empty

Post by billyboy »

Update:

I made a simple python test script to fetch the devices. To that a added al lot of ways to implement authorization but none of them worked. The response I get says that there is no protection at all, but device list is still empty.

result: This page isn't protected by authentication

Code: Select all

import urllib2, sys, re, base64
from urlparse import urlparse

topLevelUrl = 'http://127.0.0.1:8083'
url='http://127.0.0.1:8083/ZAutomation/api/v1/devices'
username = 'user'
password = 'password'

#Testing authentication
req = urllib2.Request(url)
try:
    handle = urllib2.urlopen(req)
except IOError, e:                  # here we are assuming we fail
    pass
else:                               # If we don't fail then the page isn't protected
    print "This page isn't protected by authentication."
    sys.exit(1)
    
if not hasattr(e, 'code') or e.code != 401:                 # we got an error - but not a 401 error
    print "This page isn't protected by authentication."
    print 'But we failed for another reason.'
    sys.exit(1)

authline = e.headers.get('www-authenticate', '')                # this gets the www-authenticat line from the headers - which has the authentication scheme and realm in it
if not authline:
    print 'A 401 error without an authentication response header - very weird.'
    sys.exit(1)
    
authobj = re.compile(r'''(?:\s*www-authenticate\s*:)?\s*(\w*)\s+realm=['"](\w+)['"]''', re.IGNORECASE)          # this regular expression is used to extract scheme and realm
matchobj = authobj.match(authline)
if not matchobj:                                        # if the authline isn't matched by the regular expression then something is wrong
    print 'The authentication line is badly formed.'
    sys.exit(1)
scheme = matchobj.group(1) 
realm = matchobj.group(2)
if scheme.lower() != 'basic':
    print 'This example only works with BASIC authentication.'
    sys.exit(1)

base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
authheader =  "Basic %s" % base64string
req.add_header("Authorization", authheader)
try:
    handle = urllib2.urlopen(req)
except IOError, e:                  # here we shouldn't fail if the username/password is right
    print "It looks like the username or password is wrong."
    sys.exit(1)
thepage = handle.read()
    
server = urlparse(url)[1].lower()            # server names are case insensitive, so we will convert to lower case
test = server.find(':')
if test != -1: server = server[:test]           # remove the :port information if present, we're working on the principle that realm names per server are likely to be unique...

passdict = {(server, realm) : authheader }      # now if we get another 401 we can test for an entry in passdict before having to ask the user for a username/password

print 'Done successfully - information now stored in passdict.'
print 'The webpage is stored in thepage.'
billyboy
Posts: 61
Joined: 16 Mar 2013 21:33

Re: http request, json device list empty

Post by billyboy »

again a update:

Replacing http://127.0.0.1 with the external ip address, I get a different reaction from my test script:

A 401 error without an authentication response header - very weird.

So there is no 'www-authenticate' key in the header.
fableman
Posts: 62
Joined: 01 Mar 2015 13:16

Re: http request, json device list empty

Post by fableman »

I feel your pain, after upgrading I cant get any curl based login to work, I put loooots of hours coding and I can't even downgrade to make my house lightning , alarm, doors, garage door to work again!

Please share if you find any solution to get authentication to work.
billyboy
Posts: 61
Joined: 16 Mar 2013 21:33

Re: http request, json device list empty

Post by billyboy »

I will share if I have a solution Fableman.
User avatar
PoltoS
Posts: 7594
Joined: 26 Jan 2011 19:36

Re: http request, json device list empty

Post by PoltoS »

Please look our FAQ about authentication (How to execute API commands via HTTP API? - http://razberry.z-wave.me/index.php?id=13).

The reason for empty devices list is Anonymous user with no access to devices by default.
billyboy
Posts: 61
Joined: 16 Mar 2013 21:33

Re: http request, json device list empty

Post by billyboy »

Tanks to PoltoS, I made some changes to allow cookie validation and now and it works!
I use the requests library in Python and added a session. To get JSon string with all devices I made following test script:

Code: Select all

import json
import requests

topLevelUrl = 'http://127.0.0.1:8083'
DevicesUrl= topLevelUrl +'/ZAutomation/api/v1/devices'
LoginUrl = topLevelUrl + '/ZAutomation/api/v1/login'
username = 'admin'
password = 'password'
LoginHeader = {'User-Agent': 'Mozilla/5.0', 'Content-Type': 'application/json'}
Formlogin = '{"form": true, "login": "'+username+'", "password": "'+password+'", "keepme": false, "default_ui": 1}'

session = requests.Session()
session.post(LoginUrl,headers=LoginHeader, data=Formlogin)

response = session.get(DevicesUrl)
#html = response.text
#print html
parsed_json = response.json()
print parsed_json
Post Reply