Skip to content

Commit

Permalink
Add function to dump cluster IDs for documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
cecille committed Mar 27, 2024
1 parent f7db85e commit c36485a
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 10 deletions.
118 changes: 118 additions & 0 deletions docs/cluster_ids.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Matter Cluster IDs
This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.py`. DO NOT EDIT BY HAND!

| ID (Decimal) | ID (hex) | Name |
|--------------|----------|----------------------------------------------------------|
|3 |0x0003 |Identify |
|4 |0x0004 |Groups |
|6 |0x0006 |On/Off |
|8 |0x0008 |Level Control |
|28 |0x001C |Pulse Width Modulation |
|29 |0x001D |Descriptor |
|30 |0x001E |Binding |
|31 |0x001F |AccessControl |
|37 |0x0025 |Actions |
|40 |0x0028 |Basic Information |
|41 |0x0029 |OTA Software Update Provider |
|42 |0x002A |OTA Software Update Requestor |
|43 |0x002B |Localization Configuration |
|44 |0x002C |Time Format Localization |
|45 |0x002D |Unit Localization |
|46 |0x002E |Power Source Configuration |
|47 |0x002F |Power Source |
|48 |0x0030 |General Commissioning |
|49 |0x0031 |Network Commissioning |
|50 |0x0032 |Diagnostic Logs |
|51 |0x0033 |General Diagnostics |
|52 |0x0034 |Software Diagnostics |
|53 |0x0035 |Thread Network Diagnostics |
|54 |0x0036 |Wi |
|55 |0x0037 |Ethernet Network Diagnostics |
|56 |0x0038 |Time Synchronization |
|57 |0x0039 |Bridged Device Basic Information |
|59 |0x003B |Switch |
|60 |0x003C |Administrator Commissioning |
|62 |0x003E |Operational Credentials |
|63 |0x003F |GroupKeyManagement |
|64 |0x0040 |Fixed Label |
|65 |0x0041 |User Label |
|69 |0x0045 |Boolean State |
|70 |0x0046 |ICDManagement |
|72 |0x0048 |Oven Cavity Operational State |
|73 |0x0049 |Oven Mode |
|74 |0x004A |Laundry Dryer Controls |
|80 |0x0050 |Mode Select |
|81 |0x0051 |Laundry Washer Mode |
|82 |0x0052 |Refrigerator And Temperature Controlled Cabinet Mode |
|83 |0x0053 |Laundry Washer Controls |
|84 |0x0054 |RVC Run Mode |
|85 |0x0055 |RVC Clean Mode |
|86 |0x0056 |Temperature Control |
|87 |0x0057 |Refrigerator Alarm |
|89 |0x0059 |Dishwasher Mode |
|91 |0x005B |Air Quality |
|92 |0x005C |Smoke CO Alarm |
|93 |0x005D |Dishwasher Alarm |
|94 |0x005E |Microwave Oven Mode |
|95 |0x005F |Microwave Oven Control |
|96 |0x0060 |Operational State |
|97 |0x0061 |RVC Operational State |
|98 |0x0062 |Scenes Management |
|113 |0x0071 |HEPA Filter Monitoring |
|114 |0x0072 |Activated Carbon Filter Monitoring |
|128 |0x0080 |Boolean State Configuration |
|129 |0x0081 |Valve Configuration and Control |
|144 |0x0090 |Electrical Power Measurement |
|145 |0x0091 |Electrical Energy Measurement |
|148 |0x0094 |Water Heater Management |
|149 |0x0095 |Energy Price |
|150 |0x0096 |Demand Response and Load Control |
|151 |0x0097 |Messages |
|152 |0x0098 |Device Energy Management |
|153 |0x0099 |Energy EVSE |
|154 |0x009A |Energy Calendar |
|155 |0x009B |Energy Preference |
|156 |0x009C |Power Topology |
|157 |0x009D |Energy EVSE Mode |
|158 |0x009E |Water Heater Mode |
|159 |0x009F |Device Energy Management Mode |
|257 |0x0101 |Door Lock |
|258 |0x0102 |Window Covering |
|512 |0x0200 |Pump Configuration and Control |
|513 |0x0201 |Thermostat |
|514 |0x0202 |Fan Control |
|516 |0x0204 |Thermostat User Interface Configuration |
|768 |0x0300 |Color Control |
|769 |0x0301 |Ballast Configuration |
|1024 |0x0400 |Illuminance Measurement |
|1026 |0x0402 |Temperature Measurement |
|1027 |0x0403 |Pressure Measurement |
|1028 |0x0404 |Flow Measurement |
|1029 |0x0405 |Relative Humidity Measurement |
|1030 |0x0406 |Occupancy Sensing |
|1036 |0x040C |Carbon Monoxide Concentration Measurement |
|1037 |0x040D |Carbon Dioxide Concentration Measurement |
|1043 |0x0413 |Nitrogen Dioxide Concentration Measurement |
|1045 |0x0415 |Ozone Concentration Measurement |
|1066 |0x042A |PM2 |
|1067 |0x042B |Formaldehyde Concentration Measurement |
|1068 |0x042C |PM1 Concentration Measurement |
|1069 |0x042D |PM10 Concentration Measurement |
|1070 |0x042E |Total Volatile Organic Compounds Concentration Measurement|
|1071 |0x042F |Radon Concentration Measurement |
|1104 |0x0450 |Network Identity Management |
|1105 |0x0451 |Wi |
|1283 |0x0503 |Wake on LAN |
|1284 |0x0504 |Channel |
|1285 |0x0505 |Target Navigator |
|1286 |0x0506 |Media Playback |
|1287 |0x0507 |Media Input |
|1288 |0x0508 |Low Power |
|1289 |0x0509 |Keypad Input |
|1290 |0x050A |Content Launcher |
|1291 |0x050B |Audio Output |
|1292 |0x050C |Application Launcher |
|1293 |0x050D |Application Basic |
|1294 |0x050E |Account Login |
|1295 |0x050F |Content Control |
|1296 |0x0510 |Content App Observer |
67 changes: 57 additions & 10 deletions scripts/spec_xml/generate_spec_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@
import os
import re
import subprocess
import sys

import click

DEFAULT_CHIP_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
DEFAULT_OUTPUT_DIR = os.path.abspath(os.path.join(DEFAULT_CHIP_ROOT, 'data_model'))
DEFAULT_CHIP_ROOT = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..'))
DEFAULT_OUTPUT_DIR = os.path.abspath(
os.path.join(DEFAULT_CHIP_ROOT, 'data_model'))
DEFAULT_DOCUMENTATION_DIR = os.path.abspath(
os.path.join(DEFAULT_CHIP_ROOT, 'docs', 'cluster_ids.md'))


def get_xml_path(filename, output_dir):
Expand Down Expand Up @@ -56,14 +61,17 @@ def main(scraper, spec_root, output_dir, dry_run):
scrape_device_types(scraper, spec_root, output_dir, dry_run)
if not dry_run:
dump_versions(scraper, spec_root, output_dir)
dump_cluster_ids(output_dir)


def scrape_clusters(scraper, spec_root, output_dir, dry_run):
src_dir = os.path.abspath(os.path.join(spec_root, 'src'))
sdm_clusters_dir = os.path.abspath(os.path.join(src_dir, 'service_device_management'))
sdm_clusters_dir = os.path.abspath(
os.path.join(src_dir, 'service_device_management'))
app_clusters_dir = os.path.abspath(os.path.join(src_dir, 'app_clusters'))
dm_clusters_dir = os.path.abspath(os.path.join(src_dir, 'data_model'))
media_clusters_dir = os.path.abspath(os.path.join(app_clusters_dir, 'media'))
media_clusters_dir = os.path.abspath(
os.path.join(app_clusters_dir, 'media'))
clusters_output_dir = os.path.abspath(os.path.join(output_dir, 'clusters'))
dm_clusters_list = ['ACL-Cluster.adoc', 'Binding-Cluster.adoc', 'bridge-clusters.adoc',
'Descriptor-Cluster.adoc', 'Group-Key-Management-Cluster.adoc', 'ICDManagement.adoc',
Expand All @@ -79,7 +87,8 @@ def scrape_clusters(scraper, spec_root, output_dir, dry_run):

def scrape_cluster(filename: str) -> None:
xml_path = get_xml_path(filename, clusters_output_dir)
cmd = [scraper, 'cluster', '-i', filename, '-o', xml_path, '-nd', '--define', 'in-progress']
cmd = [scraper, 'cluster', '-i', filename, '-o',
xml_path, '-nd', '--define', 'in-progress']
if dry_run:
print(cmd)
else:
Expand All @@ -100,16 +109,19 @@ def scrape_all_clusters(dir: str, exclude_list: list[str] = []) -> None:


def scrape_device_types(scraper, spec_root, output_dir, dry_run):
device_type_dir = os.path.abspath(os.path.join(spec_root, 'src', 'device_types'))
device_types_output_dir = os.path.abspath(os.path.join(output_dir, 'device_types'))
device_type_dir = os.path.abspath(
os.path.join(spec_root, 'src', 'device_types'))
device_types_output_dir = os.path.abspath(
os.path.join(output_dir, 'device_types'))
clusters_output_dir = os.path.abspath(os.path.join(output_dir, 'clusters'))

if not os.path.exists(device_types_output_dir):
os.makedirs(device_types_output_dir)

def scrape_device_type(filename: str) -> None:
xml_path = get_xml_path(filename, device_types_output_dir)
cmd = [scraper, 'devicetype', '-c', clusters_output_dir, '-nd', '-i', filename, '-o', xml_path]
cmd = [scraper, 'devicetype', '-c', clusters_output_dir,
'-nd', '-i', filename, '-o', xml_path]
if dry_run:
print(cmd)
else:
Expand All @@ -125,17 +137,52 @@ def scrape_device_type(filename: str) -> None:

def dump_versions(scraper, spec_root, output_dir):
sha_file = os.path.abspath(os.path.join(output_dir, 'spec_sha'))
out = subprocess.run(['git', 'rev-parse', 'HEAD'], capture_output=True, encoding="utf8", cwd=spec_root)
out = subprocess.run(['git', 'rev-parse', 'HEAD'],
capture_output=True, encoding="utf8", cwd=spec_root)
sha = out.stdout
with open(sha_file, 'wt', encoding='utf8') as output:
output.write(sha)

scraper_file = os.path.abspath(os.path.join(output_dir, 'scraper_version'))
out = subprocess.run([scraper, '--version'], capture_output=True, encoding="utf8")
out = subprocess.run([scraper, '--version'],
capture_output=True, encoding="utf8")
version = out.stdout
with open(scraper_file, "wt", encoding='utf8') as output:
output.write(version)


def dump_cluster_ids(output_dir):
python_testing_path = os.path.abspath(
os.path.join(DEFAULT_CHIP_ROOT, 'src', 'python_testing'))
sys.path.insert(0, python_testing_path)
clusters_output_dir = os.path.abspath(os.path.join(output_dir, 'clusters'))
device_types_output_dir = os.path.abspath(
os.path.join(output_dir, 'device_types'))

from spec_parsing_support import build_xml_clusters

header = '# Matter Cluster IDs\n'
header += 'This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.py`. DO NOT EDIT BY HAND!\n\n'

clusters, problems = build_xml_clusters()
all_name_lens = [len(c.name) for c in clusters.values()]
name_len = max(all_name_lens)
title_id_decimal = ' ID (Decimal) '
title_id_hex = ' ID (hex) '
title_name_raw = ' Name '
title_name = f'{title_name_raw:<{name_len}}'
dec_len = len(title_id_decimal)
hex_len = len(title_id_hex)
title = f'|{title_id_decimal}|{title_id_hex}|{title_name}|\n'
hashes = f'|{"-" * dec_len}|{"-" * hex_len}|{"-" * name_len}|\n'
s = title + hashes
for id, cluster in sorted(clusters.items()):
hex_id = f'0x{id:04X}'
s += f'|{id:<{dec_len}}|{hex_id:<{hex_len}}|{cluster.name:<{name_len}}|\n'
with open(DEFAULT_DOCUMENTATION_DIR, 'w') as fout:
fout.write(header)
fout.write(s)


if __name__ == '__main__':
main()

0 comments on commit c36485a

Please sign in to comment.