diff --git a/CHANGELOG.md b/CHANGELOG.md index 1365dcecf..acc56390f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file. - Matter sensors Humidity, Pressure, Illuminance; optimize memory (#18441) - Command ``SetOption152 0/1`` to select two (0 = default) pin bistable or one (1) pin latching relay control (#18386) - Matter allow `Matter#Initialized` rule once the device is configured (#18451) +- Matter add UI to change endpoints configuration ### Breaking Changed diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Base38.be b/lib/libesp32/berry_matter/src/embedded/Matter_Base38.be index 0992d682d..7a5c84d40 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Base38.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Base38.be @@ -68,4 +68,9 @@ matter.Base38 = Matter_Base38 #- +assert(matter.Base38.encode(bytes("DEADBEEF")) == "C.R.5B6") +assert(matter.Base38.encode(bytes("")) == "") +assert(matter.Base38.encode(bytes("00")) == "00") +assert(matter.Base38.encode(bytes("FFFFFFFF")) == "PLS18R6") + -# diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Device.be b/lib/libesp32/berry_matter/src/embedded/Matter_Device.be index 23b4e2fde..3dc514d64 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Device.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Device.be @@ -21,16 +21,16 @@ class Matter_Device static var UDP_PORT = 5540 # this is the default port for group multicast, we also use it for unicast - static var PASSCODE_DEFAULT = 20202021 static var PBKDF_ITERATIONS = 1000 # I don't see any reason to choose a different number static var VENDOR_ID = 0xFFF1 static var PRODUCT_ID = 0x8000 static var FILENAME = "_matter_device.json" static var PASE_TIMEOUT = 10*60 # default open commissioning window (10 minutes) var started # is the Matter Device started (configured, mDNS and UDPServer started) - var plugins # list of plugins + var plugins # list of plugins instances var plugins_persist # true if plugins configuration needs to be saved var plugins_classes # map of registered classes by type name + var plugins_config # map of JSON configuration for plugins var udp_server # `matter.UDPServer()` object var message_handler # `matter.MessageHandler()` object var sessions # `matter.Session_Store()` objet @@ -600,10 +600,11 @@ class Matter_Device # def save_param() import string + import json var j = string.format('{"distinguish":%i,"passcode":%i,"ipv4only":%s', self.root_discriminator, self.root_passcode, self.ipv4only ? 'true':'false') if self.plugins_persist j += ',"config":' - j += self.plugins_to_json() + j += json.dump(self.plugins_config) end j += '}' try @@ -635,9 +636,9 @@ class Matter_Device self.root_discriminator = j.find("distinguish", self.root_discriminator) self.root_passcode = j.find("passcode", self.root_passcode) self.ipv4only = bool(j.find("ipv4only", false)) - var config = j.find("config") - if config - self._load_plugins_config(config) + self.plugins_config = j.find("config") + if self.plugins_config + self._load_plugins_config(self.plugins_config) self.plugins_persist = true end except .. as e, m @@ -652,7 +653,7 @@ class Matter_Device dirty = true end if self.root_passcode == nil - self.root_passcode = self.PASSCODE_DEFAULT + self.root_passcode = self.generate_random_passcode() dirty = true end if dirty self.save_param() end @@ -975,9 +976,9 @@ class Matter_Device if size(self.plugins) > 0 return end # already configured - var config = self.autoconf_device_map() - tasmota.log("MTR: autoconfig = " + str(config), 3) - self._load_plugins_config(config) + self.plugins_config = self.autoconf_device_map() + tasmota.log("MTR: autoconfig = " + str(self.plugins_config), 3) + self._load_plugins_config(self.plugins_config) if !self.plugins_persist && self.sessions.count_active_fabrics() > 0 self.plugins_persist = true @@ -1096,24 +1097,6 @@ class Matter_Device 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 - ############################################################# - # plugins_to_json - # - # Export plugins configuration as a JSON string - def plugins_to_json() - import string - var s = '{' - var i = 0 - while i < size(self.plugins) - var pi = self.plugins[i] - if i > 0 s += ',' end - s += string.format('"%i":%s', pi.get_endpoint(), pi.to_json()) - i += 1 - end - s += '}' - return s - end - ############################################################# # register_plugin_class # @@ -1122,6 +1105,24 @@ class Matter_Device self.plugins_classes[name] = cl end + ############################################################# + # get_plugin_class_displayname + # + # get a class name light "light0" and return displayname + def get_plugin_class_displayname(name) + var cl = self.plugins_classes.find(name) + return cl ? cl.NAME : "" + end + + ############################################################# + # get_plugin_class_arg + # + # get a class name light "light0" and return the name of the json argumen (or empty) + def get_plugin_class_arg(name) + var cl = self.plugins_classes.find(name) + return cl ? cl.ARG : "" + end + ############################################################# # register_native_classes # @@ -1151,6 +1152,23 @@ class Matter_Device end end + ##################################################################### + # Generate random passcode + ##################################################################### + static var PASSCODE_INVALID = [ 0, 11111111, 22222222, 33333333, 44444444, 55555555, 66666666, 77777777, 88888888, 99999999, 12345678, 87654321] + def generate_random_passcode() + import crypto + var passcode + while true + passcode = crypto.random(4).get(0, 4) & 0x7FFFFFF + if passcode > 0x5F5E0FE continue end # larger than allowed + for inv: self.PASSCODE_INVALID + if passcode == inv passcode = nil end + end + if passcode != nil return passcode end + end + end + ##################################################################### # Commands `Mtr___` ##################################################################### diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_MessageHandler.be b/lib/libesp32/berry_matter/src/embedded/Matter_MessageHandler.be index 6c448b9cd..651731c99 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_MessageHandler.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_MessageHandler.be @@ -203,8 +203,10 @@ class Matter_MessageHandler return ret except .. as e, m tasmota.log("MTR: MessageHandler::msg_received exception: "+str(e)+";"+str(m)) - import debug - debug.traceback() + if self._debug_present + import debug + debug.traceback() + end return false end end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin.be index 659e39fc4..e36f99d88 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin.be @@ -23,7 +23,10 @@ #@ solidify:Matter_Plugin,weak class Matter_Plugin - static var NAME = "generic" # name of the plug-in in json + static var TYPE = "generic" # name of the plug-in in json + static var NAME = "" # display name of the plug-in + static var ARG = "" # additional argument name (or empty if none) + static var ARG_TYPE = / x -> str(x) # function to convert argument to the right type static var CLUSTERS = { 0x001D: [0,1,2,3,0xFFFC,0xFFFD], # Descriptor Cluster 9.5 p.453 } @@ -220,30 +223,6 @@ class Matter_Plugin self.update_shadow() # force reading value and sending subscriptions end - ############################################################# - # to_json - # - # generate the json string for parameter of the plug-in - # this function calls a method to be overriden with custom parameters - def to_json() - import string - var s = string.format('{"type":"%s"', self.NAME) - s = self.to_json_parameters(s) - s += '}' - return s - end - - ############################################################# - # to_json_parameters - # - # To be overriden. - # returns a json sub-string to add after endpoint and type name - def to_json_parameters(s) - # s += ',"my_param":"my_value"' - return s - end - - end matter.Plugin = Matter_Plugin diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light0.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light0.be index 0c0b02465..a5803101d 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light0.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light0.be @@ -25,7 +25,8 @@ class Matter_Plugin end #@ solidify:Matter_Plugin_Light0,weak class Matter_Plugin_Light0 : Matter_Plugin - static var NAME = "light0" # name of the plug-in in json + static var TYPE = "light0" # name of the plug-in in json + static var NAME = "Light 0 On" # display name of the plug-in static var CLUSTERS = { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 0x0003: [0,1,0xFFFC,0xFFFD], # Identify 1.2 p.16 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light1.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light1.be index 518b48137..656fbc666 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light1.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light1.be @@ -25,7 +25,8 @@ class Matter_Plugin_Light0 end #@ solidify:Matter_Plugin_Light1,weak class Matter_Plugin_Light1 : Matter_Plugin_Light0 - static var NAME = "light1" # name of the plug-in in json + static var TYPE = "light1" # name of the plug-in in json + static var NAME = "Light 1 Dimmer" # display name of the plug-in static var CLUSTERS = { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light2.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light2.be index 928d0a8f5..8c0cde617 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light2.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light2.be @@ -25,7 +25,8 @@ class Matter_Plugin_Light1 end #@ solidify:Matter_Plugin_Light2,weak class Matter_Plugin_Light2 : Matter_Plugin_Light1 - static var NAME = "light2" # name of the plug-in in json + static var TYPE = "light2" # name of the plug-in in json + static var NAME = "Light 2 CT" # display name of the plug-in static var CLUSTERS = { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light3.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light3.be index dec133661..8e1f63d04 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light3.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Light3.be @@ -25,7 +25,8 @@ class Matter_Plugin_Light1 end #@ solidify:Matter_Plugin_Light3,weak class Matter_Plugin_Light3 : Matter_Plugin_Light1 - static var NAME = "light3" # name of the plug-in in json + static var TYPE = "light3" # name of the plug-in in json + static var NAME = "Light 3 RGB" # display name of the plug-in static var CLUSTERS = { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 # 0x0003: inherited # Identify 1.2 p.16 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_OnOff.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_OnOff.be index fd6245ee2..f45a671f8 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_OnOff.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_OnOff.be @@ -25,7 +25,10 @@ class Matter_Plugin end #@ solidify:Matter_Plugin_OnOff,weak class Matter_Plugin_OnOff : Matter_Plugin - static var NAME = "relay" # name of the plug-in in json + static var TYPE = "relay" # name of the plug-in in json + static var NAME = "Relay" # display name of the plug-in + static var ARG = "relay" # additional argument name (or empty if none) + static var ARG_TYPE = / x -> int(x) # function to convert argument to the right type static var CLUSTERS = { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 0x0003: [0,1,0xFFFC,0xFFFD], # Identify 1.2 p.16 @@ -44,7 +47,7 @@ class Matter_Plugin_OnOff : Matter_Plugin def init(device, endpoint, arguments) super(self).init(device, endpoint, arguments) self.get_onoff() # read actual value - self.tasmota_relay_index = arguments.find('relay') + self.tasmota_relay_index = arguments.find(self.ARG #-'relay'-#) if self.tasmota_relay_index == nil self.tasmota_relay_index = 0 end end @@ -215,17 +218,6 @@ class Matter_Plugin_OnOff : Matter_Plugin self.attribute_updated(nil, 0x0006, 0x0000) # send to all endpoints end - ############################################################# - # to_json_parameters - # - # To be overriden. - # returns a json sub-string to add after endpoint and type name - def to_json_parameters(s) - import string - s += string.format(',"relay":%i', self.tasmota_relay_index) - return s - end - ############################################################# # every_second def every_second() diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Root.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Root.be index dce3c003f..0427ed022 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Root.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Root.be @@ -25,7 +25,8 @@ class Matter_Plugin end #@ solidify:Matter_Plugin_Root,weak class Matter_Plugin_Root : Matter_Plugin - static var NAME = "root" # name of the plug-in in json + static var TYPE = "root" # name of the plug-in in json + static var NAME = "Root node" # display name of the plug-in static var CLUSTERS = { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 0x001F: [0,2,3,4], # Access Control Cluster, p.461 diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor.be index 42511fd7e..45b2ee983 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor.be @@ -25,6 +25,7 @@ class Matter_Plugin_Device end #@ solidify:Matter_Plugin_Sensor,weak class Matter_Plugin_Sensor : Matter_Plugin_Device + static var ARG = "filter" # additional argument name (or empty if none) var tasmota_sensor_filter # Rule-type filter to the value, like "ESP32#Temperature" var tasmota_sensor_matcher # Actual matcher object var shadow_value # Last known value @@ -33,7 +34,7 @@ class Matter_Plugin_Sensor : Matter_Plugin_Device # Constructor def init(device, endpoint, arguments) super(self).init(device, endpoint, arguments) - self.tasmota_sensor_filter = arguments.find('filter') + self.tasmota_sensor_filter = arguments.find(self.ARG#-'filter'-#) if self.tasmota_sensor_filter self.tasmota_sensor_matcher = tasmota.Rule_Matcher.parse(self.tasmota_sensor_filter) end @@ -74,16 +75,5 @@ class Matter_Plugin_Sensor : Matter_Plugin_Device return val end - ############################################################# - # to_json_parameters - # - # To be overriden. - # returns a json sub-string to add after endpoint and type name - def to_json_parameters(s) - import string - s += string.format(',"filter":"%s"', self.tasmota_sensor_filter) - return s - end - end matter.Plugin_Sensor = Matter_Plugin_Sensor diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Humidity.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Humidity.be index 1f85523aa..b31e12965 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Humidity.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Humidity.be @@ -25,7 +25,8 @@ class Matter_Plugin_Sensor end #@ solidify:Matter_Plugin_Sensor_Humidity,weak class Matter_Plugin_Sensor_Humidity : Matter_Plugin_Sensor - static var NAME = "humidity" # name of the plug-in in json + static var TYPE = "humidity" # name of the plug-in in json + static var NAME = "Humidity" # display name of the plug-in static var CLUSTERS = { 0x0405: [0,1,2,0xFFFC,0xFFFD], # Humidity Measurement p.102 - no writable } diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Illuminance.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Illuminance.be index bdf631452..f7619bdfb 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Illuminance.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Illuminance.be @@ -25,7 +25,8 @@ class Matter_Plugin_Sensor end #@ solidify:Matter_Plugin_Sensor_Illuminance,weak class Matter_Plugin_Sensor_Illuminance : Matter_Plugin_Sensor - static var NAME = "illuminance" # name of the plug-in in json + static var TYPE = "illuminance" # name of the plug-in in json + static var NAME = "Illuminance" # display name of the plug-in static var CLUSTERS = { 0x0400: [0,1,2,0xFFFC,0xFFFD], # Illuminance Measurement p.95 - no writable } diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Pressure.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Pressure.be index c39de113e..47a2110cb 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Pressure.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Pressure.be @@ -25,7 +25,8 @@ class Matter_Plugin_Sensor end #@ solidify:Matter_Plugin_Sensor_Pressure,weak class Matter_Plugin_Sensor_Pressure : Matter_Plugin_Sensor - static var NAME = "pressure" # name of the plug-in in json + static var TYPE = "pressure" # name of the plug-in in json + static var NAME = "Pressure" # display name of the plug-in static var CLUSTERS = { 0x0403: [0,1,2,0xFFFC,0xFFFD], # Temperature Measurement p.97 - no writable } diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Temp.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Temp.be index 6dff99c57..9944633be 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Temp.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Sensor_Temp.be @@ -25,7 +25,8 @@ class Matter_Plugin_Sensor end #@ solidify:Matter_Plugin_Sensor_Temp,weak class Matter_Plugin_Sensor_Temp : Matter_Plugin_Sensor - static var NAME = "temperature" # name of the plug-in in json + static var TYPE = "temperature" # name of the plug-in in json + static var NAME = "Temperature" # display name of the plug-in static var CLUSTERS = { 0x0402: [0,1,2,0xFFFC,0xFFFD], # Temperature Measurement p.97 - no writable } diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Session.be b/lib/libesp32/berry_matter/src/embedded/Matter_Session.be index 5936c44cf..b0fe0185c 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Session.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Session.be @@ -328,7 +328,7 @@ class Matter_Session : Matter_Expirable end ############################################################# - # Session::to_json() + # Session::tojson() # # convert a single entry as json # returns a JSON string diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_UI.be b/lib/libesp32/berry_matter/src/embedded/Matter_UI.be index 605c55738..5eb86378b 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_UI.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_UI.be @@ -32,6 +32,8 @@ import matter # WebUI for the partition manager ################################################################################# class Matter_UI + static var _CLASSES_TYPES = "root|relay|light0|light1|light2|light3" + "|temperature|pressure|illuminance|humidity" var device def init(device) @@ -64,7 +66,7 @@ class Matter_UI webserver.content_send(string.format("