More missing attributes

This commit is contained in:
Scott Shawcroft 2024-10-22 11:19:31 -07:00
parent 0a8b706903
commit 2ed0fec614
No known key found for this signature in database
8 changed files with 80 additions and 29 deletions

View file

@ -81,7 +81,12 @@ class CircuitMatter:
self._endpoints = {}
self._next_endpoint = 0
self.root_node = RootNode(
random_source, self.mdns_server, self.UDP_PORT, vendor_id, product_id
random_source,
self.mdns_server,
self.UDP_PORT,
vendor_id,
product_id,
version=__version__,
)
self.add_device(self.root_node)

View file

@ -3,4 +3,4 @@ from circuitmatter import data_model
class GeneralDiagnosticsCluster(data_model.Cluster):
CLUSTER_ID = 0x0033
REVISION = 2
cluster_revision = 2

View file

@ -41,25 +41,42 @@ class ColorMode(data_model.Enum8):
class ColorControl(data_model.Cluster):
CLUSTER_ID = 0x0300
REVISION = 6
cluster_revision = 6
CurrentHue = data_model.NumberAttribute(0x0000, signed=False, bits=8, default=0)
CurrentSaturation = data_model.NumberAttribute(
current_hue = data_model.NumberAttribute(0x0000, signed=False, bits=8, default=0)
current_saturation = data_model.NumberAttribute(
0x0001, signed=False, bits=8, default=0
)
RemainingTime = data_model.NumberAttribute(0x0002, signed=False, bits=16, default=0)
CurrentX = data_model.NumberAttribute(0x0003, signed=False, bits=16, default=0)
CurrentY = data_model.NumberAttribute(0x0004, signed=False, bits=16, default=0)
DriftCompensation = data_model.NumberAttribute(
remaining_time = data_model.NumberAttribute(
0x0002, signed=False, bits=16, default=0
)
current_x = data_model.NumberAttribute(0x0003, signed=False, bits=16, default=0)
current_y = data_model.NumberAttribute(0x0004, signed=False, bits=16, default=0)
drift_compensation = data_model.NumberAttribute(
0x0005, signed=False, bits=8, default=0
)
CompensationText = data_model.UTF8StringAttribute(0x0006, default="")
ColorTemperature = data_model.NumberAttribute(
compensation_text = data_model.UTF8StringAttribute(0x0006, default="")
color_temperature = data_model.NumberAttribute(
0x0007, signed=False, bits=16, default=0
)
ColorMode = data_model.EnumAttribute(0x0008, data_model.Enum8, default=0)
Options = data_model.BitmapAttribute(0x000F, OptionsBitmap, default=0)
ColorCapabilities = data_model.BitmapAttribute(0x400A, FeatureBitmap, default=0)
color_mode = data_model.EnumAttribute(0x0008, data_model.Enum8, default=0)
options = data_model.BitmapAttribute(0x000F, OptionsBitmap, default=0)
color_capabilities = data_model.BitmapAttribute(0x400A, FeatureBitmap, default=0)
color_temp_physical_min_mireds = data_model.NumberAttribute(
0x400B,
signed=False,
bits=16,
default=0,
feature=FeatureBitmap.COLOR_TEMPERATURE,
) # maximum=0xfeff
color_temp_physical_max_mireds = data_model.NumberAttribute(
0x400C,
signed=False,
bits=16,
default=0xFEFF,
feature=FeatureBitmap.COLOR_TEMPERATURE,
) # maximum=0xfeff
class MoveToHue(tlv.Structure):
Hue = tlv.IntMember(0, signed=False, octets=1, maximum=254)

View file

@ -4,7 +4,7 @@ from circuitmatter import tlv
class BindingCluster(data_model.Cluster):
CLUSTER_ID = 0x001E
REVISION = 1
cluster_revision = 1
class TargetStruct(tlv.Structure):
Node = data_model.NodeId(1, optional=True)

View file

@ -4,7 +4,7 @@ from circuitmatter import tlv
class UserLabelCluster(data_model.Cluster):
CLUSTER_ID = 0x0041
REVISION = 1
cluster_revision = 1
class LabelStruct(tlv.Structure):
Label = tlv.UTF8StringMember(0, 16, default="")

View file

@ -57,6 +57,18 @@ class ClusterId(Uint16):
pass
class AttributeId(Uint16):
pass
class EventId(Uint16):
pass
class CommandId(Uint16):
pass
class DeviceTypeId(Uint32):
pass
@ -302,13 +314,30 @@ class Command:
class Cluster:
cluster_revision = NumberAttribute(0xFFFD, signed=False, bits=12, default=1)
feature_map = NumberAttribute(0xFFFC, signed=False, bits=32, default=0)
attribute_list = ListAttribute(0xFFFB, AttributeId())
event_list = ListAttribute(0xFFFA, EventId())
accepted_command_list = ListAttribute(0xFFF9, CommandId())
generated_command_list = ListAttribute(0xFFF8, CommandId())
def __init__(self):
self._attribute_values = {}
# Use random since this isn't for security or replayability.
self.data_version = random.randint(0, 0xFFFFFFFF)
self.attribute_list = []
for _, descriptor in self._attributes():
self.attribute_list.append(descriptor.id)
self.accepted_command_list = []
self.generated_command_list = []
self.event_list = []
for _, descriptor in self._commands():
self.accepted_command_list.append(descriptor.command_id)
if descriptor.response_id is not None:
self.generated_command_list.append(descriptor.response_id)
def __contains__(self, descriptor_id):
return descriptor_id in self._attribute_values
@ -372,7 +401,7 @@ class Cluster:
if path.Attribute is not None:
break
if not replies:
print("not found", path.Attribute)
print(f"\033[91mnot found 0x{path.Attribute:04x}\033[0m")
return replies
def set_attribute(

View file

@ -425,14 +425,24 @@ class RootNode(simple_device.SimpleDevice):
DEVICE_TYPE_ID = 0x0011
REVISION = 2
def __init__(self, random_source, mdns_server, port, vendor_id, product_id):
def __init__(
self,
random_source,
mdns_server,
port,
vendor_id,
product_id,
version="",
serial_number="1234",
):
super().__init__("root")
basic_info = BasicInformationCluster()
basic_info.vendor_id = vendor_id
basic_info.product_id = product_id
basic_info.product_name = "CircuitMatter"
basic_info.serial_number = "1234"
basic_info.serial_number = serial_number
basic_info.software_version_string = version
self.servers.append(basic_info)
access_control = AccessControlCluster()
self.servers.append(access_control)

View file

@ -4,7 +4,6 @@ import subprocess
class Avahi:
def __init__(self):
self.active_services = {}
self.publish_address = None
def advertise_service(
self,
@ -26,16 +25,7 @@ class Avahi:
*txt_records,
]
self.active_services[service_type + instance_name] = subprocess.Popen(command)
if self.publish_address is None:
command = [
"avahi-publish-address",
"dalinar.local",
"fd98:bbab:bd61:8040:642:1aff:fe0c:9f2a", # "fe80::642:1aff:fe0c:9f2a",
]
self.publish_address = subprocess.Popen(command)
def __del__(self):
for active_service in self.active_services.values():
active_service.kill()
if self.publish_address is not None:
self.publish_address.kill()