Here's another version that automatically adds users and scenes too. All room/device/scene/etc names are converted to lowercase (except the mobile device name so it can be copy/pasted from the Access Control settings page on HC2).
ID's are available using the following format:
HC2["zwave devices"]["room name"]["device name"]
HC2["virtual devices"]["room name"]["device name"]
HC2["mobile devices"]["device name"]
HC2["scenes"]["room name"]["scene name"]
HC2["users"]["user name"]
--[[
%% autostart
%% properties
%% events
%% globals
--]]
local global = "HC2" -- set to name of global variable to store table
local debug = false -- Debug Output: true = enabled / false = disabled
-- DO NOT EDIT BELOW THIS LINE
function log(msg)
if debug and msg then fibaro:debug(tostring(msg)) end
end
local http = {
client = net.HTTPClient(),
baseUrl = "http://127.0.0.1:11111/api/",
}
function http:new (parent)
self.parent = parent
return self
end
function http:failure (params)
log("Failed loading " .. tostring(params.category) .. " (" .. tostring(params.error) .. ")")
end
function http:success (params)
if params.response.status == 200 then
log(params.category .. " information retreived")
for n, data in pairs(json.decode(params.response.data)) do self.parent:add(params.category, data) end
self.parent:save(params.category)
else
self:failure({category = params.category, error = params.response.status})
end
end
function http:get (category)
if type(category) == "table" then
for k, v in pairs(category) do self:get(v) end
elseif category then -- validate category
log("\r\nLOADING " .. category:upper() .. "...")
self.parent.complete[category] = false
self.client:request(
self.baseUrl .. category,
{
success = function(status)
self:success({category = category, response = status})
end,
error = function(error)
self:failure({category = category, error = error})
end
}
)
end
end
local this = {
[global] = {}, -- global variable name to store table
["complete"] = {},
}
function this:http ()
return http:new(self)
end
function this:save (category)
fibaro:debug(category .. " information collated")
self.complete[category] = nil
for k, v in pairs(self.complete) do return nil end -- items still waiting completion
fibaro:setGlobal("CreateGlobal", global) -- optional scene trigger to create new global
fibaro:setGlobal(global, type(self[global]) == "table" and json.encode(self[global]) or self[global])
if not pcall(
function()
local test = json.decode(fibaro:getGlobalValue(global)) -- retrieve saved global
if type(test) ~= "table" then error() end -- check global is a table
log("\r\nGLOBAL " .. global .. " TABLE CONTENTS")
log(json.encode(test))
fibaro:debug("Global ID's table '" .. global .. "' has been stored successfully")
end
) then
fibaro:debug("Failed to create global table :(")
end
end
function this:add (category, data)
if category == "users" or category:match("mobile") then
self[global][category] = self[global][category] or {} -- intialise category table
self[global][category][category:match("mobile") and data.name or data.name:lower()] = data.id
elseif category == "scenes" or category:match("devices") then
local room = (data.room or fibaro:getRoomName(data.roomID) and fibaro:getRoomName(data.roomID) or "unassigned"):lower() -- Fibaro bug workaround
self[global][category] = self[global][category] or {} -- intialise category table
self[global][category][room] = self[global][category][room] or {} -- initialise room table
self[global][category][room][data.name:lower()] = data.id
end
end
-- LOAD SCENES & USERS
this:http():get({"scenes", "users"})
-- LOAD DEVICES
local devices = {
["mobile devices"] = fibaro:getDevicesId(
{
enabled = true,
type = "iOS_device"
}
),
["virtual devices"] = fibaro:getDevicesId(
{
enabled = true,
type = "virtual_device"
}
),
["zwave devices"] = fibaro:getDevicesId(
{
visible = true,
enabled = true,
interfaces = {
"zwave",
},
}
),
}
log("\r\nLOADING DEVICES...")
for category, list in pairs(devices) do
log(category:upper() .. " ID's = " .. json.encode(list))
this.complete[category] = false
for n, id in ipairs(list) do
this:add(
category,
{
id = id,
name = fibaro:getName(id),
room = fibaro:getRoomNameByDeviceID(id),
}
)
end
this:save(category)
end