mirror of
https://github.com/arendst/Tasmota.git
synced 2026-10-27 06:22:25 +00:00
Matter simplify TLV type with generalized integers (#25087)
This commit is contained in:
1 parent
835813e423
commit
1f543a3374
27 files changed
+244
-208
No files matched your search
@@ -62,6 +62,40 @@ solidified during the Tasmota build. Do not require generated files in
|
||||
`src/solidify/` to be updated in a pull request unless the build workflow
|
||||
explicitly requires committed generated output.
|
||||
|
||||
### Berry Matter TLV encoding widths
|
||||
|
||||
When encoding, `Matter_TLV_item.tlv2raw()` and `encode_len()` in
|
||||
`lib/libesp32/berry_matter/src/embedded/Matter_TLV.be` choose the wire type
|
||||
from the value. The type passed to `add_TLV()` / `set()` is only a starting
|
||||
point:
|
||||
|
||||
- `I2`/`I4` shrink to the smallest signed width that fits (`I1`, `I2` or `I4`).
|
||||
- `U2`/`U4` shrink to the smallest unsigned width that fits (`U1`, `U2` or `U4`).
|
||||
A Berry int that is negative, meaning a u32 above `0x7FFFFFFF`, stays `U4`.
|
||||
- `I8`/`U8` with a plain Berry `int` become `I4`/`U4`, then shrink further.
|
||||
An `int64` instance or `bytes(8)` is always written as 8 bytes, even when
|
||||
the value is small. Pass an `int` if you want the compact form.
|
||||
- `I1`/`U1` are never widened. A value that doesn't fit is truncated to one
|
||||
byte, so declare a wider type if the value can exceed the range.
|
||||
- Signedness is kept: `U*` never becomes `I*`, and the reverse is also true.
|
||||
- `B1`..`B8` and `UTF1`..`UTF8` get their length prefix from the actual size.
|
||||
`BOOL` becomes `BTRUE` or `BFALSE` from the value.
|
||||
- Encoding updates `item.typ` in place.
|
||||
|
||||
Convention: Matter Berry code encodes every signed integer up to 32 bits as
|
||||
`0x02 #-TLV.I4-#` and every unsigned one as `0x06 #-TLV.U4-#`, whatever the
|
||||
schema width (enum8, uint16, int16, and so on). Don't use `I1`/`I2`/`U1`/`U2`
|
||||
in new code. `I8`/`U8` stay for 64-bit fields, and the other type codes are
|
||||
unchanged. `Matter_zzz_TLV_test.be` still covers every code to test the
|
||||
encoder.
|
||||
|
||||
As a result, declaring `U1`, `U2` or `U4` for an enum8, or `I8` for an int64
|
||||
field holding a small value, produces the same bytes. Matter TLV readers must accept
|
||||
any integer width that holds the value, so code reviews shouldn't flag the
|
||||
declared width unless it is too narrow (`I1`/`U1` truncation) or an `int64`
|
||||
instance is used where the compact form was expected. When decoding, only
|
||||
8-byte integers come back as `int64`; smaller ones come back as Berry `int`.
|
||||
|
||||
### Configuration Override
|
||||
|
||||
To customize a build, copy `tasmota/user_config_override_sample.h` to `tasmota/user_config_override.h` and add your `#define` / `#undef` directives there. Do not edit `my_user_config.h` directly — it is the master configuration shipped with each release.
|
||||
|
||||
@@ -90,7 +90,7 @@ class Matter_PBKDFParamResponse
|
||||
# initiatorRandom
|
||||
s.add_TLV(1, 0x10 #-TLV.B1-#, self.initiatorRandom)
|
||||
s.add_TLV(2, 0x10 #-TLV.B1-#, self.responderRandom)
|
||||
s.add_TLV(3, 0x05 #-TLV.U2-#, self.responderSessionId)
|
||||
s.add_TLV(3, 0x06 #-TLV.U4-#, self.responderSessionId)
|
||||
var s_pbkdf = s.add_struct(4)
|
||||
s_pbkdf.add_TLV(1, 0x06 #-TLV.U4-#, self.pbkdf_parameters_iterations)
|
||||
s_pbkdf.add_TLV(2, 0x10 #-TLV.B1-#, self.pbkdf_parameters_salt)
|
||||
@@ -98,11 +98,11 @@ class Matter_PBKDFParamResponse
|
||||
var s2 = s.add_struct(5)
|
||||
s2.add_TLV(1, 0x06 #-TLV.U4-#, self.SLEEPY_IDLE_INTERVAL) # SESSION_IDLE_INTERVAL (optional, sent if set)
|
||||
s2.add_TLV(2, 0x06 #-TLV.U4-#, self.SLEEPY_ACTIVE_INTERVAL) # SESSION_ACTIVE_INTERVAL (optional, sent if set)
|
||||
s2.add_TLV(3, 0x05 #-TLV.U2-#, 4000) # SESSION_ACTIVE_THRESHOLD (4000ms default)
|
||||
s2.add_TLV(4, 0x05 #-TLV.U2-#, 21) # DATA_MODEL_REVISION
|
||||
s2.add_TLV(5, 0x05 #-TLV.U2-#, 13) # INTERACTION_MODEL_REVISION
|
||||
s2.add_TLV(3, 0x06 #-TLV.U4-#, 4000) # SESSION_ACTIVE_THRESHOLD (4000ms default)
|
||||
s2.add_TLV(4, 0x06 #-TLV.U4-#, 21) # DATA_MODEL_REVISION
|
||||
s2.add_TLV(5, 0x06 #-TLV.U4-#, 13) # INTERACTION_MODEL_REVISION
|
||||
s2.add_TLV(6, 0x06 #-TLV.U4-#, 0x01060100) # SPECIFICATION_VERSION (1.6.1.0)
|
||||
s2.add_TLV(7, 0x05 #-TLV.U2-#, 1) # MAX_PATHS_PER_INVOKE
|
||||
s2.add_TLV(7, 0x06 #-TLV.U4-#, 1) # MAX_PATHS_PER_INVOKE
|
||||
return s.tlv2raw(b)
|
||||
end
|
||||
end
|
||||
@@ -224,18 +224,18 @@ class Matter_Sigma2
|
||||
var s = TLV.Matter_TLV_struct()
|
||||
# initiatorRandom
|
||||
s.add_TLV(1, 0x10 #-TLV.B1-#, self.responderRandom)
|
||||
s.add_TLV(2, 0x05 #-TLV.U2-#, self.responderSessionId)
|
||||
s.add_TLV(2, 0x06 #-TLV.U4-#, self.responderSessionId)
|
||||
s.add_TLV(3, 0x10 #-TLV.B1-#, self.responderEphPubKey)
|
||||
s.add_TLV(4, 0x10 #-TLV.B1-#, self.encrypted2)
|
||||
# Always include session params with mandatory fields (Matter 1.4 §4.10)
|
||||
var s2 = s.add_struct(5)
|
||||
s2.add_TLV(1, 0x06 #-TLV.U4-#, self.SLEEPY_IDLE_INTERVAL) # SESSION_IDLE_INTERVAL (optional, sent if set)
|
||||
s2.add_TLV(2, 0x06 #-TLV.U4-#, self.SLEEPY_ACTIVE_INTERVAL) # SESSION_ACTIVE_INTERVAL (optional, sent if set)
|
||||
s2.add_TLV(3, 0x05 #-TLV.U2-#, 4000) # SESSION_ACTIVE_THRESHOLD (4000ms default)
|
||||
s2.add_TLV(4, 0x05 #-TLV.U2-#, 21) # DATA_MODEL_REVISION
|
||||
s2.add_TLV(5, 0x05 #-TLV.U2-#, 13) # INTERACTION_MODEL_REVISION
|
||||
s2.add_TLV(3, 0x06 #-TLV.U4-#, 4000) # SESSION_ACTIVE_THRESHOLD (4000ms default)
|
||||
s2.add_TLV(4, 0x06 #-TLV.U4-#, 21) # DATA_MODEL_REVISION
|
||||
s2.add_TLV(5, 0x06 #-TLV.U4-#, 13) # INTERACTION_MODEL_REVISION
|
||||
s2.add_TLV(6, 0x06 #-TLV.U4-#, 0x01060100) # SPECIFICATION_VERSION (1.6.1.0)
|
||||
s2.add_TLV(7, 0x05 #-TLV.U2-#, 1) # MAX_PATHS_PER_INVOKE
|
||||
s2.add_TLV(7, 0x06 #-TLV.U4-#, 1) # MAX_PATHS_PER_INVOKE
|
||||
return s.tlv2raw(b)
|
||||
end
|
||||
end
|
||||
@@ -257,16 +257,16 @@ class Matter_Sigma2Resume
|
||||
# initiatorRandom
|
||||
s.add_TLV(1, 0x10 #-TLV.B1-#, self.resumptionID)
|
||||
s.add_TLV(2, 0x10 #-TLV.B1-#, self.sigma2ResumeMIC)
|
||||
s.add_TLV(3, 0x05 #-TLV.U2-#, self.responderSessionID)
|
||||
s.add_TLV(3, 0x06 #-TLV.U4-#, self.responderSessionID)
|
||||
# Always include session params with mandatory fields (Matter 1.4 §4.10)
|
||||
var s2 = s.add_struct(4)
|
||||
s2.add_TLV(1, 0x06 #-TLV.U4-#, self.SLEEPY_IDLE_INTERVAL) # SESSION_IDLE_INTERVAL (optional, sent if set)
|
||||
s2.add_TLV(2, 0x06 #-TLV.U4-#, self.SLEEPY_ACTIVE_INTERVAL) # SESSION_ACTIVE_INTERVAL (optional, sent if set)
|
||||
s2.add_TLV(3, 0x05 #-TLV.U2-#, 4000) # SESSION_ACTIVE_THRESHOLD (4000ms default)
|
||||
s2.add_TLV(4, 0x05 #-TLV.U2-#, 21) # DATA_MODEL_REVISION
|
||||
s2.add_TLV(5, 0x05 #-TLV.U2-#, 13) # INTERACTION_MODEL_REVISION
|
||||
s2.add_TLV(3, 0x06 #-TLV.U4-#, 4000) # SESSION_ACTIVE_THRESHOLD (4000ms default)
|
||||
s2.add_TLV(4, 0x06 #-TLV.U4-#, 21) # DATA_MODEL_REVISION
|
||||
s2.add_TLV(5, 0x06 #-TLV.U4-#, 13) # INTERACTION_MODEL_REVISION
|
||||
s2.add_TLV(6, 0x06 #-TLV.U4-#, 0x01060100) # SPECIFICATION_VERSION (1.6.1.0)
|
||||
s2.add_TLV(7, 0x05 #-TLV.U2-#, 1) # MAX_PATHS_PER_INVOKE
|
||||
s2.add_TLV(7, 0x06 #-TLV.U4-#, 1) # MAX_PATHS_PER_INVOKE
|
||||
return s.tlv2raw(b)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -133,12 +133,12 @@ class Matter_AttributePathIB : Matter_IM_base
|
||||
var s = TLV.Matter_TLV_list()
|
||||
s.add_TLV(0, 0x08 #-TLV.BOOL-#, self.tag_compression)
|
||||
s.add_TLV(1, 0x07 #-TLV.U8-#, self.node)
|
||||
s.add_TLV(2, 0x05 #-TLV.U2-#, self.endpoint)
|
||||
s.add_TLV(2, 0x06 #-TLV.U4-#, self.endpoint)
|
||||
s.add_TLV(3, 0x06 #-TLV.U4-#, self.cluster)
|
||||
s.add_TLV(4, 0x06 #-TLV.U4-#, self.attribute)
|
||||
# Re-emit ListIndex only when it was present, preserving append semantics.
|
||||
if self.list_index_present
|
||||
s.add_TLV(5, self.list_index_is_null ? 0x14 #-TLV.NULL-# : 0x05 #-TLV.U2-#, self.list_index)
|
||||
s.add_TLV(5, self.list_index_is_null ? 0x14 #-TLV.NULL-# : 0x06 #-TLV.U4-#, self.list_index)
|
||||
end
|
||||
return s
|
||||
end
|
||||
@@ -167,7 +167,7 @@ class Matter_ClusterPathIB : Matter_IM_base
|
||||
var TLV = matter.TLV
|
||||
var s = TLV.Matter_TLV_list()
|
||||
s.add_TLV(0, 0x07 #-TLV.U8-#, self.node)
|
||||
s.add_TLV(1, 0x05 #-TLV.U2-#, self.endpoint)
|
||||
s.add_TLV(1, 0x06 #-TLV.U4-#, self.endpoint)
|
||||
s.add_TLV(2, 0x06 #-TLV.U4-#, self.cluster)
|
||||
return s
|
||||
end
|
||||
@@ -306,7 +306,7 @@ class Matter_EventPathIB : Matter_IM_base
|
||||
var TLV = matter.TLV
|
||||
if s == nil s = TLV.Matter_TLV_list() end
|
||||
s.add_TLV(0, 0x07 #-TLV.U8-#, self.node)
|
||||
s.add_TLV(1, 0x05 #-TLV.U2-#, self.endpoint)
|
||||
s.add_TLV(1, 0x06 #-TLV.U4-#, self.endpoint)
|
||||
s.add_TLV(2, 0x06 #-TLV.U4-#, self.cluster)
|
||||
s.add_TLV(3, 0x06 #-TLV.U4-#, self.event)
|
||||
s.add_TLV(4, 0x08 #-TLV.BOOL-#, self.is_urgent)
|
||||
@@ -352,7 +352,7 @@ class Matter_EventDataIB : Matter_IM_base
|
||||
self.path.to_TLV(s.add_list(0))
|
||||
end
|
||||
s.add_TLV(1, 0x07 #-TLV.U8-#, self.event_number)
|
||||
s.add_TLV(2, 0x04 #-TLV.U1-#, self.priority)
|
||||
s.add_TLV(2, 0x06 #-TLV.U4-#, self.priority)
|
||||
s.add_TLV(3, 0x07 #-TLV.U8-#, self.epoch_timestamp)
|
||||
s.add_TLV(4, 0x07 #-TLV.U8-#, self.system_timestamp)
|
||||
s.add_TLV(5, 0x07 #-TLV.U8-#, self.delta_epoch_timestamp)
|
||||
@@ -409,7 +409,7 @@ class Matter_CommandPathIB : Matter_IM_base
|
||||
def to_TLV()
|
||||
var TLV = matter.TLV
|
||||
var s = TLV.Matter_TLV_list()
|
||||
s.add_TLV(0, 0x05 #-TLV.U2-#, self.endpoint)
|
||||
s.add_TLV(0, 0x06 #-TLV.U4-#, self.endpoint)
|
||||
s.add_TLV(1, 0x06 #-TLV.U4-#, self.cluster)
|
||||
s.add_TLV(2, 0x06 #-TLV.U4-#, self.command)
|
||||
return s
|
||||
@@ -562,8 +562,8 @@ class Matter_StatusIB : Matter_IM_base
|
||||
def to_TLV()
|
||||
var TLV = matter.TLV
|
||||
var s = TLV.Matter_TLV_struct()
|
||||
s.add_TLV(0, 0x05 #-TLV.U2-#, self.status)
|
||||
s.add_TLV(1, 0x05 #-TLV.U2-#, self.cluster_status)
|
||||
s.add_TLV(0, 0x06 #-TLV.U4-#, self.status)
|
||||
s.add_TLV(1, 0x06 #-TLV.U4-#, self.cluster_status)
|
||||
return s
|
||||
end
|
||||
end
|
||||
@@ -602,7 +602,7 @@ class Matter_StatusResponseMessage : Matter_IM_Message_base
|
||||
var TLV = matter.TLV
|
||||
var s = TLV.Matter_TLV_struct()
|
||||
s.add_TLV(0, 0x06 #-TLV.U4-#, self.status)
|
||||
s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
return s
|
||||
end
|
||||
end
|
||||
@@ -638,7 +638,7 @@ class Matter_ReadRequestMessage : Matter_IM_Message_base
|
||||
# self.to_TLV_array(s, 2, self.event_filters)
|
||||
# s.add_TLV(3, 0x08 #-TLV.BOOL-#, self.fabric_filtered)
|
||||
# self.to_TLV_array(s, 4, self.data_version_filters)
|
||||
# s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
# s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
# return s
|
||||
# end
|
||||
end
|
||||
@@ -909,7 +909,7 @@ class Matter_ReportDataMessage : Matter_IM_Message_base
|
||||
self.to_TLV_array(s, 2, self.event_reports)
|
||||
s.add_TLV(3, 0x08 #-TLV.BOOL-#, self.more_chunked_messages)
|
||||
s.add_TLV(4, 0x08 #-TLV.BOOL-#, self.suppress_response)
|
||||
s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
return s
|
||||
end
|
||||
end
|
||||
@@ -947,14 +947,14 @@ class Matter_SubscribeRequestMessage : Matter_IM_Message_base
|
||||
# var TLV = matter.TLV
|
||||
# var s = TLV.Matter_TLV_struct()
|
||||
# s.add_TLV(0, 0x08 #-TLV.BOOL-#, self.keep_subscriptions)
|
||||
# s.add_TLV(1, 0x05 #-TLV.U2-#, self.min_interval_floor)
|
||||
# s.add_TLV(2, 0x05 #-TLV.U2-#, self.max_interval_ceiling)
|
||||
# s.add_TLV(1, 0x06 #-TLV.U4-#, self.min_interval_floor)
|
||||
# s.add_TLV(2, 0x06 #-TLV.U4-#, self.max_interval_ceiling)
|
||||
# self.to_TLV_array(s, 3, self.attributes_requests)
|
||||
# self.to_TLV_array(s, 4, self.event_requests)
|
||||
# self.to_TLV_array(s, 5, self.event_filters)
|
||||
# s.add_TLV(7, 0x08 #-TLV.BOOL-#, self.fabric_filtered)
|
||||
# self.to_TLV_array(s, 8, self.data_version_filters)
|
||||
# s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
# s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
# return s
|
||||
# end
|
||||
end
|
||||
@@ -980,8 +980,8 @@ class Matter_SubscribeResponseMessage : Matter_IM_Message_base
|
||||
var TLV = matter.TLV
|
||||
var s = TLV.Matter_TLV_struct()
|
||||
s.add_TLV(0, 0x06 #-TLV.U4-#, self.subscription_id)
|
||||
s.add_TLV(2, 0x05 #-TLV.U2-#, self.max_interval)
|
||||
s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
s.add_TLV(2, 0x06 #-TLV.U4-#, self.max_interval)
|
||||
s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
return s
|
||||
end
|
||||
end
|
||||
@@ -1014,7 +1014,7 @@ class Matter_WriteRequestMessage : Matter_IM_Message_base
|
||||
# s.add_TLV(1, 0x08 #-TLV.BOOL-#, self.timed_request)
|
||||
# self.to_TLV_array(s, 2, self.write_requests)
|
||||
# s.add_TLV(3, 0x08 #-TLV.BOOL-#, self.more_chunked_messages)
|
||||
# s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
# s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
# return s
|
||||
# end
|
||||
end
|
||||
@@ -1038,7 +1038,7 @@ class Matter_WriteResponseMessage : Matter_IM_Message_base
|
||||
var TLV = matter.TLV
|
||||
var s = TLV.Matter_TLV_struct()
|
||||
self.to_TLV_array(s, 0, self.write_responses)
|
||||
s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
return s
|
||||
end
|
||||
end
|
||||
@@ -1061,8 +1061,8 @@ class Matter_TimedRequestMessage : Matter_IM_Message_base
|
||||
# def to_TLV()
|
||||
# var TLV = matter.TLV
|
||||
# var s = TLV.Matter_TLV_struct()
|
||||
# s.add_TLV(0, 0x05 #-TLV.U2-#, self.timeout)
|
||||
# s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
# s.add_TLV(0, 0x06 #-TLV.U4-#, self.timeout)
|
||||
# s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
# return s
|
||||
# end
|
||||
end
|
||||
@@ -1092,7 +1092,7 @@ class Matter_InvokeRequestMessage : Matter_IM_Message_base
|
||||
# s.add_TLV(0, 0x08 #-TLV.BOOL-#, self.suppress_response)
|
||||
# s.add_TLV(1, 0x08 #-TLV.BOOL-#, self.timed_request)
|
||||
# self.to_TLV_array(s, 2, self.invoke_requests)
|
||||
# s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
# s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
# return s
|
||||
# end
|
||||
end
|
||||
@@ -1119,7 +1119,7 @@ class Matter_InvokeResponseMessage : Matter_IM_Message_base
|
||||
var s = TLV.Matter_TLV_struct()
|
||||
s.add_TLV(0, 0x08 #-TLV.BOOL-#, self.suppress_response)
|
||||
self.to_TLV_array(s, 1, self.invoke_responses)
|
||||
s.add_TLV(0xFF, 0x04 #-TLV.U1-#, self.InteractionModelRevision)
|
||||
s.add_TLV(0xFF, 0x06 #-TLV.U4-#, self.InteractionModelRevision)
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
@@ -426,8 +426,8 @@ matter_device.events.dump()
|
||||
var types = self.TYPES
|
||||
for dt: types.keys()
|
||||
var d1 = dtl.add_struct()
|
||||
d1.add_TLV(0, 0x05 #-TLV.U2-#, dt) # DeviceType
|
||||
d1.add_TLV(1, 0x05 #-TLV.U2-#, types[dt]) # Revision
|
||||
d1.add_TLV(0, 0x06 #-TLV.U4-#, dt) # DeviceType
|
||||
d1.add_TLV(1, 0x06 #-TLV.U4-#, types[dt]) # Revision
|
||||
end
|
||||
return dtl
|
||||
elif attribute == 0x0001 # ---------- ServerList / list[cluster-id] ----------
|
||||
@@ -460,7 +460,7 @@ matter_device.events.dump()
|
||||
var attr_list_bytes_sz = (attr_list_bytes != nil) ? size(attr_list_bytes) / 2 : 0
|
||||
var idx = 0
|
||||
while idx < attr_list_bytes_sz
|
||||
acli.add_TLV(nil, 0x05 #-TLV.U2-#, attr_list_bytes.get(idx * 2, -2))
|
||||
acli.add_TLV(nil, 0x06 #-TLV.U4-#, attr_list_bytes.get(idx * 2, -2))
|
||||
idx += 1
|
||||
end
|
||||
return acli # TODO, empty list for now
|
||||
|
||||
@@ -78,16 +78,16 @@ class Matter_Plugin_Aggregator : Matter_Plugin
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0003 # ========== Identify 1.2 p.16 ==========
|
||||
if attribute == 0x0000 # ---------- IdentifyTime / u2 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0) # no identification in progress
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) # no identification in progress
|
||||
elif attribute == 0x0001 # ---------- IdentifyType / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0) # IdentifyType = 0x00 None
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) # IdentifyType = 0x00 None
|
||||
end
|
||||
|
||||
elif cluster == 0x001D # ========== Descriptor Cluster 9.5 p.453 ==========
|
||||
if attribute == 0x0002 # ---------- ClientList / list[cluster-id] ----------
|
||||
var pl = TLV.Matter_TLV_array()
|
||||
# from connectedhome reference implementation
|
||||
pl.add_TLV(nil, 0x05 #-TLV.U2-#, 0x001E) # Binding
|
||||
pl.add_TLV(nil, 0x06 #-TLV.U4-#, 0x001E) # Binding
|
||||
return pl
|
||||
# overwrite PartsList
|
||||
elif attribute == 0x0003 # ---------- PartsList / list[endpoint-no]----------
|
||||
@@ -95,7 +95,7 @@ class Matter_Plugin_Aggregator : Matter_Plugin
|
||||
for plugin: self.device.plugins
|
||||
var ep = plugin.get_endpoint()
|
||||
if ep != 0x0001 #-matter.AGGREGATOR_ENDPOINT-# && ep != 0 && plugin.AGGREGATE
|
||||
pl.add_TLV(nil, 0x05 #-TLV.U2-#, ep) # add each top-level endpoint
|
||||
pl.add_TLV(nil, 0x06 #-TLV.U4-#, ep) # add each top-level endpoint
|
||||
end
|
||||
end
|
||||
return pl
|
||||
@@ -126,7 +126,7 @@ class Matter_Plugin_Aggregator : Matter_Plugin
|
||||
# ID=1
|
||||
# 0=Certificate (octstr)
|
||||
var iqr = TLV.Matter_TLV_struct()
|
||||
iqr.add_TLV(0, 0x05 #-TLV.U2-#, 0) # Timeout
|
||||
iqr.add_TLV(0, 0x06 #-TLV.U4-#, 0) # Timeout
|
||||
ctx.command = 0x00 # IdentifyQueryResponse
|
||||
return iqr
|
||||
elif command == 0x0040 # ---------- TriggerEffect ----------
|
||||
|
||||
@@ -216,15 +216,15 @@ class Matter_Plugin_Device : Matter_Plugin
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0003 # ========== Identify 1.2 p.16 ==========
|
||||
if attribute == 0x0000 # ---------- IdentifyTime / u2 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0) # no identification in progress
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) # no identification in progress
|
||||
elif attribute == 0x0001 # ---------- IdentifyType / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0) # IdentifyType = 0x00 None
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) # IdentifyType = 0x00 None
|
||||
end
|
||||
|
||||
# ====================================================================================================
|
||||
elif cluster == 0x0004 # ========== Groups 1.3 p.21 ==========
|
||||
if attribute == 0x0000 # ---------- NameSupport ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, self.device.GROUP_TRANSPORT_READY ? 0x80 : 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.device.GROUP_TRANSPORT_READY ? 0x80 : 0)
|
||||
elif attribute == 0xFFFC # ---------- FeatureMap ----------
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.device.GROUP_TRANSPORT_READY ? 1 : 0)
|
||||
end
|
||||
@@ -242,14 +242,14 @@ class Matter_Plugin_Device : Matter_Plugin
|
||||
var types = self.TYPES
|
||||
for dt: types.keys()
|
||||
var d1 = dtl.add_struct()
|
||||
d1.add_TLV(0, 0x05 #-TLV.U2-#, dt) # DeviceType
|
||||
d1.add_TLV(1, 0x05 #-TLV.U2-#, types[dt]) # Revision
|
||||
d1.add_TLV(0, 0x06 #-TLV.U4-#, dt) # DeviceType
|
||||
d1.add_TLV(1, 0x06 #-TLV.U4-#, types[dt]) # Revision
|
||||
end
|
||||
# if fabric is not Alexa
|
||||
if (self.NON_BRIDGE_VENDOR.find(session.get_admin_vendor()) == nil) && (!self.device.disable_bridge_mode)
|
||||
var d1 = dtl.add_struct()
|
||||
d1.add_TLV(0, 0x05 #-TLV.U2-#, 0x0013) # DeviceType
|
||||
d1.add_TLV(1, 0x05 #-TLV.U2-#, 1) # Revision
|
||||
d1.add_TLV(0, 0x06 #-TLV.U4-#, 0x0013) # DeviceType
|
||||
d1.add_TLV(1, 0x06 #-TLV.U4-#, 1) # Revision
|
||||
end
|
||||
return dtl
|
||||
end
|
||||
@@ -328,7 +328,7 @@ class Matter_Plugin_Device : Matter_Plugin
|
||||
# ID=1
|
||||
# 0=Certificate (octstr)
|
||||
var iqr = TLV.Matter_TLV_struct()
|
||||
iqr.add_TLV(0, 0x05 #-TLV.U2-#, 0) # Timeout
|
||||
iqr.add_TLV(0, 0x06 #-TLV.U4-#, 0) # Timeout
|
||||
ctx.command = 0x00 # IdentifyQueryResponse
|
||||
return iqr
|
||||
elif command == 0x0040 # ---------- TriggerEffect ----------
|
||||
@@ -365,8 +365,8 @@ class Matter_Plugin_Device : Matter_Plugin
|
||||
fabric.add_group_endpoint(group_id, self.endpoint, group_name)
|
||||
end
|
||||
var response = TLV.Matter_TLV_struct()
|
||||
response.add_TLV(0, 0x04 #-TLV.U1-#, status)
|
||||
response.add_TLV(1, 0x05 #-TLV.U2-#, group_id)
|
||||
response.add_TLV(0, 0x06 #-TLV.U4-#, status)
|
||||
response.add_TLV(1, 0x06 #-TLV.U4-#, group_id)
|
||||
ctx.command = 0x0000 # AddGroupResponse
|
||||
return response
|
||||
|
||||
@@ -380,10 +380,10 @@ class Matter_Plugin_Device : Matter_Plugin
|
||||
var member = self.device.GROUP_TRANSPORT_READY &&
|
||||
group != nil && group.find("endpoints", []).find(self.endpoint) != nil
|
||||
var response = TLV.Matter_TLV_struct()
|
||||
response.add_TLV(0, 0x04 #-TLV.U1-#,
|
||||
response.add_TLV(0, 0x06 #-TLV.U4-#,
|
||||
group_id == 0 ? 0x87 #-matter.CONSTRAINT_ERROR-# :
|
||||
member ? 0 : 0x8B #-matter.NOT_FOUND-#)
|
||||
response.add_TLV(1, 0x05 #-TLV.U2-#, group_id)
|
||||
response.add_TLV(1, 0x06 #-TLV.U4-#, group_id)
|
||||
response.add_TLV(2, 0x0C #-TLV.UTF1-#, member ? group.find("name", "") : "")
|
||||
ctx.command = 0x0001 # ViewGroupResponse
|
||||
return response
|
||||
@@ -391,7 +391,7 @@ class Matter_Plugin_Device : Matter_Plugin
|
||||
elif command == 0x0002 # ---------- GetGroupMembership ----------
|
||||
var requested = val.findsub(0)
|
||||
var response = TLV.Matter_TLV_struct()
|
||||
response.add_TLV(0, 0x04 #-TLV.U1-#,
|
||||
response.add_TLV(0, 0x06 #-TLV.U4-#,
|
||||
self.device.GROUP_TRANSPORT_READY ? 4 - size(fabric.get_group_table()) : 0)
|
||||
var groups = response.add_array(1)
|
||||
if self.device.GROUP_TRANSPORT_READY
|
||||
@@ -409,7 +409,7 @@ class Matter_Plugin_Device : Matter_Plugin
|
||||
end
|
||||
end
|
||||
if include
|
||||
groups.add_TLV(nil, 0x05 #-TLV.U2-#, group.find("group_id"))
|
||||
groups.add_TLV(nil, 0x06 #-TLV.U4-#, group.find("group_id"))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -424,10 +424,10 @@ class Matter_Plugin_Device : Matter_Plugin
|
||||
end
|
||||
var removed = group_id != 0 && fabric.remove_group_endpoint(group_id, self.endpoint)
|
||||
var response = TLV.Matter_TLV_struct()
|
||||
response.add_TLV(0, 0x04 #-TLV.U1-#,
|
||||
response.add_TLV(0, 0x06 #-TLV.U4-#,
|
||||
group_id == 0 ? 0x87 #-matter.CONSTRAINT_ERROR-# :
|
||||
removed ? 0 : 0x8B #-matter.NOT_FOUND-#)
|
||||
response.add_TLV(1, 0x05 #-TLV.U2-#, group_id)
|
||||
response.add_TLV(1, 0x06 #-TLV.U4-#, group_id)
|
||||
ctx.command = 0x0003 # RemoveGroupResponse
|
||||
return response
|
||||
|
||||
|
||||
@@ -641,7 +641,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
super(self).init(device, endpoint, config)
|
||||
# publish mandatory events
|
||||
self.publish_event(0x0028, 0x00, 2 #-matter.EVENT_CRITICAL-#, matter.TLV.Matter_TLV_item().set(0x06 #-matter.TLV.U4-#, tasmota.version())) # Event StartUp - Software Version
|
||||
self.publish_event(0x0033, 0x03, 2 #-matter.EVENT_CRITICAL-#, matter.TLV.Matter_TLV_item().set(0x04 #-matter.TLV.U1-#, 1)) # Event BootReason - PowerOnReboot - TODO if we need to refine
|
||||
self.publish_event(0x0033, 0x03, 2 #-matter.EVENT_CRITICAL-#, matter.TLV.Matter_TLV_item().set(0x06 #-matter.TLV.U4-#, 1)) # Event BootReason - PowerOnReboot - TODO if we need to refine
|
||||
end
|
||||
|
||||
# Open or resume the GroupKeyMap list-write transaction for this exchange.
|
||||
@@ -689,11 +689,11 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
var result = TLV.Matter_TLV_array()
|
||||
if fabric != nil
|
||||
var out = result.add_struct(nil)
|
||||
out.add_TLV(1, 0x04 #-TLV.U1-#, 5) # Administer
|
||||
out.add_TLV(2, 0x04 #-TLV.U1-#, 2) # CASE
|
||||
out.add_TLV(1, 0x06 #-TLV.U4-#, 5) # Administer
|
||||
out.add_TLV(2, 0x06 #-TLV.U4-#, 2) # CASE
|
||||
out.add_TLV(3, 0x14 #-TLV.NULL-#, nil) # all CASE subjects
|
||||
out.add_TLV(4, 0x14 #-TLV.NULL-#, nil) # all targets
|
||||
out.add_TLV(0xFE, 0x04 #-TLV.U1-#, fabric.get_fabric_index())
|
||||
out.add_TLV(0xFE, 0x06 #-TLV.U4-#, fabric.get_fabric_index())
|
||||
end
|
||||
return result
|
||||
end
|
||||
@@ -709,9 +709,9 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
end
|
||||
for entry : fabric.get_group_key_map()
|
||||
var out = result.add_struct(nil)
|
||||
out.add_TLV(1, 0x05 #-TLV.U2-#, entry.find("group_id"))
|
||||
out.add_TLV(2, 0x05 #-TLV.U2-#, entry.find("key_set_id"))
|
||||
out.add_TLV(0xFE, 0x04 #-TLV.U1-#, fabric.get_fabric_index())
|
||||
out.add_TLV(1, 0x06 #-TLV.U4-#, entry.find("group_id"))
|
||||
out.add_TLV(2, 0x06 #-TLV.U4-#, entry.find("key_set_id"))
|
||||
out.add_TLV(0xFE, 0x06 #-TLV.U4-#, fabric.get_fabric_index())
|
||||
end
|
||||
return result
|
||||
end
|
||||
@@ -825,13 +825,13 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
end
|
||||
for entry : fabric.get_group_table()
|
||||
var out = result.add_struct(nil)
|
||||
out.add_TLV(1, 0x05 #-TLV.U2-#, entry.find("group_id"))
|
||||
out.add_TLV(1, 0x06 #-TLV.U4-#, entry.find("group_id"))
|
||||
var endpoints = out.add_array(2)
|
||||
for endpoint : entry.find("endpoints", [])
|
||||
endpoints.add_TLV(nil, 0x05 #-TLV.U2-#, endpoint)
|
||||
endpoints.add_TLV(nil, 0x06 #-TLV.U4-#, endpoint)
|
||||
end
|
||||
out.add_TLV(3, 0x0C #-TLV.UTF1-#, entry.find("name", ""))
|
||||
out.add_TLV(0xFE, 0x04 #-TLV.U1-#, fabric.get_fabric_index())
|
||||
out.add_TLV(0xFE, 0x06 #-TLV.U4-#, fabric.get_fabric_index())
|
||||
end
|
||||
return result
|
||||
end
|
||||
@@ -902,8 +902,8 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
def group_key_set_to_tlv(key_set, id)
|
||||
var TLV = matter.TLV
|
||||
var out = TLV.Matter_TLV_struct()
|
||||
out.add_TLV(0, 0x05 #-TLV.U2-#, id)
|
||||
out.add_TLV(1, 0x04 #-TLV.U1-#, key_set != nil ? key_set.find("policy", 0) : 0)
|
||||
out.add_TLV(0, 0x06 #-TLV.U4-#, id)
|
||||
out.add_TLV(1, 0x06 #-TLV.U4-#, key_set != nil ? key_set.find("policy", 0) : 0)
|
||||
# KeySetRead never discloses group key material; only epoch start times are returned.
|
||||
var idx = 0
|
||||
while idx < 3
|
||||
@@ -930,13 +930,13 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
return tlv_solo.set(0x07 #-TLV.U8-#, session._breadcrumb)
|
||||
elif attribute == 0x0001 # ---------- BasicCommissioningInfo / BasicCommissioningInfo----------
|
||||
var bci = TLV.Matter_TLV_struct()
|
||||
bci.add_TLV(0, 0x05 #-TLV.U2-#, 60) # FailSafeExpiryLengthSeconds
|
||||
bci.add_TLV(1, 0x05 #-TLV.U2-#, 900) # MaxCumulativeFailsafeSeconds
|
||||
bci.add_TLV(0, 0x06 #-TLV.U4-#, 60) # FailSafeExpiryLengthSeconds
|
||||
bci.add_TLV(1, 0x06 #-TLV.U4-#, 900) # MaxCumulativeFailsafeSeconds
|
||||
return bci
|
||||
elif attribute == 0x0002 # ---------- RegulatoryConfig / RegulatoryLocationType ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 2) # 2 = IndoorOutdoor | esp-matter = 0
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 2) # 2 = IndoorOutdoor | esp-matter = 0
|
||||
elif attribute == 0x0003 # ---------- LocationCapability / RegulatoryLocationType----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 2) # 2 = IndoorOutdoor
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 2) # 2 = IndoorOutdoor
|
||||
elif attribute == 0x0004 # ---------- SupportsConcurrentConnection / bool ----------
|
||||
return tlv_solo.set(0x08 #-TLV.BOOL-#, false) # false - maybe can set to true
|
||||
end
|
||||
@@ -964,7 +964,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
var ip6 = eth.add_array(6) # IPv6Addresses
|
||||
ip6.add_TLV(nil, 0x10 #-TLV.B1-#, matter.get_ip_bytes(tas_eth.find("ip6local", "")))
|
||||
ip6.add_TLV(nil, 0x10 #-TLV.B1-#, matter.get_ip_bytes(tas_eth.find("ip6", "")))
|
||||
eth.add_TLV(7, 0x04 #-TLV.U1-#, 2) # InterfaceType, p646
|
||||
eth.add_TLV(7, 0x06 #-TLV.U4-#, 2) # InterfaceType, p646
|
||||
end
|
||||
|
||||
var tas_wif = tasmota.wifi()
|
||||
@@ -981,11 +981,11 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
var ip6 = wif.add_array(6) # IPv6Addresses
|
||||
ip6.add_TLV(nil, 0x10 #-TLV.B1-#, matter.get_ip_bytes(tas_wif.find("ip6local", "")))
|
||||
ip6.add_TLV(nil, 0x10 #-TLV.B1-#, matter.get_ip_bytes(tas_wif.find("ip6", "")))
|
||||
wif.add_TLV(7, 0x04 #-TLV.U1-#, 1) # InterfaceType, p646
|
||||
wif.add_TLV(7, 0x06 #-TLV.U4-#, 1) # InterfaceType, p646
|
||||
end
|
||||
return nwi
|
||||
elif attribute == 0x0001 # ---------- RebootCount u16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, tasmota.cmd("Status 1", true)['StatusPRM']['BootCount'])
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, tasmota.cmd("Status 1", true)['StatusPRM']['BootCount'])
|
||||
elif attribute == 0x0002 # ---------- UpTime u16 ----------
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, tasmota.cmd("Status 11", true)['StatusSTS']['UptimeSec'])
|
||||
# TODO add later other attributes
|
||||
@@ -1008,7 +1008,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
var epoch_us = (int64(unix_time) - int64(946684800 #-self.MATTER_EPOCH_OFFSET-#)) * int64(1000000)
|
||||
return tlv_solo.set(0x07 #-TLV.U8-#, epoch_us)
|
||||
elif attribute == 0x0001 # ---------- Granularity / enum ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 3) # MillisecondsGranularity (NTP every hour, i.e. 36ms max drift)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 3) # MillisecondsGranularity (NTP every hour, i.e. 36ms max drift)
|
||||
# TODO add some missing args
|
||||
elif attribute == 0x0007 # ---------- LocalTime / epoch_us ----------
|
||||
var unix_time = tasmota.rtc('local')
|
||||
@@ -1033,7 +1033,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
var nocs = nocl.add_struct(nil)
|
||||
nocs.add_TLV(1, 0x11 #-TLV.B2-#, loc_fabric.get_noc()) # NOC
|
||||
nocs.add_TLV(2, 0x11 #-TLV.B2-#, loc_fabric.get_icac()) # ICAC
|
||||
nocs.add_TLV(0xFE, 0x05 #-TLV.U2-#, loc_fabric.get_fabric_index()) # Label
|
||||
nocs.add_TLV(0xFE, 0x06 #-TLV.U4-#, loc_fabric.get_fabric_index()) # Label
|
||||
end
|
||||
return nocl
|
||||
elif attribute == 0x0001 # ---------- Fabrics / list[FabricDescriptorStruct] ----------
|
||||
@@ -1045,24 +1045,24 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
var root_ca_tlv = TLV.parse(loc_fabric.get_ca())
|
||||
var fab = fabrics.add_struct(nil) # encoding see p.303
|
||||
fab.add_TLV(1, 0x11 #-TLV.B2-#, root_ca_tlv.findsubval(9)) # RootPublicKey
|
||||
fab.add_TLV(2, 0x05 #-TLV.U2-#, loc_fabric.get_admin_vendor()) # VendorID
|
||||
fab.add_TLV(2, 0x06 #-TLV.U4-#, loc_fabric.get_admin_vendor()) # VendorID
|
||||
fab.add_TLV(3, 0x07 #-TLV.U8-#, loc_fabric.get_fabric_id_as_int64()) # FabricID
|
||||
fab.add_TLV(4, 0x07 #-TLV.U8-#, loc_fabric.get_device_id_as_int64()) # NodeID
|
||||
fab.add_TLV(5, 0x0C #-TLV.UTF1-#, loc_fabric.get_fabric_label()) # Label
|
||||
fab.add_TLV(0xFE, 0x05 #-TLV.U2-#, loc_fabric.get_fabric_index()) # idx
|
||||
fab.add_TLV(0xFE, 0x06 #-TLV.U4-#, loc_fabric.get_fabric_index()) # idx
|
||||
end
|
||||
return fabrics
|
||||
elif attribute == 0x0002 # ---------- SupportedFabrics / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, matter.Fabric._MAX_CASE) # Max 5 fabrics
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, matter.Fabric._MAX_CASE) # Max 5 fabrics
|
||||
elif attribute == 0x0003 # ---------- CommissionedFabrics / u1 ----------
|
||||
var fabric_actice = self.device.sessions.count_active_fabrics()
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, fabric_actice) # number of active fabrics
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, fabric_actice) # number of active fabrics
|
||||
elif attribute == 0x0004 # ---------- TrustedRootCertificates / list[octstr] ----------
|
||||
# TODO
|
||||
elif attribute == 0x0005 # ---------- Current FabricIndex / u1 ----------
|
||||
var fab_index = session._fabric.get_fabric_index()
|
||||
if fab_index == nil fab_index = 0 end # if PASE session, then the fabric index should be zero
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, fab_index) # number of active sessions
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, fab_index) # number of active sessions
|
||||
end
|
||||
|
||||
# ====================================================================================================
|
||||
@@ -1071,16 +1071,16 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
var commissioning_open = self.device.commissioning.is_commissioning_open()
|
||||
var basic_commissioning = self.device.commissioning.is_root_commissioning_open()
|
||||
var val = commissioning_open ? (basic_commissioning ? 2 #-BasicWindowOpen-# : 1 #-EnhancedWindowOpen-#) : 0 #-WindowNotOpen-#
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, val)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, val)
|
||||
elif attribute == 0x0001 # ---------- AdminFabricIndex / u16 ----------
|
||||
var admin_fabric = self.device.commissioning.commissioning_admin_fabric
|
||||
if admin_fabric != nil
|
||||
return tlv_solo.set_or_nil(0x05 #-TLV.U2-#, admin_fabric.get_fabric_index())
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, admin_fabric.get_fabric_index())
|
||||
end
|
||||
elif attribute == 0x0002 # ---------- AdminVendorId / u16 ----------
|
||||
var admin_fabric = self.device.commissioning.commissioning_admin_fabric
|
||||
if admin_fabric != nil
|
||||
return tlv_solo.set_or_nil(0x05 #-TLV.U2-#, admin_fabric.get_admin_vendor())
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, admin_fabric.get_admin_vendor())
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1089,21 +1089,21 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
self.ack_request(ctx) # long operation, send Ack first
|
||||
|
||||
if attribute == 0x0000 # ---------- DataModelRevision ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 21) # Matter 1.6.1 data model
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 21) # Matter 1.6.1 data model
|
||||
elif attribute == 0x0001 # ---------- VendorName / string ----------
|
||||
return tlv_solo.set(0x0C #-TLV.UTF1-#, "Tasmota")
|
||||
elif attribute == 0x0002 # ---------- VendorID / vendor-id ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, self.device.VENDOR_ID) # Vendor ID reserved for development
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.device.VENDOR_ID) # Vendor ID reserved for development
|
||||
elif attribute == 0x0003 # ---------- ProductName / string ----------
|
||||
return tlv_solo.set(0x0C #-TLV.UTF1-#, tasmota.cmd("DeviceName", true)['DeviceName'])
|
||||
elif attribute == 0x0004 # ---------- ProductID / u16 (opt) ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 32768) # taken from esp-matter example
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 32768) # taken from esp-matter example
|
||||
elif attribute == 0x0005 # ---------- NodeLabel / string ----------
|
||||
return tlv_solo.set(0x0C #-TLV.UTF1-#, tasmota.cmd("FriendlyName", true)['FriendlyName1'])
|
||||
elif attribute == 0x0006 # ---------- Location / string ----------
|
||||
return tlv_solo.set(0x0C #-TLV.UTF1-#, "XX") # no location
|
||||
elif attribute == 0x0007 # ---------- HardwareVersion / u16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
elif attribute == 0x0008 # ---------- HardwareVersionString / string ----------
|
||||
return tlv_solo.set(0x0C #-TLV.UTF1-#, tasmota.cmd("Status 2", true)['StatusFWR']['Hardware'])
|
||||
elif attribute == 0x0009 # ---------- SoftwareVersion / u32 ----------
|
||||
@@ -1121,17 +1121,17 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
return tlv_solo.set(0x0C #-TLV.UTF1-#, tasmota.wifi().find("mac", ""))
|
||||
elif attribute == 0x0013 # ---------- CapabilityMinima / CapabilityMinimaStruct ----------
|
||||
var cps = TLV.Matter_TLV_struct()
|
||||
cps.add_TLV(0, 0x05 #-TLV.U2-#, 3) # CaseSessionsPerFabric = 3
|
||||
cps.add_TLV(1, 0x05 #-TLV.U2-#, 3) # SubscriptionsPerFabric = 3
|
||||
cps.add_TLV(2, 0x05 #-TLV.U2-#, 1) # SimultaneousInvocationsSupported
|
||||
cps.add_TLV(3, 0x05 #-TLV.U2-#, 1) # SimultaneousWritesSupported
|
||||
cps.add_TLV(4, 0x05 #-TLV.U2-#, 9) # ReadPathsSupported
|
||||
cps.add_TLV(5, 0x05 #-TLV.U2-#, 3) # SubscribePathsSupported
|
||||
cps.add_TLV(0, 0x06 #-TLV.U4-#, 3) # CaseSessionsPerFabric = 3
|
||||
cps.add_TLV(1, 0x06 #-TLV.U4-#, 3) # SubscriptionsPerFabric = 3
|
||||
cps.add_TLV(2, 0x06 #-TLV.U4-#, 1) # SimultaneousInvocationsSupported
|
||||
cps.add_TLV(3, 0x06 #-TLV.U4-#, 1) # SimultaneousWritesSupported
|
||||
cps.add_TLV(4, 0x06 #-TLV.U4-#, 9) # ReadPathsSupported
|
||||
cps.add_TLV(5, 0x06 #-TLV.U4-#, 3) # SubscribePathsSupported
|
||||
return cps
|
||||
elif attribute == 0x0015 # ---------- SpecificationVersion / uint32 ----------
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0x01060100) # Matter 1.6.1.0
|
||||
elif attribute == 0x0016 # ---------- MaxPathsPerInvoke / uint16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 1)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 1)
|
||||
elif attribute == 0x0018 # ---------- ConfigurationVersion / uint32 ----------
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.device.configuration_version)
|
||||
end
|
||||
@@ -1142,11 +1142,11 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
if attribute == 0x0000 # ---------- ACL / list[AccessControlEntryStruct] ----------
|
||||
return self.fixed_acl_to_tlv(session.get_fabric())
|
||||
elif attribute == 0x0002 # ---------- SubjectsPerAccessControlEntry / uint16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 4) # spec minimum
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 4) # spec minimum
|
||||
elif attribute == 0x0003 # ---------- TargetsPerAccessControlEntry / uint16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 3) # spec minimum
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 3) # spec minimum
|
||||
elif attribute == 0x0004 # ---------- AccessControlEntriesPerFabric / uint16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 1) # one fixed wildcard entry
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 1) # one fixed wildcard entry
|
||||
end
|
||||
|
||||
# ====================================================================================================
|
||||
@@ -1161,9 +1161,9 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
elif attribute == 0x0002 # ---------- MaxGroupsPerFabric / uint16 ----------
|
||||
# Groups remains discoverable for unicast compatibility, but group
|
||||
# provisioning is fail-closed until encrypted multicast receive exists.
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, self.device.GROUP_TRANSPORT_READY ? 4 : 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.device.GROUP_TRANSPORT_READY ? 4 : 0)
|
||||
elif attribute == 0x0003 # ---------- MaxGroupKeysPerFabric / uint16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 3) # spec minimum
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 3) # spec minimum
|
||||
elif attribute == 0xFFF8 # ---------- GeneratedCommandList ----------
|
||||
var generated = TLV.Matter_TLV_array()
|
||||
generated.add_TLV(nil, 0x06 #-TLV.U4-#, 0x0002) # KeySetReadResponse
|
||||
@@ -1186,7 +1186,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
elif attribute == 0x0001 # ---------- UpdatePossible / bool ----------
|
||||
return tlv_solo.set(0x08 #-TLV.BOOL-#, 0) # we claim that update is not possible, would require to go to Tasmota UI
|
||||
elif attribute == 0x0002 # ---------- UpdateState / UpdateStateEnum ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 1) # Idle
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 1) # Idle
|
||||
elif attribute == 0x0003 # ---------- UpdateStateProgress / uint8 ----------
|
||||
return tlv_solo.set(0x14 #-TLV.NULL-#, nil) # null, nothing in process
|
||||
end
|
||||
@@ -1206,12 +1206,12 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
elif cluster == 0x002C # ========== Time Format Localization Cluster 11.4 p.581 ==========
|
||||
|
||||
if attribute == 0x0000 # ---------- HourFormat / HourFormat ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 1) # 1 = 24hr
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 1) # 1 = 24hr
|
||||
elif attribute == 0x0001 # ---------- ActiveCalendarType / CalendarType ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 4) # 4 = Gregorian
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 4) # 4 = Gregorian
|
||||
elif attribute == 0x0002 # ---------- SupportedCalendarTypes / list[CalendarType] ----------
|
||||
var callist = TLV.Matter_TLV_array()
|
||||
callist.add_TLV(nil, TLV.create_TLV(0x04 #-TLV.U1-#, 4))
|
||||
callist.add_TLV(nil, 0x06 #-TLV.U4-#, 4) # 4 = Gregorian
|
||||
return callist
|
||||
end
|
||||
|
||||
@@ -1221,13 +1221,13 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
if attribute == 0x0000 # ---------- TemperatureUnit / TempUnitEnum ----------
|
||||
# 0=Fahrenheit, 1=Celsius, 2=Kelvin
|
||||
# SetOption8: 0=Celsius, 1=Fahrenheit -> Matter: 0=Fahrenheit, 1=Celsius (inverted)
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, tasmota.get_option(8) ? 0 : 1)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, tasmota.get_option(8) ? 0 : 1)
|
||||
end
|
||||
|
||||
# ====================================================================================================
|
||||
elif cluster == 0x0031 # ========== Network Commissioning Cluster cluster 11.8 p.606 ==========
|
||||
if attribute == 0x0003 # ---------- ConnectMaxTimeSeconds / uint8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 30) # 30 - value taking from example in esp-matter
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 30) # 30 - value taking from example in esp-matter
|
||||
end
|
||||
|
||||
elif cluster == 0x001D # ========== Descriptor Cluster 9.5 p.453 ==========
|
||||
@@ -1236,7 +1236,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
if attribute == 0x0002 # ---------- ClientList / list[cluster-id] ----------
|
||||
var pl = TLV.Matter_TLV_array()
|
||||
# from connectedhome reference implementation
|
||||
pl.add_TLV(nil, 0x05 #-TLV.U2-#, 0x001F) # Access Control Cluster
|
||||
pl.add_TLV(nil, 0x06 #-TLV.U4-#, 0x001F) # Access Control Cluster
|
||||
return pl
|
||||
# overwrite PartsList
|
||||
elif attribute == 0x0003 # ---------- PartsList / list[endpoint-no]----------
|
||||
@@ -1246,7 +1246,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
for ep: eps
|
||||
# if bridge mode is disabled, don't announce Aggregatore (above 0xFF00)
|
||||
if !disable_bridge_mode || ep != 0x0001 #-matter.AGGREGATOR_ENDPOINT-#
|
||||
pl.add_TLV(nil, 0x05 #-TLV.U2-#, ep) # add each endpoint
|
||||
pl.add_TLV(nil, 0x06 #-TLV.U4-#, ep) # add each endpoint
|
||||
end
|
||||
end
|
||||
return pl
|
||||
@@ -1270,7 +1270,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 300)
|
||||
elif attribute == 0x0002 # ---------- ActiveModeThreshold / uint16 (milliseconds) ----------
|
||||
# For always-on WiFi device: 300ms (spec default)
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 300)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 300)
|
||||
# Note: attributes 0x0003-0x0005 require CIP feature (Check-In Protocol)
|
||||
# Note: attribute 0x0008 (OperatingMode) requires LITS feature (Long Idle Time Support)
|
||||
# We don't implement CIP or LITS since this is an always-on WiFi device
|
||||
@@ -1302,7 +1302,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
session._breadcrumb = Breadcrumb
|
||||
|
||||
var afsr = TLV.Matter_TLV_struct()
|
||||
afsr.add_TLV(0, 0x04 #-TLV.U1-#, 0) # ErrorCode = OK
|
||||
afsr.add_TLV(0, 0x06 #-TLV.U4-#, 0) # ErrorCode = OK
|
||||
afsr.add_TLV(1, 0x0C #-TLV.UTF1-#, "") # DebugText = ""
|
||||
ctx.command = 0x01 # ArmFailSafeResponse
|
||||
return afsr
|
||||
@@ -1317,7 +1317,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
# 0=ErrorCode (OK=0)
|
||||
# 1=DebugText
|
||||
var srcr = TLV.Matter_TLV_struct()
|
||||
srcr.add_TLV(0, 0x04 #-TLV.U1-#, 0) # ErrorCode = OK
|
||||
srcr.add_TLV(0, 0x06 #-TLV.U4-#, 0) # ErrorCode = OK
|
||||
srcr.add_TLV(1, 0x0C #-TLV.UTF1-#, "") # DebugText = ""
|
||||
ctx.command = 0x03 # SetRegulatoryConfigResponse
|
||||
return srcr
|
||||
@@ -1336,7 +1336,7 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
# 0=ErrorCode (OK=0)
|
||||
# 1=DebugText
|
||||
var ccr = TLV.Matter_TLV_struct()
|
||||
ccr.add_TLV(0, 0x04 #-TLV.U1-#, 0) # ErrorCode = OK
|
||||
ccr.add_TLV(0, 0x06 #-TLV.U4-#, 0) # ErrorCode = OK
|
||||
ccr.add_TLV(1, 0x0C #-TLV.UTF1-#, "") # DebugText = ""
|
||||
ctx.command = 0x05 # CommissioningCompleteResponse
|
||||
|
||||
@@ -1505,8 +1505,8 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
# 1=FabricIndex (1-254) (opt)
|
||||
# 2=DebugText (opt)
|
||||
var nocr = TLV.Matter_TLV_struct()
|
||||
nocr.add_TLV(0, 0x04 #-TLV.U1-#, 0x00 #-matter.SUCCESS-#) # Status
|
||||
nocr.add_TLV(1, 0x04 #-TLV.U1-#, new_fabric.get_fabric_index()) # fabric-index
|
||||
nocr.add_TLV(0, 0x06 #-TLV.U4-#, 0x00 #-matter.SUCCESS-#) # Status
|
||||
nocr.add_TLV(1, 0x06 #-TLV.U4-#, new_fabric.get_fabric_index()) # fabric-index
|
||||
ctx.command = 0x08 # NOCResponse
|
||||
return nocr
|
||||
|
||||
@@ -1520,8 +1520,8 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
# 1=FabricIndex (1-254) (opt)
|
||||
# 2=DebugText (opt)
|
||||
var nocr = TLV.Matter_TLV_struct()
|
||||
nocr.add_TLV(0, 0x04 #-TLV.U1-#, 0x00 #-matter.SUCCESS-#) # Status
|
||||
nocr.add_TLV(1, 0x04 #-TLV.U1-#, session.get_fabric().get_fabric_index()) # fabric-index
|
||||
nocr.add_TLV(0, 0x06 #-TLV.U4-#, 0x00 #-matter.SUCCESS-#) # Status
|
||||
nocr.add_TLV(1, 0x06 #-TLV.U4-#, session.get_fabric().get_fabric_index()) # fabric-index
|
||||
ctx.command = 0x08 # NOCResponse
|
||||
return nocr
|
||||
|
||||
@@ -1541,8 +1541,8 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
# 1=FabricIndex (1-254) (opt)
|
||||
# 2=DebugText (opt)
|
||||
var nocr = TLV.Matter_TLV_struct()
|
||||
nocr.add_TLV(0, 0x04 #-TLV.U1-#, 0x00 #-matter.SUCCESS-#) # Status
|
||||
nocr.add_TLV(1, 0x04 #-TLV.U1-#, index) # fabric-index
|
||||
nocr.add_TLV(0, 0x06 #-TLV.U4-#, 0x00 #-matter.SUCCESS-#) # Status
|
||||
nocr.add_TLV(1, 0x06 #-TLV.U4-#, index) # fabric-index
|
||||
ctx.command = 0x08 # NOCResponse
|
||||
return nocr
|
||||
end
|
||||
@@ -1660,9 +1660,9 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
elif command == 0x0004 # ---------- KeySetReadAllIndices ----------
|
||||
var response = TLV.Matter_TLV_struct()
|
||||
var indices = response.add_array(0)
|
||||
indices.add_TLV(nil, 0x05 #-TLV.U2-#, 0) # operational IPK key set
|
||||
indices.add_TLV(nil, 0x06 #-TLV.U4-#, 0) # operational IPK key set
|
||||
for key_set : fabric.get_group_key_sets()
|
||||
indices.add_TLV(nil, 0x05 #-TLV.U2-#, key_set.find("id"))
|
||||
indices.add_TLV(nil, 0x06 #-TLV.U4-#, key_set.find("id"))
|
||||
end
|
||||
ctx.command = 0x0005 # KeySetReadAllIndicesResponse
|
||||
return response
|
||||
@@ -1685,9 +1685,9 @@ class Matter_Plugin_Root : Matter_Plugin
|
||||
tasmota.delay(1000)
|
||||
|
||||
var ncresp = TLV.Matter_TLV_struct()
|
||||
ncresp.add_TLV(0, 0x04 #-TLV.U1-#, 0x00 #-matter.SUCCESS-#) # NetworkCommissioningStatusEnum
|
||||
ncresp.add_TLV(0, 0x06 #-TLV.U4-#, 0x00 #-matter.SUCCESS-#) # NetworkCommissioningStatusEnum
|
||||
ncresp.add_TLV(1, 0x0D #-TLV.UTF2-#, tasmota.wifi().tostring()) # DebugText
|
||||
ncresp.add_TLV(2, 0x04 #-TLV.U1-#, 1) # NetworkIndex
|
||||
ncresp.add_TLV(2, 0x06 #-TLV.U4-#, 1) # NetworkIndex
|
||||
ctx.command = 0x05 # NetworkConfigResponse
|
||||
return ncresp
|
||||
|
||||
|
||||
@@ -230,13 +230,13 @@ class Matter_Plugin_Fan : Matter_Plugin_Device
|
||||
if cluster == 0x0202 # ========== Fan ==========
|
||||
self.update_shadow_lazy()
|
||||
if attribute == 0x0000 # ---------- FanMode / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, self.shadow_fan_mode)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.shadow_fan_mode)
|
||||
elif attribute == 0x0001 # ---------- FanModeSequence / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 2) # Off/Low/Med/High/Auto
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 2) # Off/Low/Med/High/Auto
|
||||
elif attribute == 0x0002 # ---------- PercentSetting / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, self.shadow_fan_speed_pct)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.shadow_fan_speed_pct)
|
||||
elif attribute == 0x0003 # ---------- PercentSetting / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, self.shadow_fan_speed_pct)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.shadow_fan_speed_pct)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -220,9 +220,9 @@ class Matter_Plugin_Light0 : Matter_Plugin_Device
|
||||
elif attribute == 0x4000 # ---------- GlobalSceneControl / bool ----------
|
||||
return tlv_solo.set(0x08 #-TLV.BOOL-#, true)
|
||||
elif attribute == 0x4001 # ---------- OnTime / u2 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
elif attribute == 0x4002 # ---------- OffWaitTime / u2 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
elif attribute == 0x4003 # ---------- StartUpOnOff / enum8 nullable ----------
|
||||
return tlv_solo.set(0x14 #-TLV.NULL-#, nil)
|
||||
end
|
||||
|
||||
@@ -393,9 +393,9 @@ class Matter_Plugin_Sensor_Air_Quality : Matter_Plugin_Device
|
||||
elif attribute == 0x0002 # ---------- MaxMeasured Value / float ----------
|
||||
return tlv_solo.set(0x14 #-TLV.NULL-#, nil)
|
||||
elif attribute == 0x0008 # ---------- MeasurementUnit / u8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, unit)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, unit)
|
||||
elif attribute == 0x0009 # ---------- MeasurementMedium / u8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0) # 0 = Air
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) # 0 = Air
|
||||
elif attribute == 0xFFFC # ---------- FeatureMap / map32 ----------
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 1) # MEA = NumericMeasurement
|
||||
end
|
||||
@@ -405,7 +405,7 @@ class Matter_Plugin_Sensor_Air_Quality : Matter_Plugin_Device
|
||||
# ====================================================================================================
|
||||
if cluster == 0x005B # ========== Air Quality ==========
|
||||
if attribute == 0x0000 # ---------- AirQuality / U8 ----------
|
||||
return tlv_solo.set_or_nil(0x04 #-TLV.U1-#, self.shadow_air_quality)
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, self.shadow_air_quality)
|
||||
# elif attribute == 0xFFFC # ---------- FeatureMap / map32 ----------
|
||||
# return tlv_solo.set(0x06 #-TLV.U4-#, 0) #
|
||||
end
|
||||
|
||||
@@ -171,11 +171,11 @@ class Matter_Plugin_Sensor_GenericSwitch_Btn : Matter_Plugin_Device
|
||||
if cluster == 0x003B # ========== Generic Switch, 1.12 ==========
|
||||
# self.update_shadow_lazy()
|
||||
if attribute == 0x0000 # ---------- NumberOfPositions / uint8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 2) # default to 2 positions
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 2) # default to 2 positions
|
||||
elif attribute == 0x0001 # ---------- CurrentPosition / uint8 ----------
|
||||
return tlv_solo.set_or_nil(0x04 #-TLV.U1-#, self.shadow_position)
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, self.shadow_position)
|
||||
elif attribute == 0x0002 # ---------- MultiPressMax / uint8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 5) # up to penta press
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 5) # up to penta press
|
||||
|
||||
elif attribute == 0xFFFC # ---------- FeatureMap / map32 ----------
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0x16 #-0x02 | 0x04 | 0x10-#) # MomentarySwitch + MomentarySwitchRelease + MomentarySwitchMultiPress
|
||||
@@ -214,19 +214,19 @@ class Matter_Plugin_Sensor_GenericSwitch_Btn : Matter_Plugin_Device
|
||||
# publish event for (mode==1), InitialPress and ShortRelease
|
||||
if (mode == 1)
|
||||
if state # InitialPress
|
||||
self.publish_event(0x003B, 0x01, 1 #-matter.EVENT_INFO-#, matter.TLV.Matter_TLV_item().set(0x04 #-matter.TLV.U1-#, 1)) # InitialPress, position hardcoded to 1
|
||||
self.publish_event(0x003B, 0x01, 1 #-matter.EVENT_INFO-#, matter.TLV.Matter_TLV_item().set(0x06 #-matter.TLV.U4-#, 1)) # InitialPress, position hardcoded to 1
|
||||
else
|
||||
self.publish_event(0x003B, 0x03, 1 #-matter.EVENT_INFO-#, matter.TLV.Matter_TLV_item().set(0x04 #-matter.TLV.U1-#, 1)) # ShortRelease, previous position hardcoded to 1
|
||||
self.publish_event(0x003B, 0x03, 1 #-matter.EVENT_INFO-#, matter.TLV.Matter_TLV_item().set(0x06 #-matter.TLV.U4-#, 1)) # ShortRelease, previous position hardcoded to 1
|
||||
end
|
||||
# check if there is an ungoing multi-press
|
||||
if (state == 1) && (press_counter > 0)
|
||||
# MultiPressOngoing
|
||||
self.publish_event(0x003B, 0x05, 1 #-matter.EVENT_INFO-#, matter.TLV.Matter_TLV_item().set(0x04 #-matter.TLV.U1-#, 1),
|
||||
matter.TLV.Matter_TLV_item().set(0x04 #-matter.TLV.U1-#, press_counter + 1)) # MultiPressCom plete
|
||||
self.publish_event(0x003B, 0x05, 1 #-matter.EVENT_INFO-#, matter.TLV.Matter_TLV_item().set(0x06 #-matter.TLV.U4-#, 1),
|
||||
matter.TLV.Matter_TLV_item().set(0x06 #-matter.TLV.U4-#, press_counter + 1)) # MultiPressCom plete
|
||||
end
|
||||
elif (mode == 2) && (press_counter > 0) # Multipress
|
||||
self.publish_event(0x003B, 0x06, 1 #-matter.EVENT_INFO-#, matter.TLV.Matter_TLV_item().set(0x04 #-matter.TLV.U1-#, 1),
|
||||
matter.TLV.Matter_TLV_item().set(0x04 #-matter.TLV.U1-#, press_counter)) # MultiPressCom plete
|
||||
self.publish_event(0x003B, 0x06, 1 #-matter.EVENT_INFO-#, matter.TLV.Matter_TLV_item().set(0x06 #-matter.TLV.U4-#, 1),
|
||||
matter.TLV.Matter_TLV_item().set(0x06 #-matter.TLV.U4-#, press_counter)) # MultiPressCom plete
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -221,13 +221,13 @@ class Matter_Plugin_Shutter : Matter_Plugin_Device
|
||||
self.update_shadow_lazy()
|
||||
self.update_inverted()
|
||||
if attribute == 0x0000 # ---------- Type / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0xFF) # 0xFF = unknown type of shutter
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0xFF) # 0xFF = unknown type of shutter
|
||||
elif attribute == 0x0005 # ---------- NumberOfActuationsLift / u16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
elif attribute == 0x0007 # ---------- ConfigStatus / u8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 1 + 8) # Operational + Lift Position Aware
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 1 + 8) # Operational + Lift Position Aware
|
||||
elif attribute == 0x000D # ---------- EndProductType / u8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0xFF) # 0xFF = unknown type of shutter
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0xFF) # 0xFF = unknown type of shutter
|
||||
elif attribute == 0x000E # ---------- CurrentPositionLiftPercent100ths / u16 ----------
|
||||
if self.shadow_shutter_pos != nil
|
||||
if self.shadow_shutter_inverted == 0
|
||||
@@ -236,13 +236,13 @@ class Matter_Plugin_Shutter : Matter_Plugin_Device
|
||||
matter_position = self.shadow_shutter_pos * 100
|
||||
end
|
||||
end
|
||||
return tlv_solo.set_or_nil(0x05 #-TLV.U2-#, matter_position)
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, matter_position)
|
||||
elif attribute == 0x000A # ---------- OperationalStatus / u8 ----------
|
||||
var op
|
||||
if self.shadow_shutter_direction != nil
|
||||
op = self.shadow_shutter_direction == 0 ? 0 : (self.shadow_shutter_direction > 0 ? 1 : 2)
|
||||
end
|
||||
return tlv_solo.set_or_nil(0x04 #-TLV.U1-#, op)
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, op)
|
||||
elif attribute == 0x000B # ---------- TargetPositionLiftPercent100ths / u16 ----------
|
||||
if self.shadow_shutter_target != nil
|
||||
if self.shadow_shutter_inverted == 0
|
||||
@@ -251,10 +251,10 @@ class Matter_Plugin_Shutter : Matter_Plugin_Device
|
||||
matter_position = self.shadow_shutter_target * 100
|
||||
end
|
||||
end
|
||||
return tlv_solo.set_or_nil(0x05 #-TLV.U2-#, matter_position)
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, matter_position)
|
||||
|
||||
elif attribute == 0x0017 # ---------- Mode / u8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0) # normal mode
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) # normal mode
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -157,18 +157,18 @@ class Matter_Plugin_Thermostat : Matter_Plugin_Device
|
||||
if self.shadow_local_temperature == nil
|
||||
return tlv_solo.set(0x14 #-TLV.NULL-#, nil)
|
||||
else
|
||||
return tlv_solo.set(0x01 #-TLV.I2-#, self.shadow_local_temperature)
|
||||
return tlv_solo.set(0x02 #-TLV.I4-#, self.shadow_local_temperature)
|
||||
end
|
||||
elif attribute == 0x0011 # OccupiedCoolingSetpoint / int16
|
||||
return tlv_solo.set(0x01 #-TLV.I2-#, self.shadow_cooling_setpoint)
|
||||
return tlv_solo.set(0x02 #-TLV.I4-#, self.shadow_cooling_setpoint)
|
||||
elif attribute == 0x0012 # OccupiedHeatingSetpoint / int16
|
||||
return tlv_solo.set(0x01 #-TLV.I2-#, self.shadow_heating_setpoint)
|
||||
return tlv_solo.set(0x02 #-TLV.I4-#, self.shadow_heating_setpoint)
|
||||
elif attribute == 0x001B # ControlSequenceOfOperation / enum8
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 4) # Cooling and heating
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 4) # Cooling and heating
|
||||
elif attribute == 0x001C # SystemMode / enum8
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, self.shadow_system_mode)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.shadow_system_mode)
|
||||
elif attribute == 0x0029 # ThermostatRunningState / bitmap16
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, self.shadow_running_state)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.shadow_running_state)
|
||||
end
|
||||
end
|
||||
return super(self).read_attribute(session, ctx, tlv_solo)
|
||||
|
||||
@@ -272,15 +272,15 @@ class Matter_Plugin_Light1 : Matter_Plugin_Light0
|
||||
if cluster == 0x0008 # ========== Level Control 1.6 p.57 ==========
|
||||
self.update_shadow_lazy()
|
||||
if attribute == 0x0000 # ---------- CurrentLevel / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, self.shadow_bri)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.shadow_bri)
|
||||
elif attribute == 0x0002 # ---------- MinLevel / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
elif attribute == 0x0003 # ---------- MaxLevel / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 254)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 254)
|
||||
elif attribute == 0x000F # ---------- Options / map8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0) #
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) #
|
||||
elif attribute == 0x0011 # ---------- OnLevel / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, self.shadow_bri)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.shadow_bri)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -238,7 +238,7 @@ class Matter_Plugin_OnOff_Power : Matter_Plugin_OnOff
|
||||
]
|
||||
for s: specs
|
||||
var e = acc.add_struct()
|
||||
e.add_TLV(0, 0x04 #-TLV.U1-#, s[0]) # MeasurementType
|
||||
e.add_TLV(0, 0x06 #-TLV.U4-#, s[0]) # MeasurementType
|
||||
e.add_TLV(1, 0x08 #-TLV.BOOL-#, true) # Measured
|
||||
e.add_TLV(2, 0x03 #-TLV.I8-#, s[1]) # MinMeasuredValue
|
||||
e.add_TLV(3, 0x03 #-TLV.I8-#, s[2]) # MaxMeasuredValue
|
||||
@@ -246,7 +246,7 @@ class Matter_Plugin_OnOff_Power : Matter_Plugin_OnOff
|
||||
var r = ranges.add_struct()
|
||||
r.add_TLV(0, 0x03 #-TLV.I8-#, s[1]) # RangeMin
|
||||
r.add_TLV(1, 0x03 #-TLV.I8-#, s[2]) # RangeMax
|
||||
r.add_TLV(2, 0x05 #-TLV.U2-#, 500) # PercentMax = 5.00%
|
||||
r.add_TLV(2, 0x06 #-TLV.U4-#, 500) # PercentMax = 5.00%
|
||||
end
|
||||
return acc
|
||||
end
|
||||
@@ -261,9 +261,9 @@ class Matter_Plugin_OnOff_Power : Matter_Plugin_OnOff
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0090 # ========== Electrical Power Measurement 2.13 ==========
|
||||
if attribute == 0x0000 # ---------- PowerMode / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 2) # AC
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 2) # AC
|
||||
elif attribute == 0x0001 # ---------- NumberOfMeasurementTypes / u8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 8)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 8)
|
||||
elif attribute == 0x0002 # ---------- Accuracy / list[MeasurementAccuracyStruct] ----------
|
||||
return self._build_accuracy_list()
|
||||
elif attribute == 0x0008 # ---------- ActivePower / i64 (mW) ----------
|
||||
|
||||
@@ -124,11 +124,11 @@ class Matter_Plugin_Sensor_Flow : Matter_Plugin_Sensor
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0404 # ========== Flow Measurement 2.4 p.98 ==========
|
||||
if attribute == 0x0000 # ---------- MeasuredValue / i16 ----------
|
||||
return tlv_solo.set_or_nil(0x05 #-TLV.U2-#, int(self.shadow_value)) # MeasuredValue represents 10 x flow in m3/h.
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, int(self.shadow_value)) # MeasuredValue represents 10 x flow in m3/h.
|
||||
elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0) # 0 m3/h
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) # 0 m3/h
|
||||
elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 65534) # 65534 m3/h
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 65534) # 65534 m3/h
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -133,11 +133,11 @@ class Matter_Plugin_Sensor_Humidity : Matter_Plugin_Sensor
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0405 # ========== Humidity Measurement 2.4 p.98 ==========
|
||||
if attribute == 0x0000 # ---------- Humidity / u16 ----------
|
||||
return tlv_solo.set_or_nil(0x05 #-TLV.U2-#, int(self.shadow_value))
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, int(self.shadow_value))
|
||||
elif attribute == 0x0001 # ---------- MinMeasuredValue / u16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 500) # 0%
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 500) # 0%
|
||||
elif attribute == 0x0002 # ---------- MaxMeasuredValue / u16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 10000) # 100%
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 10000) # 100%
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -150,11 +150,11 @@ class Matter_Plugin_Sensor_Illuminance : Matter_Plugin_Sensor
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0400 # ========== Illuminance Measurement 2.2 p.95 ==========
|
||||
if attribute == 0x0000 # ---------- MeasuredValue / i16 ----------
|
||||
return tlv_solo.set_or_nil(0x05 #-TLV.U2-#, int(self.shadow_value))
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, int(self.shadow_value))
|
||||
elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 1) # 1 lux
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 1) # 1 lux
|
||||
elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0xFFFE)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0xFFFE)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -154,11 +154,11 @@ class Matter_Plugin_Sensor_Occupancy : Matter_Plugin_Sensor_Boolean
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0406 # ========== Occupancy Sensing ==========
|
||||
if attribute == 0x0000 # ---------- Occupancy / U8 ----------
|
||||
return tlv_solo.set_or_nil(0x04 #-TLV.U1-#, self.shadow_bool_value)
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, self.shadow_bool_value)
|
||||
elif attribute == 0x0001 # ---------- OccupancySensorType / enum8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 3) # physical contact
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 3) # physical contact
|
||||
elif attribute == 0x0002 # ---------- OccupancySensorTypeBitmap / u8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0) # unknown
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0) # unknown
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -135,11 +135,11 @@ class Matter_Plugin_Sensor_Pressure : Matter_Plugin_Sensor
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0403 # ========== Pressure Measurement 2.4 p.98 ==========
|
||||
if attribute == 0x0000 # ---------- MeasuredValue / i16 ----------
|
||||
return tlv_solo.set_or_nil(0x01 #-TLV.I2-#, int(self.shadow_value))
|
||||
return tlv_solo.set_or_nil(0x02 #-TLV.I4-#, int(self.shadow_value))
|
||||
elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 ----------
|
||||
return tlv_solo.set(0x01 #-TLV.I2-#, 500) # 500 hPA
|
||||
return tlv_solo.set(0x02 #-TLV.I4-#, 500) # 500 hPA
|
||||
elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 ----------
|
||||
return tlv_solo.set(0x01 #-TLV.I2-#, 1500) # 1500 hPA
|
||||
return tlv_solo.set(0x02 #-TLV.I4-#, 1500) # 1500 hPA
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -143,11 +143,11 @@ class Matter_Plugin_Sensor_Temp : Matter_Plugin_Sensor
|
||||
# ====================================================================================================
|
||||
if cluster == 0x0402 # ========== Temperature Measurement 2.3 p.97 ==========
|
||||
if attribute == 0x0000 # ---------- MeasuredValue / i16 (*100) ----------
|
||||
return tlv_solo.set_or_nil(0x01 #-TLV.I2-#, self.shadow_value)
|
||||
return tlv_solo.set_or_nil(0x02 #-TLV.I4-#, self.shadow_value)
|
||||
elif attribute == 0x0001 # ---------- MinMeasuredValue / i16 (*100) ----------
|
||||
return tlv_solo.set(0x01 #-TLV.I2-#, -5000) # -50 °C
|
||||
return tlv_solo.set(0x02 #-TLV.I4-#, -5000) # -50 °C
|
||||
elif attribute == 0x0002 # ---------- MaxMeasuredValue / i16 (*100) ----------
|
||||
return tlv_solo.set(0x01 #-TLV.I2-#, 15000) # 150 °C
|
||||
return tlv_solo.set(0x02 #-TLV.I4-#, 15000) # 150 °C
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -194,20 +194,20 @@ class Matter_Plugin_ShutterTilt : Matter_Plugin_Shutter
|
||||
if cluster == 0x0102 # ========== Window Covering 5.3 p.289 ==========
|
||||
self.update_shadow_lazy()
|
||||
if attribute == 0x0007 # ---------- ConfigStatus / u8 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 1 + 8 + 16) # Operational + Lift Position Aware + Tilt Position Aware
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 1 + 8 + 16) # Operational + Lift Position Aware + Tilt Position Aware
|
||||
|
||||
elif attribute == 0x000F # ---------- CurrentPositionTiltPercent100ths / u8 ----------
|
||||
self.update_tilt_min_max()
|
||||
if self.tilt_min != nil && self.tilt_max != nil
|
||||
var tilt_percentage = tasmota.scale_uint(self.shadow_shutter_tilt - self.tilt_min, 0, self.tilt_max - self.tilt_min, 0, 10000)
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, tilt_percentage)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, tilt_percentage)
|
||||
else
|
||||
return tlv_solo.set(0x14 #-TLV.NULL-#, nil) # return invalid
|
||||
end
|
||||
elif attribute == 0x000C # ---------- TargetPositionTiltPercent100ths / u16 ----------
|
||||
if self.tilt_min != nil && self.tilt_max != nil
|
||||
var tilt_percentage = tasmota.scale_uint(self.shadow_shutter_tilt - self.tilt_min, 0, self.tilt_max - self.tilt_min, 0, 10000)
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, tilt_percentage)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, tilt_percentage)
|
||||
else
|
||||
return tlv_solo.set(0x14 #-TLV.NULL-#, nil) # return invalid
|
||||
end
|
||||
|
||||
@@ -212,23 +212,23 @@ class Matter_Plugin_Light2 : Matter_Plugin_Light1
|
||||
if cluster == 0x0300 # ========== Color Control 3.2 p.111 ==========
|
||||
self.update_shadow_lazy()
|
||||
if attribute == 0x0007 # ---------- ColorTemperatureMireds / u2 ----------
|
||||
return tlv_solo.set_or_nil(0x05 #-TLV.U2-#, self.shadow_ct) # if `nil` it is replaced with 0x14 #-TLV.NULL-#
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, self.shadow_ct) # if `nil` it is replaced with 0x14 #-TLV.NULL-#
|
||||
elif attribute == 0x0008 # ---------- ColorMode / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 2) # 2 = ColorTemperatureMireds
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 2) # 2 = ColorTemperatureMireds
|
||||
elif attribute == 0x000F # ---------- Options / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
elif attribute == 0x4001 # ---------- EnhancedColorMode / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 2) # 2 = ColorTemperatureMireds
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 2) # 2 = ColorTemperatureMireds
|
||||
elif attribute == 0x400A # ---------- ColorCapabilities / map2 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0x10) # CT
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0x10) # CT
|
||||
elif attribute == 0x400B # ---------- ColorTempPhysicalMinMireds / u2 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, self.ct_min)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.ct_min)
|
||||
elif attribute == 0x400C # ---------- ColorTempPhysicalMaxMireds / u2 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, self.ct_max)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, self.ct_max)
|
||||
|
||||
# Defined Primaries Information Attribute Set
|
||||
elif attribute == 0x0010 # ---------- NumberOfPrimaries / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
|
||||
elif attribute == 0xFFFC # ---------- FeatureMap / map32 ----------
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0x10) # CT
|
||||
|
||||
@@ -234,21 +234,21 @@ class Matter_Plugin_Light3 : Matter_Plugin_Light1
|
||||
if cluster == 0x0300 # ========== Color Control 3.2 p.111 ==========
|
||||
self.update_shadow_lazy()
|
||||
if attribute == 0x0000 # ---------- CurrentHue / u1 ----------
|
||||
return tlv_solo.set_or_nil(0x04 #-TLV.U1-#, self.shadow_hue)
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, self.shadow_hue)
|
||||
elif attribute == 0x0001 # ---------- CurrentSaturation / u2 ----------
|
||||
return tlv_solo.set_or_nil(0x04 #-TLV.U1-#, self.shadow_sat)
|
||||
return tlv_solo.set_or_nil(0x06 #-TLV.U4-#, self.shadow_sat)
|
||||
elif attribute == 0x0008 # ---------- ColorMode / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0)# 0 = CurrentHue and CurrentSaturation
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)# 0 = CurrentHue and CurrentSaturation
|
||||
elif attribute == 0x000F # ---------- Options / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
elif attribute == 0x4001 # ---------- EnhancedColorMode / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
elif attribute == 0x400A # ---------- ColorCapabilities / map2 ----------
|
||||
return tlv_solo.set(0x05 #-TLV.U2-#, 0x01) # HS
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0x01) # HS
|
||||
|
||||
# Defined Primaries Information Attribute Set
|
||||
elif attribute == 0x0010 # ---------- NumberOfPrimaries / u1 ----------
|
||||
return tlv_solo.set(0x04 #-TLV.U1-#, 0)
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0)
|
||||
|
||||
elif attribute == 0xFFFC # ---------- FeatureMap / map32 ----------
|
||||
return tlv_solo.set(0x06 #-TLV.U4-#, 0x01) # HS
|
||||
|
||||
@@ -149,7 +149,7 @@ class Matter_Plugin_Virt_HVAC : Matter_Plugin_Thermostat
|
||||
var parts = TLV.Matter_TLV_array()
|
||||
for pl: self.device.plugins
|
||||
if pl.TYPE == "v_hvac_option" && pl.hvac_ep == self.endpoint
|
||||
parts.add_TLV(nil, 0x05 #-TLV.U2-#, pl.endpoint)
|
||||
parts.add_TLV(nil, 0x06 #-TLV.U4-#, pl.endpoint)
|
||||
end
|
||||
end
|
||||
return parts
|
||||
|
||||
@@ -51,6 +51,8 @@ class Matter_TLV
|
||||
# :----|:---
|
||||
# I1 I2 I4|Signed integer of at most (1/2/4) bytes (as 32 bits signed Berry type)
|
||||
# U1 U2 U4|Unsiged integer of at motst (1/2/4) bytes (as 32 bits signed Berry type, be careful when comparing. Use `matter.Counter.is_greater(a,b)`)
|
||||
# |Convention: encode all signed ints with I4 (0x02) and all unsigned ints with U4 (0x06);
|
||||
# |the encoder shrinks them to the smallest width. I1/I2/U1/U2 are never widened and truncate out-of-range values.
|
||||
# I8 U8|Signed/insigned 8 bytes. You can pass `bytes(8)`, `int64()` or `int`. Type is collapsed to a lower type if possible when encoding.
|
||||
# BOOL|boolean, takes `true` and `false`. Abstracts the internal `BTRUE` and `BFALSE` that you don't need to use
|
||||
# FLOAT|32 bites float
|
||||
|
||||
@@ -174,7 +174,7 @@ class Matter_Device_BLE : Matter_Device
|
||||
|
||||
var cnresp = TLV.Matter_TLV_struct()
|
||||
if r == "Successful"
|
||||
cnresp.add_TLV(0, 0x04 #-TLV.U1-#, 0x00 #-SUCCESS-#)
|
||||
cnresp.add_TLV(0, 0x06 #-TLV.U4-#, 0x00 #-SUCCESS-#)
|
||||
cnresp.add_TLV(1, 0x0D #-TLV.UTF2-#, format("ip6=%s", tasmota.wifi()['ip6local']))
|
||||
log("MTR: ConnectNetwork deferred -> Successful", 2)
|
||||
global.matter_device.start()
|
||||
@@ -193,7 +193,7 @@ class Matter_Device_BLE : Matter_Device
|
||||
end
|
||||
end
|
||||
else
|
||||
cnresp.add_TLV(0, 0x04 #-TLV.U1-#, 0x01 #-FAILURE-#)
|
||||
cnresp.add_TLV(0, 0x06 #-TLV.U4-#, 0x01 #-FAILURE-#)
|
||||
cnresp.add_TLV(1, 0x0D #-TLV.UTF2-#, format("wifi connect failed: %s", r))
|
||||
log(f"MTR: ConnectNetwork deferred -> Failed: {r}", 2)
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user