Skip to content

Commit

Permalink
Merge branch 'development' into prerelease-12.5
Browse files Browse the repository at this point in the history
  • Loading branch information
arendst committed Apr 17, 2023
2 parents ea592b9 + 8139c07 commit e9e3b03
Show file tree
Hide file tree
Showing 16 changed files with 3,617 additions and 3,312 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file.
- Support for GDK101 gamma radiation sensor by Petr Novacek (#18390)
- Matter support in now stabilized for Apple and Google (not tested with Alexa)
- Berry `instrospect.name()` to get names of functions, modules and classes (#18422)
- Berry add `searchall()` and `matchall()` to `re` module and pre-compiled patterns (#18429)
- Matter automatically exposes all detected Temperature sensors (#18430)

### Changed
- ESP32 LVGL library from v8.3.5 to v8.3.6 (no functional change)
Expand Down
2 changes: 2 additions & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- Berry support for Tensorflow Lite (TFL) by Christiaan Baars [#18119](https://github.com/arendst/Tasmota/issues/18119)
- Berry `webclient` features
- Berry `instrospect.name()` to get names of functions, modules and classes [#18422](https://github.com/arendst/Tasmota/issues/18422)
- Berry add `searchall()` and `matchall()` to `re` module and pre-compiled patterns [#18429](https://github.com/arendst/Tasmota/issues/18429)
- Matter support for Light and Relays by Stephan Hadinger [#18320](https://github.com/arendst/Tasmota/issues/18320)
- Matter automatically exposes all detected Temperature sensors [#18430](https://github.com/arendst/Tasmota/issues/18430)

### Breaking Changed
- Shelly Pro 4PM using standard MCP23xxx driver and needs one time Auto-Configuration
Expand Down
38 changes: 38 additions & 0 deletions lib/libesp32/berry/default/be_re_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,42 @@ int re_pattern_search(bvm *vm) {
be_raise(vm, "type_error", NULL);
}

// Berry: `re_pattern.searchall(s:string) -> list(list(string))`
int re_pattern_match_search_all(bvm *vm, bbool is_anchored) {
int32_t argc = be_top(vm); // Get the number of arguments
if (argc >= 2 && be_isstring(vm, 2)) {
const char * hay = be_tostring(vm, 2);
be_getmember(vm, 1, "_p");
ByteProg * code = (ByteProg*) be_tocomptr(vm, -1);
int limit = -1;
if (argc >= 3) {
limit = be_toint(vm, 3);
}

be_newobject(vm, "list");
for (int i = limit; i != 0 && hay != NULL; i--) {
hay = be_re_match_search_run(vm, code, hay, is_anchored);
if (hay != NULL) {
be_data_push(vm, -2); // add sub list to list
}
be_pop(vm, 1);
}
be_pop(vm, 1);
be_return(vm);
}
be_raise(vm, "type_error", NULL);
}

// Berry: `re_pattern.searchall(s:string) -> list(list(string))`
int re_pattern_search_all(bvm *vm) {
return re_pattern_match_search_all(vm, bfalse);
}

// Berry: `re_pattern.matchall(s:string) -> list(list(string))`
int re_pattern_match_all(bvm *vm) {
return re_pattern_match_search_all(vm, btrue);
}

// Berry: `re_pattern.match(s:string) -> list(string)`
int re_pattern_match(bvm *vm) {
int32_t argc = be_top(vm); // Get the number of arguments
Expand Down Expand Up @@ -277,7 +313,9 @@ module re (scope: global) {
class be_class_re_pattern (scope: global, name: re_pattern) {
_p, var
search, func(re_pattern_search)
searchall, func(re_pattern_search_all)
match, func(re_pattern_match)
matchall, func(re_pattern_match_all)
split, func(re_pattern_split)
}
@const_object_info_end */
24 changes: 12 additions & 12 deletions lib/libesp32/berry_matter/src/embedded/Matter_Commissioning.be
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ class Matter_Commisioning_Context
if msg.opcode != 0x20 || msg.local_session_id != 0 || msg.protocol_id != 0
tasmota.log("MTR: invalid PBKDFParamRequest message", 2)
tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
return false
end
var pbkdfparamreq = matter.PBKDFParamRequest().parse(msg.raw, msg.app_payload_idx)
Expand All @@ -126,7 +126,7 @@ class Matter_Commisioning_Context
if pbkdfparamreq.passcodeId != 0
tasmota.log("MTR: non-zero passcode id", 2)
tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
return false
end

Expand Down Expand Up @@ -164,7 +164,7 @@ class Matter_Commisioning_Context
if msg.opcode != 0x22 || msg.local_session_id != 0 || msg.protocol_id != 0
tasmota.log("MTR: invalid Pake1 message", 2)
tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
return false
end
var pake1 = matter.Pake1().parse(msg.raw, msg.app_payload_idx)
Expand Down Expand Up @@ -247,7 +247,7 @@ class Matter_Commisioning_Context
if msg.opcode != 0x24 || msg.local_session_id != 0 || msg.protocol_id != 0
tasmota.log("MTR: invalid Pake3 message", 2)
tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
return false
end
var pake3 = matter.Pake3().parse(msg.raw, msg.app_payload_idx)
Expand All @@ -259,7 +259,7 @@ class Matter_Commisioning_Context
if cA != session.__spake_cA
tasmota.log("MTR: invalid cA received", 2)
tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
return false
end

Expand All @@ -278,7 +278,7 @@ class Matter_Commisioning_Context
# tasmota.log("MTR: ******************************", 4)

# StatusReport(GeneralCode: SUCCESS, ProtocolId: SECURE_CHANNEL, ProtocolCode: SESSION_ESTABLISHMENT_SUCCESS)
var raw = self.send_status_report(msg, 0x00, 0x0000, 0x0000, false)
self.send_status_report(msg, 0x00, 0x0000, 0x0000, false)

self.add_session(session.__future_local_session_id, session.__future_initiator_session_id, I2RKey, R2IKey, AttestationChallenge, created)
return true
Expand Down Expand Up @@ -315,7 +315,7 @@ class Matter_Commisioning_Context
if msg.opcode != 0x30 || msg.local_session_id != 0 || msg.protocol_id != 0
# tasmota.log("MTR: invalid Sigma1 message", 2)
tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
return false
end
var sigma1 = matter.Sigma1().parse(msg.raw, msg.app_payload_idx)
Expand Down Expand Up @@ -445,7 +445,7 @@ class Matter_Commisioning_Context

if session == nil || session._fabric == nil
tasmota.log("MTR: StatusReport(GeneralCode: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: NO_SHARED_TRUST_ROOTS)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0001, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0001, false)
return false
end
session._source_node_id = msg.source_node_id
Expand Down Expand Up @@ -539,7 +539,7 @@ class Matter_Commisioning_Context
# sanity checks
if msg.opcode != 0x32 || msg.local_session_id != 0 || msg.protocol_id != 0
tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
return false
end
var session = msg.session
Expand Down Expand Up @@ -576,7 +576,7 @@ class Matter_Commisioning_Context
if TBETag3 != tag
tasmota.log("MTR: Tag don't match", 2)
tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
return false
end

Expand Down Expand Up @@ -618,7 +618,7 @@ class Matter_Commisioning_Context
tasmota.log("MTR: sigma3_tbs does not have a valid signature", 2)
tasmota.log("MTR: ******************* Invalid signature, trying anyways", 2)
# tasmota.log("MTR: StatusReport(General Code: FAILURE, ProtocolId: SECURE_CHANNEL, ProtocolCode: INVALID_PARAMETER)", 2)
# var raw = self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
# self.send_status_report(msg, 0x01, 0x0000, 0x0002, false)
# return false
else
# All good, compute new keys
Expand Down Expand Up @@ -654,7 +654,7 @@ class Matter_Commisioning_Context
tasmota.log("MTR: ******************************", 4)

# StatusReport(GeneralCode: SUCCESS, ProtocolId: SECURE_CHANNEL, ProtocolCode: SESSION_ESTABLISHMENT_SUCCESS)
var raw = self.send_status_report(msg, 0x00, 0x0000, 0x0000, true)
self.send_status_report(msg, 0x00, 0x0000, 0x0000, true)

session.close()
session.set_keys(i2r, r2i, ac, created)
Expand Down
31 changes: 29 additions & 2 deletions lib/libesp32/berry_matter/src/embedded/Matter_Device.be
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ class Matter_Device
# autoconfigure other plugins
self.autoconf_device()

# for now read sensors every 5 seconds
tasmota.add_cron("*/5 * * * * *", def () self._trigger_read_sensors() end, "matter_sensors_5s")
# for now read sensors every 30 seconds
tasmota.add_cron("*/30 * * * * *", def () self._trigger_read_sensors() end, "matter_sensors_30s")

self._start_udp(self.UDP_PORT)

Expand Down Expand Up @@ -908,6 +908,7 @@ class Matter_Device
#
def autoconf_device()
import string
import json
# check if we have a light
var endpoint = 1
var light_present = false
Expand Down Expand Up @@ -944,7 +945,33 @@ class Matter_Device
endpoint += 1
end

# auto-detect sensors
var sensors = json.load(tasmota.read_sensors())

# temperature sensors
# they are starting at endpoint `32..39` (8 max)
endpoint = 0x20
for k1:self.k2l(sensors)
var sensor_2 = sensors[k1]
if isinstance(sensor_2, map) && sensor_2.contains("Temperature")
var temp_rule = k1 + "#Temperature"
self.plugins.push(matter.Plugin_Temp_Sensor(self, endpoint, temp_rule))
tasmota.log(string.format("MTR: Endpoint:%i Temperature (%s)", endpoint, temp_rule), 2)
endpoint += 1
end
if endpoint > 0x28 break end
end

end

# get keys of a map in sorted order
static def k2l(m) var l=[] if m==nil return l end for k:m.keys() l.push(k) end
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


# keys to llist

end
matter.Device = Matter_Device

Expand Down
15 changes: 13 additions & 2 deletions lib/libesp32/berry_matter/src/embedded/Matter_IM.be
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ class Matter_IM
# should return true if answered, false if passing to next handler
def read_single_attribute(ret, pi, ctx, direct)
import string
var TLV = matter.TLV
var attr_name = matter.get_attribute_name(ctx.cluster, ctx.attribute)
attr_name = attr_name ? " (" + attr_name + ")" : ""
# Special case to report unsupported item, if pi==nil
Expand All @@ -230,7 +231,12 @@ class Matter_IM
a1.attribute_data.path.attribute = ctx.attribute
a1.attribute_data.data = res

ret.attribute_reports.push(a1)
var a1_tlv = a1.to_TLV()
var a1_len = a1_tlv.encode_len()
var a1_bytes = bytes(a1_len)
var a2 = TLV.create_TLV(TLV.RAW, a1_tlv.tlv2raw(a1_bytes))

ret.attribute_reports.push(a2)
if !no_log
tasmota.log(string.format("MTR: >Read_Attr (%6i) %s%s - %s", session.local_session_id, str(ctx), attr_name, str(res)), 2)
end
Expand All @@ -246,7 +252,12 @@ class Matter_IM
a1.attribute_status.path.attribute = ctx.attribute
a1.attribute_status.status.status = ctx.status

ret.attribute_reports.push(a1)
var a1_tlv = a1.to_TLV()
var a1_len = a1_tlv.encode_len()
var a1_bytes = bytes(a1_len)
var a2 = TLV.create_TLV(TLV.RAW, a1_tlv.tlv2raw(a1_bytes))

ret.attribute_reports.push(a2)
tasmota.log(string.format("MTR: >Read_Attr (%6i) %s%s - STATUS: 0x%02X %s", session.local_session_id, str(ctx), attr_name, ctx.status, ctx.status == matter.UNSUPPORTED_ATTRIBUTE ? "UNSUPPORTED_ATTRIBUTE" : ""), 2)
return true
end
Expand Down
4 changes: 2 additions & 2 deletions lib/libesp32/berry_matter/src/embedded/Matter_IM_Message.be
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,10 @@ class Matter_IM_SubscribeResponse : Matter_IM_ReportData

# Status ok received
def status_ok_received(msg)
# import string
import string
# tasmota.log(string.format("MTR: IM_SubscribeResponse status_ok_received sub=%i exch=%i ack=%i last_counter=%i", self.sub.subscription_id, self.resp.exchange_id, msg.ack_message_counter ? msg.ack_message_counter : 0 , self.last_counter), 3)
# once we receive ack, open flow for subscriptions
# tasmota.log(string.format("MTR: >Sub_OK (%6i) sub=%i", msg.session.local_session_id, self.sub.subscription_id), 2)
tasmota.log(string.format("MTR: >Sub_OK (%6i) sub=%i", msg.session.local_session_id, self.sub.subscription_id), 2)
return super(self).status_ok_received(msg)
end

Expand Down
5 changes: 5 additions & 0 deletions lib/libesp32/berry_matter/src/embedded/Matter_TLV.be
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class Matter_TLV
static var ARRAY = 0x16
static var LIST = 0x17
static var EOC = 0x18
static var RAW = 0xFF # encodes an anonymous raw value (already encoded in TLV to save memory)

#################################################################################
# Matter_TLV_item class
Expand Down Expand Up @@ -224,6 +225,8 @@ class Matter_TLV
var TLV = self.TLV
if b == nil b = bytes() end # start new buffer if none passed

if self.typ == TLV.RAW b..self.val return b end

# special case for bool
# we need to change the type according to the value
if self.typ == TLV.BFALSE || self.typ == TLV.BTRUE
Expand Down Expand Up @@ -320,6 +323,8 @@ class Matter_TLV
var TLV = self.TLV
var len = 0

if self.typ == TLV.RAW return size(self.val) end

# special case for bool
# we need to change the type according to the value
if self.typ == TLV.BFALSE || self.typ == TLV.BTRUE
Expand Down
Loading

0 comments on commit e9e3b03

Please sign in to comment.