-
Compteur de contenus
206 -
Inscription
-
Dernière visite
-
Jours gagnés
41
Tout ce qui a été posté par jang
-
Well, of course there was a small problem with my code.... Try this version The load and creation of children is protected with a pcall. do local childID = 'ChildID' local classID = 'ClassName' local defChildren local children = {} local undefinedChildren = {} local createChild = QuickApp.createChildDevice class 'QwikAppChild'(QuickAppChild) function QwikAppChild:__init(device) QuickAppChild.__init(self, device) self:debug("Instantiating object ",device.name) local uid = self:getVariable(childID) or "" if defChildren[uid] then children[uid]=self -- Keep table with all children indexed by uid. uid is unique. else -- If uid not in our children table, we will remove this child undefinedChildren[#undefinedChildren+1]=self.id end end function QuickApp:createChildDevice(uid,props,interfaces,className) __assert_type(uid,'string') __assert_type(className,'string') props.initialProperties = props.initialProperties or {} local qas = {{name=childID,value=uid},{name=classID,value=className}} props.initialProperties.quickAppVariables = qas props.initialInterfaces = interfaces self:debug("Creating device ",props.name) return createChild(self,props,_G[className]) end local function getVar(child,varName) for _,v in ipairs(child.properties.quickAppVariables or {}) do if v.name==varName then return v.value end end return "" end function QuickApp:loadExistingChildren(chs) __assert_type(chs,'table') local stat,err = pcall(function() defChildren = chs self.children = children function self.initChildDevices() end local cdevs,n = api.get("/devices?parentId="..self.id) or {},0 -- Pick up all my children for _,child in ipairs(cdevs) do local uid = getVar(child,childID) local className = getVar(child,classID) local childObject = _G[className] and _G[className](child) or QuickAppChild(child) self.childDevices[child.id]=childObject childObject.parent = self end end) if not stat then self:error("loadExistingChildren:"..err) end end function QuickApp:createMissingChildren() local stat,err = pcall(function() for uid,data in pairs(defChildren) do if not self.children[uid] then local props = { name = data.name, type = data.type, } self:createChildDevice(uid,props,data.interfaces,data.className) end end end) if not stat then self:error("createMissingChildren:"..err) end end function QuickApp:removeUndefinedChildren() for _,deviceId in ipairs(undefinedChildren) do -- Remove children not in children table self:removeChildDevice(deviceId) end end end ------------------------------- -- 1 - Definition of class ------------------------------- class 'Class_Temp'(QwikAppChild) -- Class NOM_Temps pour "com.fibaro.temperatureSensor" ------------------------------- -- 2 - Class constructor ------------------------------- function Class_Temp:__init(device) QwikAppChild.__init(self, device) end -------------------------------- -- 3 - Definition of children -------------------------------- local myChildren = { -- Unique ID (uid) -> child initialization data, in our case the name ["Child_Temps1"] = { name="Température1", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps2"] = { name="Température2", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps3"] = { name="Température3", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps4"] = { name="Température4", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps5"] = { name="Température5", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps6"] = { name="Température6", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, } -------------------------------- -- 4 - Initialization of children -------------------------------- function QuickApp:onInit() self:loadExistingChildren(myChildren) self:createMissingChildren() self:removeUndefinedChildren() self:update_child("Child_Temps5") -- example, update child with uid 'Child_Temps5' -- for uid,_ in pairs(self.children) do -- update all children -- self:update_child(uid) -- end end -------------------------------- -- 5 - Accessing children -------------------------------- function QuickApp:update_child(uid) local default_temp = 37 --- pour l'ex du tuto local default_log = " I'm bad " --- pour l'ex du tuto self.children[uid]:updateProperty("value", default_temp) self.children[uid]:updateProperty("log", default_log) end
-
So, if we refine the code and create a library of it do local childID = 'ChildID' local classID = 'ClassName' local defChildren children = {} local undefinedChildren = {} local createChild = QuickApp.createChildDevice class 'QwikAppChild'(QuickAppChild) function QwikAppChild:__init(device) QuickAppChild.__init(self, device) local uid = self:getVariable(childID) or "" if defChildren[uid] then children[uid]=self -- Keep table with all children indexed by uid. uid is unique. else -- If uid not in our children table, we will remove this child undefinedChildren[#undefinedChildren+1]=self.id end end function QuickApp:createChildDevice(uid,props,interfaces,className) __assert_type(uid,'string') __assert_type(className,'string') props.initialProperties = props.initialProperties or {} local qas = {{name=childID,value=uid},{name=classID,value=className}} props.initialProperties.quickAppVariables = qas props.initialInterfaces = interfaces return createChild(self,props,_G[className]) end local function getVar(child,varName) for _,v in ipairs(child.properties.quickAppVariables or {}) do if v.name==varName then return v.value end end return "" end function QuickApp:loadExistingChildren(chs) __assert_type(chs,'table') defChildren = chs self.children = children function self.initChildDevices() end local cdevs,n = api.get("/devices?parentId="..self.id) or {},0 -- Pick up all my children for _,child in ipairs(cdevs) do local uid = getVar(child,childID) local className = getVar(child,classID) local childObject = _G[className] and _G[className](child) or QuickAppChild(child) self.childDevices[child.id]=childObject childObject.parent = self end end function QuickApp:createMissingChildren() for uid,data in pairs(defChildren) do if not self.children[uid] then local props = { name = data.name, type = data.type, } self:createChildDevice(uid,props,data.interfaces,data.className) end end end function QuickApp:removeUndefinedChildren() for _,deviceId in ipairs(undefinedChildren) do -- Remove children not in children table self:removeChildDevice(deviceId) end end end do local childID = 'ChildID' local classID = 'ClassName' local defChildren children = {} local undefinedChildren = {} local createChild = QuickApp.createChildDevice class 'QwikAppChild'(QuickAppChild) function QwikAppChild:__init(device) QuickAppChild.__init(self, device) local uid = self:getVariable(childID) or "" if defChildren[uid] then children[uid]=self -- Keep table with all children indexed by uid. uid is unique. else -- If uid not in our children table, we will remove this child undefinedChildren[#undefinedChildren+1]=self.id end end function QuickApp:createChildDevice(uid,props,interfaces,className) __assert_type(uid,'string') __assert_type(className,'string') props.initialProperties = props.initialProperties or {} local qas = {{name=childID,value=uid},{name=clsID,value=className}} props.initialProperties.quickAppVariables = qas props.initialInterfaces = interfaces return createChild(self,props,_G[className]) end local function getVar(child,varName) for _,v in ipairs(child.properties.quickAppVariables or {}) do if v.name==varName then return v.value end end return "" end function QuickApp:loadExistingChildren(chs) __assert_type(chs,'table') defChildren = chs self.children = children function self.initChildDevices() end local cdevs,n = api.get("/devices?parentId="..self.id) or {},0 -- Pick up all my children for _,child in ipairs(cdevs) do local uid = getVar(child,childID) local className = getVar(child,classID) local childObject = _G[className] and _G[className](child) or QuickAppChild(child) self.childDevices[child.id]=childObject childObject.parent = self end end function QuickApp:createMissingChildren() for uid,data in pairs(defChildren) do if not self.children[uid] then local props = { name = data.name, type = data.type, } self:createChildDevice(uid,props,data.interfaces,data.className) end end end function QuickApp:removeUndefinedChildren() for _,deviceId in ipairs(undefinedChildren) do -- Remove children not in children table self:removeChildDevice(deviceId) end end end then we can use it like this ------------------------------- -- 1 - Definition of class ------------------------------- class 'Class_Temp'(QwikAppChild) -- Class NOM_Temps pour "com.fibaro.temperatureSensor" ------------------------------- -- 2 - Class constructor ------------------------------- function Class_Temp:__init(device) QwikAppChild.__init(self, device) end -------------------------------- -- 3 - Definition of children -------------------------------- local myChildren = { -- Unique ID (uid) -> child initialization data, in our case the name ["Child_Temps1"] = { name="Température1", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps2"] = { name="Température2", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps3"] = { name="Température3", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps4"] = { name="Température4", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps5"] = { name="Température5", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, ["Child_Temps6"] = { name="Température6", type="com.fibaro.temperatureSensor", className='Class_Temp', interfaces = {'battery'}, }, } -------------------------------- -- 4 - Initialization of children -------------------------------- function QuickApp:onInit() self:loadExistingChildren(myChildren) self:createMissingChildren() self:removeUndefinedChildren() self:update_child("Child_Temps5") -- example, update child with uid 'Child_Temps5' -- for uid,_ in pairs(self.children) do -- update all children -- self:update_child(uid) -- end end -------------------------------- -- 5 - Accessing children -------------------------------- function QuickApp:update_child(uid) local default_temp = 37 --- pour l'ex du tuto local default_log = " I'm bad " --- pour l'ex du tuto self.children[uid]:updateProperty("value", default_temp) self.children[uid]:updateProperty("log", default_log) end
-
...but you needed to reboot your HC3
-
I think this became a good example, I will repost the code in the (main) Fibaro forum with credits to you. https://forum.fibaro.com/topic/49113-hc3-quickapps-coding-tips-and-tricks/?do=findComment&comment=260188
-
This version will remove children that are not in the children table. It can be useful if you change the number of children (reduce them), or the code creates children infinitely like the last version... ;-) local childrenToDelete,children = {} local childID = 'Nappe_Child_ID' ------------------------------- -- 1 - Création d'un Child ------------------------------- -- Child Température : function QuickApp:createChildTmps(ID,Nom) local child = self:createChildDevice({ name = Nom, type = "com.fibaro.temperatureSensor", initialProperties = {quickAppVariables = {{name=childID,value=ID}}}, }, NOM_Temps) end ------------------------------- -- 2 - Définition des classes ------------------------------- class 'NOM_Temps'(QuickAppChild) -- Class NOM_Temps pour "com.fibaro.temperatureSensor" ------------------------------- -- 3 - Constructeur ------------------------------- -- Constructeur __init pour la classe NOM_Temps function NOM_Temps:__init(device) QuickAppChild.__init(self, device) local uid = self:getVariable(childID) or "" if children[uid] then children[uid]=self -- Keep table with all children indexed by name. Assumes name unique. else childrenToDelete[#childrenToDelete+1]=self.id -- child to remove end end -------------------------------- -- 4 - Initialisation des Childs -------------------------------- children = { -- Unique ID -> Name ["Child_Temps1"] = "Température1", ["Child_Temps2"] = "Température2", ["Child_Temps3"] = "Température3", ["Child_Temps4"] = "Température4", ["Child_Temps5"] = "Température5", ["Child_Temps6"] = "Température6", } function QuickApp:onInit() self:initChildDevices({ ["com.fibaro.temperatureSensor"] = NOM_Temps -- Température }) for uid,Nom in pairs(children) do if type(Nom)=='string' then -- Uninitialized child self:createChildTmps(uid,Nom) -- ...create child end end for _,deviceId in ipairs(childrenToDelete) do self:removeChildDevice(deviceId) end self:Mise_a_jour_des_Childs("Child_Temps5") end function QuickApp:Mise_a_jour_des_Childs(Nom) local variable_qui_donne_la_temperature = 37 --- pour l'ex du tuto local variable_pour_le_log = " I'm bad " --- pour l'ex du tuto children[Nom]:updateProperty("value", variable_qui_donne_la_temperature) children[Nom]:updateProperty("log", variable_pour_le_log) end
-
So, there was another bug in creating the childDevice. The initialProperties should be quickAppVariables = ... If you copy the last post in full it should work.
-
You could also add code to automatically delete children that you don't use/need (e.g. children not in the children table)
-
I made a change in the original code if type ( Name )== 'string' instead of the wrong code type(children[Name])=='string' Did you change that? Otherwise you will create the children every time you restart.
-
No problem, just fixed it myself.
-
The problem with using the name as the unique key is that you may want the children to have the same name - or the user can change the name in the Web UI of your child... So, instead you can store the unique id in a quickAppVariable, similar to in your own example, and then create a table mapping these unique ids to the child objects. It becomes a little bit more complex. local children local childID = 'Nappe_Child_ID' ------------------------------- -- 1 - Création d'un Child ------------------------------- -- Child Température : function QuickApp:createChildTmps(ID,Nom) local child = self:createChildDevice({ name = Nom, type = "com.fibaro.temperatureSensor", initialProperties = { quickAppVariables = {{name=childID,value=ID}}}, }, NOM_Temps) end ------------------------------- -- 2 - Définition des classes ------------------------------- class 'NOM_Temps'(QuickAppChild) -- Class NOM_Temps pour "com.fibaro.temperatureSensor" ------------------------------- -- 3 - Constructeur ------------------------------- -- Constructeur __init pour la classe NOM_Temps function NOM_Temps:__init(device) QuickAppChild.__init(self, device) children[self:getVariable(childID)]=self -- Keep table with all children indexed by name. Assumes name unique. end -------------------------------- -- 4 - Initialisation des Childs -------------------------------- children = { -- Unique ID -> Name ["Child_Temps1"] = "Température1", ["Child_Temps2"] = "Température2", ["Child_Temps3"] = "Température3", ["Child_Temps4"] = "Température4", ["Child_Temps5"] = "Température5", ["Child_Temps6"] = "Température6", } function QuickApp:onInit() self:initChildDevices({ ["com.fibaro.temperatureSensor"] = NOM_Temps -- Température }) for uid,Nom in pairs(children) do if type(Nom)=='string' then -- Uninitialized child self:createChildTmps(uid,Nom) -- ...create child end end self:Mise_a_jour_des_Childs("Child_Temps5") end function QuickApp:Mise_a_jour_des_Childs(Nom) local variable_qui_donne_la_temperature = 37 --- pour l'ex du tuto local variable_pour_le_log = " I'm bad " --- pour l'ex du tuto children[Nom]:updateProperty("value", variable_qui_donne_la_temperature) children[Nom]:updateProperty("log", variable_pour_le_log) end .
-
It should not work. children={} is a table you define where you keep a map <name> -> <child>. The "builtin" table, self.childDevices keep a map <deviceID> -> <child>, which is not as useful when working with the children. However, deviceID is always unique so that is the reason why they have that mapping. If we know that the names are unique it is more helpful to have a name to child mapping, like in the example. Otherwise we can also give our children a unique id that we store in a quickAppVariable, like in your example, and index on that.
-
If you have 6 predefined children with unique names local children ------------------------------- -- 1 - Création d'un Child ------------------------------- -- Child Température : function QuickApp:createChildTmps(Nom) local child = self:createChildDevice({name = Nom, type = "com.fibaro.temperatureSensor",}, NOM_Temps) end ------------------------------- -- 2 - Définition des classes ------------------------------- class 'NOM_Temps'(QuickAppChild) -- Class NOM_Temps pour "com.fibaro.temperatureSensor" ------------------------------- -- 3 - Constructeur ------------------------------- -- Constructeur __init pour la classe NOM_Temps function NOM_Temps:__init(device) QuickAppChild.__init(self, device) children[self.name]=self -- Keep table with all children indexed by name. Assumes name unique. end -------------------------------- -- 4 - Initialisation des Childs -------------------------------- children = { ["Température1"] = false, ["Température2"] = false, ["Température3"] = false, ["Température4"] = false, ["Température5"] = false, ["Température6"] = false, } function QuickApp:onInit() self:initChildDevices({ ["com.fibaro.temperatureSensor"] = NOM_Temps -- Température }) for Nom,c in pairs(children) do if c==false then self:createChildTmps(Nom) end end self:Mise_a_jour_des_Childs("Température5") end function QuickApp:Mise_a_jour_des_Childs(Nom) local variable_qui_donne_la_temperature = 37 --- pour l'ex du tuto local variable_pour_le_log = " I'm bad " --- pour l'ex du tuto children[Nom]:updateProperty("value", variable_qui_donne_la_temperature) children[Nom]:updateProperty("log", variable_pour_le_log) end
-
Sorry, local children = {} in the beginning of the code didn't come along when I copied the code. I fixed it in the previous post.
-
Could also simplify like this. This assumes that child name is unique. You can index on some quickAppVariable too. local children = {} ------------------------------- -- 1 - Création d'un Child ------------------------------- -- Child Température : function QuickApp:createChildTmps(Nom) local child = self:createChildDevice({name = Nom, type = "com.fibaro.temperatureSensor",}, NOM_Temps) end ------------------------------- -- 2 - Définition des classes ------------------------------- class 'NOM_Temps'(QuickAppChild) -- Class NOM_Temps pour "com.fibaro.temperatureSensor" ------------------------------- -- 3 - Constructeur ------------------------------- -- Constructeur __init pour la classe NOM_Temps function NOM_Temps:__init(device) QuickAppChild.__init(self, device) children[self.name]=self -- Keep table with all children indexed by name. Assumes name unique. end -------------------------------- -- 4 - Initialisation des Childs -------------------------------- local Nom = "Température" function QuickApp:onInit() self:initChildDevices({ ["com.fibaro.temperatureSensor"] = NOM_Temps -- Température }) if not children[Nom] then self:createChildTmps(Nom) end self:Mise_a_jour_des_Childs() end function QuickApp:Mise_a_jour_des_Childs() local variable_qui_donne_la_temperature = 37 --- pour l'ex du tuto local variable_pour_le_log = " I'm bad " --- pour l'ex du tuto children[Nom]:updateProperty("value", variable_qui_donne_la_temperature) children[Nom]:updateProperty("log", variable_pour_le_log) end
-
api.get("/alarms/v1/partitions/"..partitionId).devices
-
Not sure this helps, but.... local myTable = {} myTable.x = 5 function myTable:test1(x) print(self.x+x) end Defining a function with ':' is the same as defining function myTable.test1(self,x) print(self.x+x) end It inserts a variable 'self' as the first argument (Lua choses the name 'self') The above function definition is the same as myTable.test1 = function(self,x) print(self.x+x) end So the resulting myTable is now { x = 5, test1 = function(self,v) print(self.x+x) end } If we call myTable:test1(5) it is transformed to the call myTable.test1(myTable,5), taking the table on the left of ':' and passing it on as the first argument 'self' to the test1 function myTable.test1(myTable,5) and we get >10 If we define our function with '.' we can call 'self' something else... function myTable.test2(y,x) print(y.x*x) end myTable:test2(5) >25 So, 'self' is just a Lua table (object) that is sent around as the first argument to all methods, and representing the object the methods belongs to. In the common case it's the QuickApp object, but for QuickAppChild classes, it's the child object. We can define our QuickApp functions with '.' instead of ':' but we need to add the first parameter, the 'self' We can also call our QuickApp functions with '.' instead of ':' but we need to add the first argument, the 'self', explicitly. In the below case we call it 'myApp' instead of 'self' function QuickApp.test3(myApp,x) myApp.debug(myApp,myApp.x+x) end function QuickApp.onInit(myApp) myApp.x = 9 QuickApp.test3(myApp,8) end
-
'self' is a variable passed on to all method calls. Ex. function QuickApp:test(x) print(self.name) end is the same as function QuickApp.test(self,x) print(self.name) end Lua will pass the same 'self' object every time a QuickApp:fun is called 'self' is a Lua table and you can add your own values to self self.xxx = "variable self" and later access it when a QuickApp:fun is called function QuickApp:test2(x) print(self.xxx) end A global Lua variable is accessible from all functions xxx = "Lua global" function QuickApp:test3() print(xxx) end function test3() print(xxx) end 'self' can be a convenient place to store values as not to pollute the global Lua name space, and you can have values shared privately between QuickApp:funs. What is faster? Well they are both a table access (table 'self' and table '_G') so without testing I expect them to be similar in efficiency. Note, if you create QuickAppChild objects in your QA they will have their own individual 'self' variables.
-
Yes, A json value can contain null values. If we replace null with nil in a Lua table the key/value is removed from the table. A proper json decoder for Lua would like to preserve the null values as it can be significant (key exist with null value, or key does not exist at all) The json decoder choose json.null to be a function value is that they wanted a value that is unique and quick to compare. In a QA, by providing the {others = {null=false}} option to json.decode it will replace null with Lua nil and the key removed. It doesn't work in Scenes as they use a different json decoder/encoder that doesn't take options.
-
cookie = [[JSESSIONID=723BE79E2C3D6EB5DD2072CAE855A73C; Path=/; Secure; HttpOnly, TS01b0e19c=01e5b3f1f84aa60001cd253c6f621db2b9d7722f8d2ab2c51a7723da6c8d46b152c406e57daf3b78bcb3c71f629062e1c84432b5f8; Path=/; Secure; HTTPOnly]] local cookie1,cookie2 = cookie:match("(.-);.-HttpOnly, (.-);") print(cookie1) print(cookie2) [11.12.2022] [10:18:31] [DEBUG] [QUICKAPP1001]: JSESSIONID=723BE79E2C3D6EB5DD2072CAE855A73C [11.12.2022] [10:18:31] [DEBUG] [QUICKAPP1001]: TS01b0e19c=01e5b3f1f84aa60001cd253c6f621db2b9d7722f8d2ab2c51a7723da6c8d46b152c406e57daf3b78bcb3c71f629062e1c84432b5f8
-
You see in the output above that uid versions uid#5 and uid#7 both has key 'TemperatureState' and then the question is which should be choosen? Now we can get both with keys["5#uid"] and keys["7#uid"]
-
How about this? local function find(uid,expr) local res,device = {} local function find_aux(expr) if type(expr) == 'table' then if expr[1] then -- array for _,e in ipairs(expr) do find_aux(e) end else -- key/value if expr.deviceURL then device = expr.deviceURL:match(uid) if device then device = device.."#" end end if device and expr.name and (expr.name:sub(1,3)=='io:' or expr.name:sub(1,5)=='core:') and expr.value then local key = device..expr.name if res[key] and res[key]~=expr.value then error("Duplicate key:"..key) end res[key]=expr.value else for k,v in pairs(expr) do find_aux(v) end end end end end uid = uid:gsub("%-","%%-").."#(%d+)$" find_aux(expr) return res end local uid = "io://0810-4343-0200/13610533" keys = find(uid,jsonResponse.devices) for k,v in pairs(keys) do print(k,"=",json.encode(v):sub(1,80)) end and output [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 3#core:LuminanceState = 4 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:RSSILevelState = 36 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:DryingDurationMaxState = 120 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:BoostDurationMaxState = 60 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:FilterFanCloggingErrorState = 12 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:PriorityLockTimerState = 0 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:SetpointLoweringTemperatureInProgModeState = 2.5 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 6#core:PowerSourceType = "mainSupply" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:BoostModeDurationState = 0 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:IdentifierState = "00000000" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 7#core:TemperatureState = 20.5 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:DiscreteRSSILevelState = "low" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 3#core:MeasuredValueType = "core:LuminanceInLux" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 5#core:TemperatureState = 23.5 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:TargetTemperatureState = 17 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 7#core:MeasuredValueType = "core:TemperatureInCelcius" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:MaximumHeatingLevelState = "unknown" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 5#core:MeasuredValueType = "core:TemperatureInCelcius" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 4#core:MeasuredValueType = "core:RelativeValueInPercentage" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:DateTimeState = {"month":12,"weekday":3,"day":1,"second":50,"year":2022,"minute":48,"hour":11} [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:DerogatedTargetTemperatureState = 0 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:ComfortRoomTemperatureState = 17 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:TimeProgramState = [{"monday":[{"start":"04:45","end":"05:45"},{"start":"00:00","end":"00:00"},{"st [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:CumulatedLoweringState = 18 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 3#core:PowerSourceType = "mainSupply" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:CurrentWorkingRateState = 0 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:TimerForTransitoryStateState = 0 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:LocalLeadTimeState = 3268 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:OperatingModeState = "external" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:VersionState = "2d202020ffffff210002" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:OnOffState = "on" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:NameState = "I2G_Actuator" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:RegulationModeState = "none" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 7#core:PowerSourceType = "mainSupply" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:ModelState = "Symphonik Gauche" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 6#core:StatusState = "available" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:TemperatureProbeCalibrationOffsetState = 0 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 4#core:StatusState = "available" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 2#core:OccupancyState = "noPersonInside" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 2#core:StatusState = "available" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:StatusState = "available" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 4#core:RelativeHumidityState = 44 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:EffectiveTemperatureSetpointState = 17 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:PowerState = 1750 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:TowelDryerTemporaryStateState = "permanentHeating" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 7#core:Manufacturer = "Atlantic Group" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 7#core:StatusState = "available" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 6#core:MeasuredValueType = "core:ElectricalEnergyInWh" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 2#core:PowerSourceType = "mainSupply" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 3#core:Manufacturer = "Atlantic Group" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 4#core:Manufacturer = "Atlantic Group" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 5#core:Manufacturer = "Atlantic Group" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 6#core:Manufacturer = "Atlantic Group" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:ControllerAddressState = 13610532 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 6#core:ElectricEnergyConsumptionState = 1011000 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 5#core:PowerSourceType = "mainSupply" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 3#core:StatusState = "available" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 5#core:FirmwareRevision = "2d202020ffffff210002" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 4#core:FirmwareRevision = "2d202020ffffff210002" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 5#core:StatusState = "available" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:EcoRoomTemperatureState = 2.5 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:TensionState = 235 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:DryingDurationState = 0 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:DryingDurationUserParameterState = 60 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:BoostDurationUserParameterState = 30 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 4#core:PowerSourceType = "mainSupply" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:OccupancyState = 0 [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:ManufacturerNameState = "Thermor" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:TargetHeatingLevelState = "comfort" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 3#core:FirmwareRevision = "2d202020ffffff210002" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 2#core:FirmwareRevision = "2d202020ffffff210002" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:Manufacturer = "Atlantic Group" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 2#core:Manufacturer = "Atlantic Group" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 7#core:FirmwareRevision = "2d202020ffffff210002" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 6#core:FirmwareRevision = "2d202020ffffff210002" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#core:FirmwareRevision = "2d202020ffffff210002" [03.12.2022] [16:29:00] [DEBUG] [QUICKAPP1001]: 1#io:AutoProgramState = {"saturday":["CONF_3_NIV1","CONF_3_NIV1","CONF_3_NIV1","CONF_3_NIV1","CONF_3_NIV It only collects keys with the uid and prefixes the keys with the number after # Then you can do print(keys['1#core:ComfortRoomTemperatureState']) The problem with the previous statement ssConsi = (find('name','core:ComfortRoomTemperatureState',find('deviceURL','io://0810%-4343%-0200/13610533..',jsonResponse.devices).states).value) -- #1 OK is that if <uid>#1 and <uid>#2 both have the key 'core:ComfortRoomTemperatureState' we just get the first random - but we should return both. With the new find taking the uid you can ask for the specfic uid number in the result Ex. '1#core:ComfortRoomTemperatureState' of uid "io://0810-4343-0200/13610533" Will that work?
-
or if you want to see all keys keys = find(jsonResponse.devices) for k,v in pairs(keys) do print(k,"=",json.encode(v)) end output [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:TimeProgramState = [{"monday":[{"end":"19:30","start":"18:15"},{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"}]},{"tuesday":[{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"}]},{"wednesday":[{"end":"19:30","start":"18:15"},{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"}]},{"thursday":[{"end":"19:30","start":"18:15"},{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"}]},{"friday":[{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"}]},{"saturday":[{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"}]},{"sunday":[{"end":"19:30","start":"18:00"},{"end":"00:00","start":"00:00"},{"end":"00:00","start":"00:00"}]}] [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:LocalLeadTimeState = 3154 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:FirmwareRevision = "2d202020ffffff210002" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:VersionState = "2d202020ffffff210002" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:ComfortRoomTemperatureState = 19 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:LocalIPv4AddressState = "192.168.1.15" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:RegulationModeState = "none" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:DryingDurationState = 0 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:RSSILevelState = 76 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:TensionState = 235 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:MaximumHeatingLevelState = "unknown" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:RelativeHumidityState = 49 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:AutoProgramState = {"thursday":["CONF_3_NIV1",....} [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:ElectricEnergyConsumptionState = 1748000 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:StatusState = "available" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:TemperatureState = 20.5 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:InternalExternalSchedulingTypeState = "internal" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:NameState = "I2G_Actuator" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:OperatingModeState = "external" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:BoostDurationUserParameterState = 60 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:CountryCodeState = "FR" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:ManufacturerNameState = "Thermor" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:MeasuredValueType = "core:TemperatureInCelcius" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:PowerSourceType = "mainSupply" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:FilterFanCloggingErrorState = 0 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:DerogatedTargetTemperatureState = 0 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:EffectiveTemperatureSetpointState = 14 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:BoostModeDurationState = 0 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:OccupancyState = "noPersonInside" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:OnOffState = "on" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:EcoRoomTemperatureState = 5 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:CurrentWorkingRateState = 0 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:TowelDryerTemporaryStateState = "permanentHeating" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:ModelState = "Symphonik Gauche" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:DryingDurationMaxState = 120 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:DryingDurationUserParameterState = 90 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:BoostDurationMaxState = 60 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:TargetTemperatureState = 19 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:TargetHeatingLevelState = "eco" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:LuminanceState = 21 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:TimerForTransitoryStateState = 0 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:ControllerAddressState = 15984323 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:IdentifierState = "00000000" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:CumulatedLoweringState = 19 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:DiscreteRSSILevelState = "normal" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:PriorityLockTimerState = 0 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:TemperatureProbeCalibrationOffsetState = 0 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:Manufacturer = "Atlantic Group" [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:PowerState = 1750 [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: core:DateTimeState = {"weekday":3,"hour":11,"second":48,"minute":48,"month":12,"year":2022,"day":1} [03.12.2022] [10:30:53] [DEBUG] [QUICKAPP1001]: io:SetpointLoweringTemperatureInProgModeState = 5
-
Maybe just collect all the keys starting with "io:" and "core:" ? local function find(expr) local res = {} local function find_aux(expr) if type(expr) == 'table' then if expr[1] then -- array for _,e in ipairs(expr) do find_aux(e) end else -- key/value if expr.name and (expr.name:sub(1,3)=='io:' or expr.name:sub(1,5)=='core:') and expr.value then res[expr.name]=expr.value else for k,v in pairs(expr) do find_aux(v) end end end end end find_aux(expr) return res end keys = find(jsonResponse.devices) print('io:TargetHeatingLevelState=',keys['io:TargetHeatingLevelState']) print('core:RSSILevelState=',keys['core:RSSILevelState']) print('core:LuminanceState=',keys['core:LuminanceState']) print('core:RelativeHumidityState=',keys['core:RelativeHumidityState']) print('core:TemperatureState=',keys['core:TemperatureState']) print('core:ElectricEnergyConsumptionState=',keys['core:ElectricEnergyConsumptionState']) Output [02.12.2022] [23:33:07] [DEBUG] [QUICKAPP1001]: io:TargetHeatingLevelState= eco [02.12.2022] [23:33:07] [DEBUG] [QUICKAPP1001]: core:RSSILevelState= 76.0 [02.12.2022] [23:33:07] [DEBUG] [QUICKAPP1001]: core:LuminanceState= 21 [02.12.2022] [23:33:07] [DEBUG] [QUICKAPP1001]: core:RelativeHumidityState= 49.0 [02.12.2022] [23:33:07] [DEBUG] [QUICKAPP1001]: core:TemperatureState= 20.5 [02.12.2022] [23:33:07] [DEBUG] [QUICKAPP1001]: core:ElectricEnergyConsumptionState= 1748000
-
local function find(key,val,list) for _,e in ipairs(list) do if tostring(e[key]):match( then return e end end end print(find('name','io:TargetHeatingLevelState',find('deviceURL','io://0810%-4343%-0200/13610533..',jsonResponse.devices).states).value) You need to quote '-' in the val string ex. '%-' Also, you match any character is with '.' dot, so '..' will match "#1" Is this what you need?
-
local function find(key,val,list) for _,e in ipairs(list) do if e[key]==val then return e end end end print(find('name','io:TargetHeatingLevelState',find('deviceURL','io://0810-4343-0200/13610533#1',jsonResponse.devices).states).value)