Im hitting an issue with xml2lua and i dont understand why.
I’m when i’m running my discovery code on my local dev machine xml2lua works flawlessly and i get everythign i need out of it etc but when I run it on the hub it seems to fail to parse the xml and i end up with a table but with nothing in it… but i dont get any parsinig error messages. it seeems to parse ok.
discovery thread encountered error: [string “discovery.lua”]:56: attempt to index a nil value (field ‘root’)
It happened to me weeks ago.
As I remember, io.open isn’t available when running on the hub.
I think this is for security reasons.
In my case, I was trying to read yaml file.
I had to convert the yaml to string json inside lua file. Then, I do this: json.decode(require("my_json"))
So, instead of using io.open, I used require.
Some functions have been removed where they are impossible to use from within the sandbox, such as those dealing with filesystem access. Some have been reimplemented, matching the behavior of the standard lua implementation to work with the sandbox, such as require.
Source: Global Environment — SmartThings Edge Device Drivers documentation
local function fetch_device_info(url)
log.info("getting Metadata")
local res = {}
local _, status = http.request({
url=url,
sink=ltn12.sink.table(res)
})
-- XML Parser
local xmlres = xml_handler:new()
local xml_parser = xml2lua.parser(xmlres)
xml_parser:parse(table.concat(res))
print(xml2lua.printable(xmlres.root))
local meta = xmlres
if not xmlres.root or not meta then
log.error('Failed to get Metadata at: '..url)
return nil
end
return {
ip = url:match("http://([^,]+):([^/]+)"),
name=meta.root.root.device.friendlyName,
vendor=meta.root.root.device.UDN,
mn=meta.root.root.device.manufacturer,
model=meta.root.root.device.modelName,
description=meta.root.root.device.modelDescription,
location="http://"..url:match("http://([^,]+):([^/]+)")
}
end
xmlres ends up as a table but seems to be empty and i get the error discovery thread encountered error: [string “discovery.lua”]:52: attempt to index a nil value (field ‘root’) when trying to get name=meta.root.root.device.friendlyName
If i do the same on my local dev machine it all works fine.
I found the problem. You cant use the standard lua socket lib. The request was returning empty but i didnt realise until I started back tracking to make sure i was getting the response.
Replacing it with the cosock version solves the issue