Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matter latency improvement for single attribute reads and single commands #19158

Merged
merged 1 commit into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ All notable changes to this project will be documented in this file.
- Configuration backup and restore now backup and restore ``.xdrvsetXXX`` files too (#18295)
- Berry extend `range(lower, upper, incr)` to arbitrary increment
- Berry updated syntax highlighting plugin for VSCode
- Matter latency improvement for single attribute reads and single commands

### Fixed

Expand Down
2 changes: 2 additions & 0 deletions lib/libesp32/berry_matter/src/be_matter_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,13 +338,15 @@ module matter (scope: global, strings: weak) {
StatusIB, class(be_class_Matter_StatusIB)
StatusResponseMessage, class(be_class_Matter_StatusResponseMessage)
ReadRequestMessage, class(be_class_Matter_ReadRequestMessage)
ReadRequestMessage_solo, class(be_class_Matter_ReadRequestMessage_solo)
ReportDataMessage, class(be_class_Matter_ReportDataMessage)
SubscribeRequestMessage, class(be_class_Matter_SubscribeRequestMessage)
SubscribeResponseMessage, class(be_class_Matter_SubscribeResponseMessage)
WriteRequestMessage, class(be_class_Matter_WriteRequestMessage)
WriteResponseMessage, class(be_class_Matter_WriteResponseMessage)
TimedRequestMessage, class(be_class_Matter_TimedRequestMessage)
InvokeRequestMessage, class(be_class_Matter_InvokeRequestMessage)
InvokeRequestMessage_solo, class(be_class_Matter_InvokeRequestMessage_solo)
InvokeResponseMessage, class(be_class_Matter_InvokeResponseMessage)

// Matter Commisioning messages
Expand Down
10 changes: 5 additions & 5 deletions lib/libesp32/berry_matter/src/embedded/Matter_Commissioning.be
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ class Matter_Commisioning_Context
var raw = resp.encode_frame(pake2_raw)

# log the fact that a new commissioning is starting
tasmota.log(format("MTR: New Commissioning (PASE id=%i) from [%s]:%i", session.__future_local_session_id, session._ip, session._port))
tasmota.log(format("MTR: New Commissioning (PASE id=%i) from [%s]:%i", session.__future_local_session_id, session._ip, session._port), 2)

self.responder.send_response_frame(resp)
return true
Expand Down Expand Up @@ -265,7 +265,7 @@ class Matter_Commisioning_Context
end

# send PakeFinished and compute session key
var created = tasmota.rtc()['utc']
var created = tasmota.rtc_utc()
var session_keys = crypto.HKDF_SHA256().derive(session.__spake_Ke, bytes(), bytes().fromstring(self.SEKeys_Info), 48)
var I2RKey = session_keys[0..15]
var R2IKey = session_keys[16..31]
Expand Down Expand Up @@ -406,7 +406,7 @@ class Matter_Commisioning_Context
var i2r = session_keys[0..15]
var r2i = session_keys[16..31]
var ac = session_keys[32..47]
var created = tasmota.rtc()['utc']
var created = tasmota.rtc_utc()

# tasmota.log("MTR: ******************************", 4)
# tasmota.log("MTR: I2RKey =" + i2r.tohex(), 4)
Expand Down Expand Up @@ -538,7 +538,7 @@ class Matter_Commisioning_Context
var raw = resp.encode_frame(sigma2_raw)

# log the fact that a new connection is starting
tasmota.log(format("MTR: New Connection (CASE id=%i) from [%s]:%i", session.__future_local_session_id, session._ip, session._port))
tasmota.log(format("MTR: New Connection (CASE id=%i) from [%s]:%i", session.__future_local_session_id, session._ip, session._port), 2)

self.responder.send_response_frame(resp)
return true
Expand Down Expand Up @@ -658,7 +658,7 @@ class Matter_Commisioning_Context
var i2r = session_keys[0..15]
var r2i = session_keys[16..31]
var ac = session_keys[32..47]
var created = tasmota.rtc()['utc']
var created = tasmota.rtc_utc()

# tasmota.log("MTR: ******************************", 4)
# tasmota.log("MTR: I2RKey =" + i2r.tohex(), 4)
Expand Down
53 changes: 44 additions & 9 deletions lib/libesp32/berry_matter/src/embedded/Matter_Device.be
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class Matter_Device
return
end # abort if SetOption 151 is not set

self.profiler = matter.Profiler()
matter.profiler = matter.Profiler()
self.started = false
self.tick = 0
self.plugins = []
Expand Down Expand Up @@ -514,18 +514,15 @@ class Matter_Device
end

var endpoint = ctx.endpoint
# var endpoint_mono = [ endpoint ]
var endpoint_found = false # did any endpoint match
var cluster = ctx.cluster
# var cluster_mono = [ cluster ]
var cluster_found = false
var attribute = ctx.attribute
# var attribute_mono = [ attribute ]
var endpoint_found = false # did any endpoint match
var cluster_found = false
var attribute_found = false

var direct = (ctx.endpoint != nil) && (ctx.cluster != nil) && (ctx.attribute != nil) # true if the target is a precise attribute, false if it results from an expansion and error are ignored

# tasmota.log(format("MTR: process_attribute_expansion %s", str(ctx)), 4)
# tasmota.log(f"MTR: process_attribute_expansion {str(ctx))}", 4)

# build the list of candidates

Expand All @@ -541,7 +538,7 @@ class Matter_Device
endpoint_found = true

# now explore the cluster list for 'ep'
var cluster_list = pi.get_cluster_list(ep) # cluster_list is the actual list of candidate cluster for this pluging and endpoint
var cluster_list = pi.get_cluster_list() # cluster_list is the actual list of candidate cluster for this pluging and endpoint
# tasmota.log(format("MTR: pi=%s ep=%s cl_list=%s", str(pi), str(ep), str(cluster_list)), 4)
for cl: cluster_list
if cluster != nil && cl != cluster continue end # skip if specific cluster and no match
Expand All @@ -550,7 +547,7 @@ class Matter_Device
cluster_found = true

# now filter on attributes
var attr_list = pi.get_attribute_list(ep, cl)
var attr_list = pi.get_attribute_list(cl)
# tasmota.log(format("MTR: pi=%s ep=%s cl=%s at_list=%s", str(pi), str(ep), str(cl), str(attr_list)), 4)
for at: attr_list
if attribute != nil && at != attribute continue end # skip if specific attribute and no match
Expand Down Expand Up @@ -595,6 +592,44 @@ class Matter_Device
end
end

#############################################################
# Optimized version for a single endpoint/cluster/attribute
#
# Retrieve the plugin for a read
def process_attribute_read_solo(ctx)
var endpoint = ctx.endpoint
# var endpoint_found = false # did any endpoint match
var cluster = ctx.cluster
# var cluster_found = false
var attribute = ctx.attribute
# var attribute_found = false

# all 3 elements must be non-nil
if endpoint == nil || cluster == nil || attribute == nil return nil end

# look for plugin
var pi = self.find_plugin_by_endpoint(endpoint)
if pi == nil # endpoint not found
ctx.status = matter.UNSUPPORTED_ENDPOINT
return nil
end

# check cluster
if !pi.contains_cluster(cluster)
ctx.status = matter.UNSUPPORTED_CLUSTER
return nil
end

# attribute list
if !pi.contains_attribute(cluster, attribute)
ctx.status = matter.UNSUPPORTED_ATTRIBUTE
return nil
end

# all good
return pi
end

#############################################################
# Return the list of endpoints from all plugins (distinct), exclud endpoint zero if `exclude_zero` is `true`
def get_active_endpoints(exclude_zero)
Expand Down
4 changes: 2 additions & 2 deletions lib/libesp32/berry_matter/src/embedded/Matter_Expirable.be
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ class Matter_Expirable
# set relative time in the future for expiration (in seconds)
def set_expire_in_seconds(s, now)
if s == nil return end
if now == nil now = tasmota.rtc()['utc'] end
if now == nil now = tasmota.rtc_utc() end
self.set_expire_time(now + s)
end

#############################################################
# set relative time in the future for expiration (in seconds)
# returns `true` if expiration date has been reached
def has_expired(now)
if now == nil now = tasmota.rtc()['utc'] end
if now == nil now = tasmota.rtc_utc() end
if self._expiration != nil
return now >= self._expiration
end
Expand Down
2 changes: 1 addition & 1 deletion lib/libesp32/berry_matter/src/embedded/Matter_Fabric.be
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class Matter_Fabric : Matter_Expirable
self._store = store
self._sessions = matter.Expirable_list()
self.fabric_label = ""
self.created = tasmota.rtc()['utc']
self.created = tasmota.rtc_utc()
# init group counters
self._counter_group_data_snd_impl = matter.Counter()
self._counter_group_ctrl_snd_impl = matter.Counter()
Expand Down
4 changes: 2 additions & 2 deletions lib/libesp32/berry_matter/src/embedded/Matter_HTTP_remote.be
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class Matter_HTTP_remote : Matter_HTTP_async
if alive
# device is known to be reachable
self.reachable = true
self.reachable_utc = tasmota.rtc()['utc']
self.reachable_utc = tasmota.rtc_utc()
else
self.reachable = false
end
Expand Down Expand Up @@ -344,7 +344,7 @@ class Matter_HTTP_remote : Matter_HTTP_async

var seconds = -1 # default if no known value
if self.reachable_utc != nil
seconds = tasmota.rtc()['utc'] - self.reachable_utc
seconds = tasmota.rtc_utc() - self.reachable_utc
end
return matter.seconds_to_dhm(seconds)
end
Expand Down
Loading