Tasmota/lib/libesp32/berry_matter/src/embedded/Matter_0_Inspect.be
2025-03-16 22:38:36 +01:00

179 lines
4.8 KiB
Plaintext

#
# Matter_inspect.be - implements a generic function to inspect an instance (for debugging only)
#
# Copyright (C) 2023 Stephan Hadinger & Theo Arends
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import matter
#@ solidify:matter.sort,weak
def sort(l)
# insertion sort
for i:1..size(l)-1
var k = l[i]
var j = i
while (j > 0) && (l[j-1] > k)
l[j] = l[j-1]
j -= 1
end
l[j] = k
end
return l
end
matter.sort = sort
#@ solidify:matter.jitter,weak
#############################################################
# jitter
#
# compute a random jitter time for an update_time value
def jitter(update_time)
# initialization to a random value within range
import crypto
var rand31 = crypto.random(4).get(0,4) & 0x7FFFFFFF # random int over 31 bits
return tasmota.millis(rand31 % update_time)
end
matter.jitter = jitter
#@ solidify:matter.inspect,weak
# debug function
def inspect(p)
try
import introspect
var keys = []
var o = p
while (o != nil)
for k : introspect.members(o)
var v = introspect.get(o, k)
if (type(v) != 'function') && (keys.find(k) == nil)
keys.push(k)
end
end
o = super(o) # move to superclass
end
keys = matter.sort(keys)
var r = []
for k : keys
var v = introspect.get(p, k)
# if type(v) == 'string' v = string.escape(v, true) end
r.push(format("'%s': %s", str(k), str(v)))
end
return "{" + r.concat(", ") + "}"
except .. as e, m
return "Exception:" + str(e) + "|" + str(m)
end
end
matter.inspect = inspect
#############################################################
# consolidate_clusters
#
# Build a consolidated map of all the `CLUSTERS` static vars
# from the inheritance hierarchy
#
# `cl` can be a the class to get the superclass, or a `map`
#@ solidify:matter.consolidate_clusters,weak
def consolidate_clusters(cl, m)
var cl_parent
if cl == nil
cl_parent = {}
elif type(cl) == 'class'
cl_parent = (super(cl) != nil) ? super(cl).CLUSTERS : {}
elif type(cl) == 'instance'
cl_parent = cl
end
var ret = {}
# clone cl_parent
for k: cl_parent.keys()
# print(f"{k=} {cl_parent[k]=}")
# rebuild an actual list
var attr_arr = []
var attr_bytes = cl_parent[k]
var attr_bytes_sz = (attr_bytes != nil) ? size(attr_bytes) / 2 : 0
var idx = 0
while (idx < attr_bytes_sz)
attr_arr.push(attr_bytes.get(idx * 2, -2))
idx += 1
end
ret[k] = attr_arr
# ret[k] = cl_parent[k].copy()
end
# add all keys from m
# print("--- step 2")
for k: m.keys()
# print(f"{k=} {ret.find(k)=} {m[k]=}")
if !ret.contains(k)
ret[k] = []
end
for v: m[k]
if ret[k].find(v) == nil
ret[k].push(v)
end
end
end
# add all auto-attribbutes to each cluster
var AUTO_ATTRIBUTES = [ # pre-defined auto attributes for every cluster
0xFFF8, # GeneratedCommandList - [] by default
0xFFF9, # AcceptedCommandList - list of defined commands TODO for auto-generated
0xFFFA, # EventList - [] by default
0xFFFB, # AttributeList - list generated from cluster definition
0xFFFC, # FeatureMap - 0 by default unless redefined
0xFFFD, # ClusterRevision - 1 by default unless redefined
]
for k: m.keys()
for at: AUTO_ATTRIBUTES
if ret[k].find(at) == nil
ret[k].push(at)
end
end
end
# sort all lists
for k: ret.keys()
var attr_list = ret[k]
# sort in place
ret[k] = matter.sort(attr_list)
end
# convert back to bytes
for k: ret.keys()
var attr_arr = ret[k]
var attr_bytes = bytes()
var idx = 0
while (idx < size(attr_arr))
attr_bytes.add(attr_arr[idx], -2)
idx += 1
end
ret[k] = attr_bytes
end
# print(ret)
return ret
end
matter.consolidate_clusters = consolidate_clusters
#############################################################
# consolidate_update_commands_list
#
# Build a consolidated list and remove duplicates
#@ solidify:matter.UC_LIST,weak
def UC_LIST(cl, *l)
var uc_parent = super(cl).UPDATE_COMMANDS
return uc_parent + l
end
matter.UC_LIST = UC_LIST