From c9b616836c6aeeb2be8b6e750285bb90ef4c9e2f Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Sun, 18 Jun 2023 12:20:42 +0200 Subject: [PATCH] Matter add friendly-name (NodeLabel) to each endpoint --- CHANGELOG.md | 1 + .../src/embedded/Matter_Device.be | 10 +- .../src/embedded/Matter_Plugin_Bridge_HTTP.be | 61 +- .../embedded/Matter_Plugin_Bridge_Light0.be | 14 +- .../embedded/Matter_Plugin_Bridge_Light1.be | 3 +- .../embedded/Matter_Plugin_Bridge_Light2.be | 3 +- .../embedded/Matter_Plugin_Bridge_Light3.be | 3 +- .../embedded/Matter_Plugin_Bridge_OnOff.be | 3 +- .../embedded/Matter_Plugin_Bridge_Sensor.be | 9 + .../Matter_Plugin_Bridge_Sensor_Contact.be | 13 +- .../Matter_Plugin_Bridge_Sensor_Humidity.be | 4 +- ...Matter_Plugin_Bridge_Sensor_Illuminance.be | 4 +- .../Matter_Plugin_Bridge_Sensor_Occupancy.be | 13 +- .../Matter_Plugin_Bridge_Sensor_Pressure.be | 4 +- .../Matter_Plugin_Bridge_Sensor_Temp.be | 4 +- .../src/embedded/Matter_Plugin_Device.be | 30 +- .../berry_matter/src/embedded/Matter_UI.be | 98 +- .../src/solidify/solidified_Matter_Device.h | 6 +- .../solidified_Matter_Plugin_Bridge_HTTP.h | 760 ++++-- .../solidified_Matter_Plugin_Bridge_Light0.h | 457 ++-- .../solidified_Matter_Plugin_Bridge_Light1.h | 41 +- .../solidified_Matter_Plugin_Bridge_Light2.h | 47 +- .../solidified_Matter_Plugin_Bridge_Light3.h | 47 +- .../solidified_Matter_Plugin_Bridge_OnOff.h | 39 +- .../solidified_Matter_Plugin_Bridge_Sensor.h | 251 +- ...fied_Matter_Plugin_Bridge_Sensor_Contact.h | 303 ++- ...ied_Matter_Plugin_Bridge_Sensor_Humidity.h | 42 +- ..._Matter_Plugin_Bridge_Sensor_Illuminance.h | 28 +- ...ed_Matter_Plugin_Bridge_Sensor_Occupancy.h | 257 +- ...ied_Matter_Plugin_Bridge_Sensor_Pressure.h | 28 +- ...idified_Matter_Plugin_Bridge_Sensor_Temp.h | 42 +- .../solidified_Matter_Plugin_Device.h | 183 +- .../src/solidify/solidified_Matter_UI.h | 2390 +++++++++-------- 33 files changed, 3095 insertions(+), 2103 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03c019944ea3..a0c9b764120e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file. - Matter redesigned UI - Matter add support for Contact Sensor - Berry `string.format()` now automatically converts type according to format +- Matter add friendly-name (NodeLabel) to each endpoint ### Breaking Changed diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Device.be b/lib/libesp32/berry_matter/src/embedded/Matter_Device.be index 26c889135759..c62776068321 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Device.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Device.be @@ -698,7 +698,7 @@ class Matter_Device var param_log = '' for k:_class.k2l(plugin_conf) if k == 'type' continue end - param_log += string.format(" %s = %s", k, plugin_conf[k]) + param_log += string.format(" %s:%s", k, plugin_conf[k]) end return param_log end @@ -718,7 +718,7 @@ class Matter_Device # start with mandatory endpoint 0 for root node self.plugins.push(matter.Plugin_Root(self, 0, {})) - tasmota.log(string.format("MTR: endpoint = %5i type = %s%s", 0, 'root', ''), 2) + tasmota.log(string.format("MTR: endpoint = %5i type:%s%s", 0, 'root', ''), 2) # always include an aggregator for dynamic endpoints self.plugins.push(matter.Plugin_Aggregator(self, 0xFF00, {})) @@ -738,12 +738,12 @@ class Matter_Device var pi = pi_class(self, ep, plugin_conf) self.plugins.push(pi) - tasmota.log(string.format("MTR: endpoint = %5i type = %s%s", ep, pi_class_name, self.conf_to_log(plugin_conf)), 2) + tasmota.log(string.format("MTR: endpoint = %5i type:%s%s", ep, pi_class_name, self.conf_to_log(plugin_conf)), 2) except .. as e, m tasmota.log("MTR: Exception" + str(e) + "|" + str(m), 2) end end - tasmota.log(string.format("MTR: endpoint = %5i type = %s%s", 0xFF00, 'aggregator', ''), 2) + tasmota.log(string.format("MTR: endpoint = %5i type:%s%s", 0xFF00, 'aggregator', ''), 2) tasmota.publish_result('{"Matter":{"Initialized":1}}', 'Matter') end @@ -1260,7 +1260,7 @@ class Matter_Device pi_conf[k] = plugin_conf[k] end # add to main - tasmota.log(string.format("MTR: adding endpoint = %i type = %s%s", ep, pi_class_name, self.conf_to_log(plugin_conf)), 2) + tasmota.log(string.format("MTR: adding endpoint = %i type:%s%s", ep, pi_class_name, self.conf_to_log(plugin_conf)), 2) self.plugins_config[ep_str] = pi_conf self.plugins_persist = true self.next_ep += 1 # increment next allocated endpoint before saving diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_HTTP.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_HTTP.be index 2afe4f79f15a..cfb7ff3931bf 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_HTTP.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_HTTP.be @@ -24,6 +24,7 @@ import matter # dummy declaration for solidification class Matter_Plugin_Device end +#@ solidify:Matter_Plugin_Bridge_HTTP.GetOptionReader,weak #@ solidify:Matter_Plugin_Bridge_HTTP,weak class Matter_Plugin_Bridge_HTTP : Matter_Plugin_Device @@ -209,9 +210,20 @@ class Matter_Plugin_Bridge_HTTP : Matter_Plugin_Device # web_values # # Show values of the remote device as HTML + static var PREFIX = "| %s " def web_values() import webserver - webserver.content_send("| <-- (" + self.NAME + ") -->") + import string + self.web_values_prefix() + webserver.content_send("<-- (" + self.NAME + ") -->") + end + + # Show prefix before web value + def web_values_prefix() + import webserver + import string + var name = self.get_name() + webserver.content_send(string.format(self.PREFIX, name ? webserver.html_escape(name) : "")) end # Show on/off value as html @@ -219,5 +231,52 @@ class Matter_Plugin_Bridge_HTTP : Matter_Plugin_Device var onoff_html = (onoff != nil ? (onoff ? "On" : "Off") : "") return onoff_html end + + ############################################################# + # GetOption reader to decode `SetOption` values from `Status 3` + static class GetOptionReader + var flag, flag2, flag3, flag4, flag5, flag6 + + def init(j) + if j == nil raise "value_error", "invalid json" end + var so = j['SetOption'] + self.flag = bytes().fromhex(so[0]).reverse() + self.flag2 = bytes().fromhex(so[1]) + self.flag3 = bytes().fromhex(so[2]).reverse() + self.flag4 = bytes().fromhex(so[3]).reverse() + self.flag5 = bytes().fromhex(so[4]).reverse() + self.flag6 = bytes().fromhex(so[5]).reverse() + end + def getoption(x) + if x < 32 # SetOption0 .. 31 = Settings->flag + return self.flag.getbits(x, 1) + elif x < 50 # SetOption32 .. 49 = Settings->param + return self.flag2.get(x - 32, 1) + elif x < 82 # SetOption50 .. 81 = Settings->flag3 + return self.flag3.getbits(x - 50, 1) + elif x < 114 # SetOption82 .. 113 = Settings->flag4 + return self.flag4.getbits(x - 82, 1) + elif x < 146 # SetOption114 .. 145 = Settings->flag5 + return self.flag5.getbits(x - 114, 1) + elif x < 178 # SetOption146 .. 177 = Settings->flag6 + return self.flag6.getbits(x - 146, 1) + end + end + end + + #- Examples + + import json + + var p = '{"SerialLog":2,"WebLog":3,"MqttLog":0,"SysLog":0,"LogHost":"","LogPort":514,"SSId":["Livebox-781A",""],"TelePeriod":300,"Resolution":"558180C0","SetOption":["00008009","2805C80001800600003C5A0A192800000000","00000080","00006000","00006000","00000020"]}' + var j = json.load(p) + + var gor = matter.Plugin_Bridge_HTTP.GetOptionReader(j) + assert(gor.getoption(151) == 1) + assert(gor.getoption(150) == 0) + assert(gor.getoption(32) == 40) + assert(gor.getoption(37) == 128) + + -# end matter.Plugin_Bridge_HTTP = Matter_Plugin_Bridge_HTTP diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light0.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light0.be index dde2e84353cf..36f01dc4ff98 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light0.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light0.be @@ -145,7 +145,19 @@ class Matter_Plugin_Bridge_Light0 : Matter_Plugin_Bridge_HTTP def web_values() import webserver import string - webserver.content_send(string.format("| Light %s", self.web_value_onoff(self.shadow_onoff))) + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("%s", self.web_value_onoff(self.shadow_onoff))) + end + + # Show prefix before web value + def web_values_prefix() + import webserver + import string + var name = self.get_name() + if !name + name = "Power" + str(self.tasmota_relay_index) + end + webserver.content_send(string.format(self.PREFIX, name ? webserver.html_escape(name) : "")) end end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light1.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light1.be index 3de4c5a30e58..14d568608f11 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light1.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light1.be @@ -173,7 +173,8 @@ class Matter_Plugin_Bridge_Light1 : Matter_Plugin_Bridge_Light0 def web_values() import webserver import string - webserver.content_send(string.format("| Light %s %s", self.web_value_onoff(self.shadow_onoff), self.web_value_dimmer())) + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("%s %s", self.web_value_onoff(self.shadow_onoff), self.web_value_dimmer())) end # Show on/off value as html diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light2.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light2.be index d2ee48b6cdbf..e3e8a46d5fbb 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light2.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light2.be @@ -175,7 +175,8 @@ class Matter_Plugin_Bridge_Light2 : Matter_Plugin_Bridge_Light1 def web_values() import webserver import string - webserver.content_send(string.format("| Light %s %s %s", + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("%s %s %s", self.web_value_onoff(self.shadow_onoff), self.web_value_dimmer(), self.web_value_ct())) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light3.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light3.be index a2e9bcec6af8..42a8e1a781a4 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light3.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Light3.be @@ -201,7 +201,8 @@ class Matter_Plugin_Bridge_Light3 : Matter_Plugin_Bridge_Light1 def web_values() import webserver import string - webserver.content_send(string.format("| Light %s %s %s", + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("%s %s %s", self.web_value_onoff(self.shadow_onoff), self.web_value_dimmer(), self.web_value_RGB())) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_OnOff.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_OnOff.be index 3baaada4578c..b055579d642a 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_OnOff.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_OnOff.be @@ -39,7 +39,8 @@ class Matter_Plugin_Bridge_OnOff : Matter_Plugin_Bridge_Light0 def web_values() import webserver import string - webserver.content_send(string.format("| Relay %i %s", self.tasmota_relay_index, self.web_value_onoff(self.shadow_onoff))) + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("Relay %i %s", self.tasmota_relay_index, self.web_value_onoff(self.shadow_onoff))) end end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor.be index efb70b9643dd..aa4cea70e379 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor.be @@ -98,5 +98,14 @@ class Matter_Plugin_Bridge_Sensor : Matter_Plugin_Bridge_HTTP return "" end + # Show prefix before web value + def web_values_prefix() + import webserver + import string + var name = self.get_name() + if (!name) name = self.filter_name_html() end + webserver.content_send(string.format(self.PREFIX, name ? webserver.html_escape(name) : "")) + end + end matter.Plugin_Bridge_Sensor = Matter_Plugin_Bridge_Sensor diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Contact.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Contact.be index 694fefe6015b..32a826a116f4 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Contact.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Contact.be @@ -103,8 +103,19 @@ class Matter_Plugin_Bridge_Sensor_Contact : Matter_Plugin_Bridge_HTTP def web_values() import webserver import string - webserver.content_send(string.format("| Contact%i %s", self.tasmota_switch_index, self.web_value_onoff(self.shadow_contact))) + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("Contact%i %s", self.tasmota_switch_index, self.web_value_onoff(self.shadow_contact))) end + # Show prefix before web value + def web_values_prefix() + import webserver + import string + var name = self.get_name() + if !name + name = "Switch" + str(self.tasmota_switch_index) + end + webserver.content_send(string.format(self.PREFIX, name ? webserver.html_escape(name) : "")) + end end matter.Plugin_Bridge_Sensor_Contact = Matter_Plugin_Bridge_Sensor_Contact diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Humidity.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Humidity.be index 798225be8ad8..832a289d0a6a 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Humidity.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Humidity.be @@ -92,8 +92,8 @@ class Matter_Plugin_Bridge_Sensor_Humidity : Matter_Plugin_Bridge_Sensor def web_values() import webserver import string - webserver.content_send(string.format("| %s 💧 %2.0f%%", - self.filter_name_html(), + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("💧 %2.0f%%", self.shadow_value != nil ? real(self.shadow_value) / 100 : nil)) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Illuminance.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Illuminance.be index be957a10195c..0358dd9b5c8b 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Illuminance.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Illuminance.be @@ -99,8 +99,8 @@ class Matter_Plugin_Bridge_Sensor_Illuminance : Matter_Plugin_Bridge_Sensor def web_values() import webserver import string - webserver.content_send(string.format("| %s 🔅 %ilux", - self.filter_name_html(), + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("🔅 %ilux", int(self.shadow_value))) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Occupancy.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Occupancy.be index 33bc9763f1a4..ec244cf40cb3 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Occupancy.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Occupancy.be @@ -107,8 +107,19 @@ class Matter_Plugin_Bridge_Sensor_Occupancy : Matter_Plugin_Bridge_HTTP def web_values() import webserver import string - webserver.content_send(string.format("| Occupancy%i %s", self.tasmota_switch_index, self.web_value_onoff(self.shadow_occupancy))) + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("Occupancy%i %s", self.tasmota_switch_index, self.web_value_onoff(self.shadow_occupancy))) end + # Show prefix before web value + def web_values_prefix() + import webserver + import string + var name = self.get_name() + if !name + name = "Switch" + str(self.tasmota_switch_index) + end + webserver.content_send(string.format(self.PREFIX, name ? webserver.html_escape(name) : "")) + end end matter.Plugin_Bridge_Sensor_Occupancy = Matter_Plugin_Bridge_Sensor_Occupancy diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Pressure.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Pressure.be index 3e185d512b9d..6aaa09d78f70 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Pressure.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Pressure.be @@ -92,8 +92,8 @@ class Matter_Plugin_Bridge_Sensor_Pressure : Matter_Plugin_Bridge_Sensor def web_values() import webserver import string - webserver.content_send(string.format("| %s ⛅ %i hPa", - self.filter_name_html(), + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("⛅ %i hPa", int(self.shadow_value))) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Temp.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Temp.be index 5948cf5cdfae..e2817e6a6d01 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Temp.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Bridge_Sensor_Temp.be @@ -92,8 +92,8 @@ class Matter_Plugin_Bridge_Sensor_Temp : Matter_Plugin_Bridge_Sensor def web_values() import webserver import string - webserver.content_send(string.format("| %s ☀️ %.1f °C", - self.filter_name_html(), + self.web_values_prefix() # display '| ' and name if present + webserver.content_send(string.format("☀️ %.1f °C", self.shadow_value != nil ? real(self.shadow_value) / 100 : nil)) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Device.be b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Device.be index c35de9d4ab5c..6a99e37a5e76 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Device.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_Plugin_Device.be @@ -27,7 +27,7 @@ class Matter_Plugin end class Matter_Plugin_Device : Matter_Plugin static var CLUSTERS = { # 0x001D: inherited # Descriptor Cluster 9.5 p.453 - 0x0039: [0x11], # Bridged Device Basic Information 9.13 p.485 + 0x0039: [5], # Bridged Device Basic Information 9.13 p.485 0x0003: [0,1,0xFFFC,0xFFFD], # Identify 1.2 p.16 0x0004: [0,0xFFFC,0xFFFD], # Groups 1.3 p.21 0x0005: [0,1,2,3,4,5,0xFFFC,0xFFFD], # Scenes 1.4 p.30 - no writable @@ -35,11 +35,22 @@ class Matter_Plugin_Device : Matter_Plugin static var TYPES = { 0x0013: 1 } # fake type static var NON_BRIDGE_VENDOR = [ 0x1217, 0x1381 ] # Fabric VendorID not supporting Bridge mode + var node_label # name of the endpoint, used only in bridge mode, "" if none + + def set_name(n) + if n != self.node_label + self.attribute_updated(0x0039, 0x0005) + end + self.node_label = n + end + def get_name() return self.node_label end + ############################################################# # Constructor - # def init(device, endpoint, arguments) - # super(self).init(device, endpoint, arguments) - # end + def init(device, endpoint, config) + self.node_label = config.find("name", "") + super(self).init(device, endpoint, config) + end ############################################################# # read an attribute @@ -103,7 +114,16 @@ class Matter_Plugin_Device : Matter_Plugin else return super(self).read_attribute(session, ctx) end - + + # ==================================================================================================== + elif cluster == 0x0039 # ========== Bridged Device Basic Information 9.13 p.485 ========== + + if attribute == 0x0005 # ---------- NodeLabel / string ---------- + return TLV.create_TLV(TLV.UTF1, self.get_name()) + else + return super(self).read_attribute(session, ctx) + end + else return super(self).read_attribute(session, ctx) end diff --git a/lib/libesp32/berry_matter/src/embedded/Matter_UI.be b/lib/libesp32/berry_matter/src/embedded/Matter_UI.be index 398a3161a3fa..21c1fafd2cdb 100644 --- a/lib/libesp32/berry_matter/src/embedded/Matter_UI.be +++ b/lib/libesp32/berry_matter/src/embedded/Matter_UI.be @@ -301,8 +301,14 @@ class Matter_UI webserver.content_send("
" "

Local sensors and devices

" - "" - "") + "
#TypeParameter
") + webserver.content_send("" + "" + "" + "" + "" + "" + "") # display one line per plug-in self.device.plugins_config.remove("0") # remove any leftover from ancient configuration @@ -327,9 +333,10 @@ class Matter_UI found = true webserver.content_send(string.format("", ep)) - + webserver.content_send(string.format("", + ep, webserver.html_escape(conf.find('name', '')))) webserver.content_send(string.format("", self.plugin_name(conf.find('type', '')))) - webserver.content_send(string.format("", + webserver.content_send(string.format("", ep, webserver.html_escape(arg), cl ? webserver.html_escape(cl.ARG_HINT) : '')) webserver.content_send(string.format("
#NameTypeParameter
%i%s