diff --git a/chip-testing/src/AllClustersTestInstance.ts b/chip-testing/src/AllClustersTestInstance.ts index eebccb23ec..2ef46c264e 100644 --- a/chip-testing/src/AllClustersTestInstance.ts +++ b/chip-testing/src/AllClustersTestInstance.ts @@ -399,7 +399,7 @@ export class AllClustersTestInstance extends NodeTestInstance { levelValue: ConcentrationMeasurement.LevelValue.Critical, }, colorControl: { - coupleColorTempToLevelMinMireds: 0, + coupleColorTempToLevelMinMireds: 1, remainingTime: 0, driftCompensation: 0, compensationText: "foo", diff --git a/chip-testing/test/core/BINFO.test.ts b/chip-testing/test/core/BINFO.test.ts index 0283034480..377bb57519 100644 --- a/chip-testing/test/core/BINFO.test.ts +++ b/chip-testing/test/core/BINFO.test.ts @@ -5,22 +5,21 @@ */ import { OccurrenceManager } from "@matter/main/protocol"; -import { edit } from "@matter/testing"; import { NodeTestInstance } from "../../src/NodeTestInstance.js"; describe("BINFO", () => { - // TODO - remove when we're on 1.4 - before(() => - chip - .testFor("BINFO/2.1") - .edit( - edit.sed( - "s/value: 18/value: 17/", - "s/minValue: 0x01040000/minValue: 0x01030000/", - "s/maxValue: 0x0104FF00/maxValue: 0x0103FF00/", - ), - ), - ); + // When CHIP moves to a newer protocol that we don't support we can move CHIP's version back here + // before(() => + // chip + // .testFor("BINFO/2.1") + // .edit( + // edit.sed( + // "s/value: 18/value: 17/", + // "s/minValue: 0x01040000/minValue: 0x01030000/", + // "s/maxValue: 0x0104FF00/maxValue: 0x0103FF00/", + // ), + // ), + // ); chip("BINFO/*").exclude("BINFO/2.2"); diff --git a/chip-testing/test/core/BRBINFO.test.ts b/chip-testing/test/core/BRBINFO.test.ts index 69359da159..328378e37c 100644 --- a/chip-testing/test/core/BRBINFO.test.ts +++ b/chip-testing/test/core/BRBINFO.test.ts @@ -4,6 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { BridgeApp } from "../support.js"; + describe("BRBINFO", () => { - chip("BRBINFO/*").exclude("BRBINFO/4.1"); // Exclude ICD; test doesn't specify PICS + chip("BRBINFO/*").subject(BridgeApp).exclude("BRBINFO/4.1"); // Exclude ICD; test doesn't specify PICS }); diff --git a/chip-testing/test/core/CADMIN.test.ts b/chip-testing/test/core/CADMIN.test.ts index edf732e23b..3995336336 100644 --- a/chip-testing/test/core/CADMIN.test.ts +++ b/chip-testing/test/core/CADMIN.test.ts @@ -22,7 +22,7 @@ describe("CADMIN", () => { //before(() => chip.testFor("CADMIN/1.19").edit(edit.sed("s/0x0000000B/0x00000587/"))); // TODO - temporarily disabled other tests while working out 1.19 issues - //chip("CADMIN/*").exclude("CADMIN/1.19"); + chip("CADMIN/*").exclude("CADMIN/1.19"); // TODO - need to resolve issues w/ 1.19 chip("CADMIN/1.19").beforeTest(subject => { diff --git a/chip-testing/test/core/SC.test.ts b/chip-testing/test/core/SC.test.ts index 6310cf74e0..534012c6b0 100644 --- a/chip-testing/test/core/SC.test.ts +++ b/chip-testing/test/core/SC.test.ts @@ -38,7 +38,7 @@ describe("SC", () => { }); // Exclude 5.1 and 5.2 because our GroupKeyManagement is too limited - //chip("SC/*").exclude("SC/5.1", "SC/5.2", "SC/7.1"); + chip("SC/*").exclude("SC/5.1", "SC/5.2", "SC/7.1"); // 7.1 must start factory fresh chip("SC/7.1").uncommissioned(); diff --git a/chip/Dockerfile b/chip/Dockerfile index 351f2f55c9..d3b62c7ec6 100644 --- a/chip/Dockerfile +++ b/chip/Dockerfile @@ -162,3 +162,6 @@ RUN mkdir /run/dbus # Summarize tests for efficient metadata load at runtime COPY generate-test-descriptor /bin/generate-test-descriptor RUN generate-test-descriptor > /lib/test-descriptor.json + +# Include CHIP SHA for diagnostic purposes +COPY --from=build /connectedhomeip/.git/refs/heads/master /etc/chip-version diff --git a/codegen/src/clusters/GeneratorScope.ts b/codegen/src/clusters/GeneratorScope.ts index 5c659a8f72..cfb31e38da 100644 --- a/codegen/src/clusters/GeneratorScope.ts +++ b/codegen/src/clusters/GeneratorScope.ts @@ -46,8 +46,9 @@ export interface GeneratorScope { * * @param model the model to name * @param tlv structs have both Name and TlvName defined; this selects the latter + * @param specific if true retrieves the name for this specific model rather than any canonical override */ - nameFor(model: Model, tlv?: boolean): string; + nameFor(model: Model, tlv?: boolean, specific?: boolean): string; /** * Obtain the location of a model's definition. @@ -55,8 +56,9 @@ export interface GeneratorScope { * Throws an error if the model is not referenced in this scope. * * @param model the model whose location we load + * @param specific if true retrieves the name for this specific model rather than any canonical override */ - locationOf(model: Model): GeneratorScope.Location; + locationOf(model: Model, specific?: boolean): GeneratorScope.Location; /** * Obtain the canonical model for a definition. @@ -133,8 +135,8 @@ function allocateScope(scope: Scope): GeneratorScope { owner, scope, - nameFor(model: Model, tlv: boolean) { - const { definition: definer } = this.locationOf(model); + nameFor(model: Model, tlv: boolean, specific = false) { + const { definition: definer } = this.locationOf(model, specific); const name = names.get(definer); if (name === undefined) { throw new InternalError(`No name assigned to ${model} in scope ${owner}`); @@ -145,8 +147,11 @@ function allocateScope(scope: Scope): GeneratorScope { return name; }, - locationOf(model: Model) { - const location = locations.get(scope.modelFor(model)); + locationOf(model: Model, specific = false) { + if (!specific) { + model = scope.modelFor(model); + } + const location = locations.get(model); if (location === undefined) { throw new InternalError(`No location identified for ${model} from scope ${owner}`); } @@ -242,7 +247,7 @@ function identifyNamedModels(scope: Scope): Locations { /** * Set the location for a model and, if the model is not local, its scope */ - function define(model: Model) { + function define(model: Model, specific = false) { if (!(model instanceof ValueModel)) { return; } @@ -273,14 +278,16 @@ function identifyNamedModels(scope: Scope): Locations { return; } - const extension = scope.extensionOf(definer); - if (extension === model) { - // The model is the definer even if it doesn't provide fields of its own - definer = model; - } else if (extension) { - // Only the extension appears in the file - define(extension); - return; + if (!specific) { + const extension = scope.extensionOf(definer); + if (extension === model) { + // The model is the definer even if it doesn't provide fields of its own + definer = model; + } else if (extension) { + // Only the extension appears in the file + define(extension); + return; + } } if (locations.has(definer)) { @@ -303,12 +310,12 @@ function identifyNamedModels(scope: Scope): Locations { locations.set(definer, location); // The model is not defined locally but we need to import any subtree that references shadowed elements. - if (definer instanceof ValueModel && referencesShadows(definer)) { + if (definer instanceof ValueModel && !specific && referencesShadows(definer)) { location.isLocal = true; modelScope = owner; // Now localize any sub-references - definer.members.forEach(define); + definer.members.forEach(m => define(m)); } if (modelScope instanceof ClusterModel && modelScope !== owner) { @@ -319,6 +326,14 @@ function identifyNamedModels(scope: Scope): Locations { isGlobal: true, }); } + + // For enums any base that contributes values must be defined as well as it will be referenced in the type + if (metatype === Metatype.enum) { + const { base } = definer; + if (base && base.metatype === undefined) { + define(base, true); + } + } } /** diff --git a/codegen/src/clusters/TlvGenerator.ts b/codegen/src/clusters/TlvGenerator.ts index 98f22393e4..633dd554fe 100644 --- a/codegen/src/clusters/TlvGenerator.ts +++ b/codegen/src/clusters/TlvGenerator.ts @@ -155,10 +155,19 @@ export class TlvGenerator { case Metatype.enum: { - const dt = this.defineDatatype(model); - if (dt) { + const dts = new Set(); + for (let m = this.#scope.definingModelFor(model); m; m = m.base) { + if (!m.children.length) { + continue; + } + const dt = this.#defineSpecificDatatype(m); + if (dt !== undefined) { + dts.add(dt); + } + } + if (dts.size) { this.importTlv("number", "TlvEnum"); - tlv = `TlvEnum<${dt}>()`; + tlv = `TlvEnum<${[...dts].join(" | ")}>()`; } else { // No fields; revert to the primitive type the enum derives from tlv = this.#primitiveTlv(metabase, model); @@ -260,7 +269,7 @@ export class TlvGenerator { const enumBlock = this.definitions.expressions(`export enum ${name} {`, "}"); this.definitions.insertingBefore(enumBlock, () => { - model.members.forEach(child => { + model.children.forEach(child => { let name = child.name; if (name.match(/^\d+$/)) { // Typescript doesn't allow numeric enum keys @@ -352,14 +361,17 @@ export class TlvGenerator { defineDatatype(model: ValueModel) { // Obtain the defining model. This is the actual datatype definition const defining = this.#scope.definingModelFor(model); - if (defining) { - model = defining; - } else { + + if (!defining) { // If there's no defining model, the datatype is empty. Use either the base or the model directly for // naming. Handling of this is context specific return; } + return this.#defineSpecificDatatype(defining); + } + + #defineSpecificDatatype(model: ValueModel) { // Special case for status codes. "Status code" in door lock cluster seems to be the global status codes // instead of the local one. So always reference the global one until we see something different if (model.isGlobal && model.name === status.name && this.file.scope.owner !== model) { @@ -375,9 +387,9 @@ export class TlvGenerator { // If the model is not local, import rather than define const isObject = model.effectiveMetatype === Metatype.object; - const location = this.#scope.locationOf(model); + const location = this.#scope.locationOf(model, true); if (!location.isLocal) { - return this.#file.reference(model, isObject); + return this.#file.reference(model, isObject, true); } // If the type is already defined we reference the existing definition diff --git a/codegen/src/mom/spec/header-detection-heuristics.ts b/codegen/src/mom/spec/header-detection-heuristics.ts new file mode 100644 index 0000000000..00153f0af9 --- /dev/null +++ b/codegen/src/mom/spec/header-detection-heuristics.ts @@ -0,0 +1,19 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +export function looksLikeField(text?: string) { + return !!text?.match(/^[a-z0-9]+(?: Field| Value)$/i); +} + +export function looksLikeDatatype(text?: string) { + return !!( + text?.match(/^[a-z0-9]+(?:Enum|Struct| Attribute| Command| Event| Type| Field| Value| Bits?)$/i) || + // This is a real winner. Joint Fabric Datastore cluster in 1.4 manages to follow no convention for indicating + // these are structs *and* innovatively sticks spaces in type names. We don't add to the pattern above because + // the spaces make this pretty aggressive so we execute with case sensitivity + text?.match(/^(?:[A-Z][?:a-zA-Z0-9]* )+Entry Type$/) + ); +} diff --git a/codegen/src/mom/spec/load-clusters.ts b/codegen/src/mom/spec/load-clusters.ts index cfdf22964b..b31b0ab6cf 100644 --- a/codegen/src/mom/spec/load-clusters.ts +++ b/codegen/src/mom/spec/load-clusters.ts @@ -25,9 +25,19 @@ const GlobalTypeSections: Partial void; + /** + * The collector is active until it returns false for a section. + */ + collects(ref: HtmlReference): boolean; + + /** + * Adds a section for which the collector has asserted ownership via {@link collects}. + */ + collect(ref: HtmlReference): void; } /** @@ -56,6 +66,11 @@ export function* loadClusters(clusters: HtmlReference): Generator {}); return; } @@ -134,6 +143,21 @@ export function* loadClusters(clusters: HtmlReference): Generator void, + collects?: (ref: HtmlReference) => boolean, + ) { + if (collects === undefined) { + collects = ref => isSubsectionOf(subsection, ref); + } + collectors.push({ collect, collects }); + } + + function isSubsectionOf(section: string, ref: HtmlReference) { + return ref.xref.section.startsWith(section); + } + function clusterCollector(subref: HtmlReference) { if (definition?.type !== "cluster") { throw new InternalError(`Cluster collector invoked without an active cluster definition`); @@ -216,47 +240,53 @@ export function* loadClusters(clusters: HtmlReference): Generator { + if (!definition.datatypes) { + definition.datatypes = []; + } + datatypeRef.name = datatypeRef.name.replace(/\s+type$/i, ""); + logger.debug(`datatype ${datatypeRef.name} § ${datatypeRef.xref.section}`); + definition.datatypes.push(datatypeRef); + if (datatypeRef.tables) { + // Probably a struct, enum or bitmap. These are sometimes followed with sections that + // detail individual items + collectDetails(datatypeRef, other => { + // A field in the "datatypes" section following a datatype is a spec bug and should have been part + // of the previous section. Detect this and treat as if it is a proper subsection + if (other.name.endsWith(" Field")) { + return true; + } + if (other.prose?.[0]?.textContent?.match(/^This field /)) { + return true; + } + + return false; + }); + } }); } function collectNamespace(definition: ClusterReference, subref: HtmlReference) { - collectors.push({ - subsection: subref.xref.section, - collector(ref) { - // Only collect namespace sections that appear to have a defining table - if (!ref.tables || !ref.tables[0].fields.includes("name")) { - return; - } + collect(subref.xref.section, ref => { + // Only collect namespace sections that appear to have a defining table + if (!ref.tables || !ref.tables[0].fields.includes("name")) { + return; + } - if (!definition.namespace) { - definition.namespace = []; - } - logger.debug(`namespace section ${ref.name} § ${ref.xref.section}`); - definition.namespace.push(ref); - collectDetails(ref); - }, + if (!definition.namespace) { + definition.namespace = []; + } + logger.debug(`namespace section ${ref.name} § ${ref.xref.section}`); + definition.namespace.push(ref); + collectDetails(ref); }); } - function collectDetails(ref: HtmlReference) { - collectors.push({ - subsection: ref.detailSection ?? ref.xref.section, - collector(subref: HtmlReference) { + function collectDetails(ref: HtmlReference, memberDetector?: (ref: HtmlReference) => boolean) { + const section = ref.detailSection ?? ref.xref.section; + collect( + ref.detailSection ?? ref.xref.section, + subref => { if (!ref.details) { ref.details = []; } @@ -267,7 +297,20 @@ export function* loadClusters(clusters: HtmlReference): Generator { + const isSubsection = isSubsectionOf(section, other); + if (isSubsection) { + return true; + } + + // Support specialized detection of sections that *should* be subsections but are not + if (memberDetector?.(other)) { + return true; + } + + return false; + }, + ); } function defineElement( diff --git a/codegen/src/mom/spec/repairs/aspect-repairs.ts b/codegen/src/mom/spec/repairs/aspect-repairs.ts index 996cef85f2..6e28be052e 100644 --- a/codegen/src/mom/spec/repairs/aspect-repairs.ts +++ b/codegen/src/mom/spec/repairs/aspect-repairs.ts @@ -17,7 +17,8 @@ export function repairConstraint(record: { constraint?: string }) { .replace(/ octets| entries| bytes| per node/i, "") .replace(/ to(\d|max)/i, " to $1") .replace(/ValuetoMax/, "Value to Max") - .replace(/Sup ported/, "Supported"); + .replace(/Sup ported/, "Supported") + .replace(/N\/A/, ""); // Ignore window covering's bitmap constraints if (constraint.match(/^[0x]{4} [0x]{4}$/)) { diff --git a/codegen/src/mom/spec/repairs/cluster-html-repairs.ts b/codegen/src/mom/spec/repairs/cluster-html-repairs.ts index 314373d40d..dca9fe1ebe 100644 --- a/codegen/src/mom/spec/repairs/cluster-html-repairs.ts +++ b/codegen/src/mom/spec/repairs/cluster-html-repairs.ts @@ -4,24 +4,32 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { HtmlReference } from "../spec-types.js"; +import { InternalError } from "@matter/general"; +import { ClusterReference, GlobalReference, HtmlReference } from "../spec-types.js"; export enum ScanDirective { // Ignore section in stream IGNORE = 1, - // Treat as one-level higher than actual in stream + // Treat as one level higher than actual in stream POP = 2, + // Treat as two levels higher + POP2 = 3, + // Collect section as a "namespace" entry - NAMESPACE = 3, + NAMESPACE = 4, } const IGNORE = () => ScanDirective.IGNORE; const POP = () => ScanDirective.POP; +const POP2 = () => ScanDirective.POP2; const NAMESPACE = () => ScanDirective.NAMESPACE; -type HtmlRepairs = Record ScanDirective | void>; +type HtmlRepairs = Record< + string, + (ref: HtmlReference, ownerRef: ClusterReference | GlobalReference) => ScanDirective | void +>; export const ClusterHtmlRepairs: Record = { "General Commissioning": { @@ -66,11 +74,28 @@ export const ClusterHtmlRepairs: Record = { }, "Operational State": { - // 1.2 and 1.3 use this terminology to define a subset of the values for ErrorStateEnum. We turn into an - // independent enum - "ErrorStateEnum GeneralErrors Range"(subref) { - subref.name = "GeneralErrorStateEnum Type"; - return ScanDirective.POP; + // 1.2+ use this terminology to define a subset of the values for ErrorStateEnum. We inject the table into the + // previous section so translation picks them up + "ErrorStateEnum GeneralErrors Range"(subref, ownerRef) { + const { datatypes } = ownerRef as ClusterReference; + const datatype = datatypes?.[datatypes.length - 1]; + if (datatype?.name !== "ErrorStateEnum" || !datatype.tables || !subref.tables?.length) { + throw new InternalError("OperationalState.ErrorStateEnum definition uses unexpected format"); + } + datatype.tables[0] = subref.tables?.[0]; + return ScanDirective.IGNORE; + }, + + // These values are in the correct section but there is another table priori that describes ranges; this + // confuses translation unless we skip + "OperationalStateEnum Type"(subref) { + const tables = subref.tables; + if (tables?.length !== 2) { + return; + } + if (tables[0].rows[0]?.value?.textContent?.match(/ to /)) { + tables.splice(0, 1); + } }, }, @@ -82,17 +107,44 @@ export const ClusterHtmlRepairs: Record = { // This at a reasonable level but is a one-off. So easiest to handle here "Mode Namespace": NAMESPACE, }, + + "ICD Management": { + // ClientTypeEnum is one level too deep (1.4 core) + "9.17.5.1.1": POP, + }, + + "Service Area": { + // SelectAreaStatus and SkipAreaStatus enums are too deep (1.4 cluster) + "1.17.5.6.1": POP, + "1.17.5.6.2": POP, + }, + + "Joint Fabric Datastore": { + // This is a fake section number for a datatype that generates at the same level as a field for the previous + // datatype (1.4 core) + "11.24.5.4.7": POP2, + }, + + "Joint Fabric PKI": { + // The joint fabric guys really don't adhere to conventions. We can mostly correct automatically but in this + // case they spelled out Signing Request instead of using abbreviation SR from defining table + "11.25.4.1"(subref) { + if (subref.name === "ICAC Signing Request Status Enum Type") { + subref.name = "IcacsrRequestStatusEnum"; + } + }, + }, }; // Modify incoming stream to workaround specific spec issues -export function repairIncomingHtml(subref: HtmlReference, clusterRef: HtmlReference) { - const repairs = ClusterHtmlRepairs[clusterRef.name]; +export function repairIncomingHtml(subref: HtmlReference, ownerRef: ClusterReference | GlobalReference) { + const repairs = ClusterHtmlRepairs[ownerRef.name]; if (!repairs) { return; } const repair = repairs[subref.xref.section] ?? repairs[subref.name]; if (repair) { - return repair(subref); + return repair(subref, ownerRef); } } diff --git a/codegen/src/mom/spec/repairs/type-repairs.ts b/codegen/src/mom/spec/repairs/type-repairs.ts index 760c8dfd15..3f9c9524e1 100644 --- a/codegen/src/mom/spec/repairs/type-repairs.ts +++ b/codegen/src/mom/spec/repairs/type-repairs.ts @@ -23,6 +23,10 @@ const TYPE_ERRORS: { [badType: string]: string } = { "Time of Day": "TimeOfDay", "voltage-mW": "voltage-mV", utc: "epoch-s", + ipv4addr: "ipv4adr", + ipv6addr: "ipv6adr", + "endpoint-id": "endpoint-no", + "ModeBitmap.": "ModeBitmap", // Can't use this one because ModeSelect defines a different SemanticTagStruct //SemanticTagStruct: "semtag", @@ -33,16 +37,25 @@ export function repairTypeIdentifier(type: T): T { return type; } - if (type.startsWith("list[") && type.endsWith("]")) { - const entryType = type.slice(5, type.length - 1); + // 1.4 also started putting section identifiers in some type columns, so we end up with e.g. + // Section11.24.5.2,“DatastoreStatusEntryType”. Perhaps alchemy trying to be fancy as it tends to happen along with + // DataTypeList + type = type.replace(/Section\d+(?:\.\d+)*,“([^”]+)Type”/gi, "$1") as typeof type; + + // Grr core says list is list[...] but 1.4 decided DataTypeList[...] is good too without documenting. Possibly an + // alchemy bug + const listMatch = type.match(/^(?:list|DataTypeList)\[(.*)\]$/); + + if (listMatch) { + let entryType = listMatch[1]; if (TYPE_ERRORS[entryType]) { - return `list[${TYPE_ERRORS[entryType]}]` as T; + entryType = TYPE_ERRORS[entryType]; } - return type; + return `list[${entryType}]` as T; } - if (TYPE_ERRORS[type]) { - return TYPE_ERRORS[type] as T; + if (TYPE_ERRORS[type!]) { + return TYPE_ERRORS[type!] as T; } return type; diff --git a/codegen/src/mom/spec/scan-document.ts b/codegen/src/mom/spec/scan-document.ts index 6393194145..2b3b3e9a56 100644 --- a/codegen/src/mom/spec/scan-document.ts +++ b/codegen/src/mom/spec/scan-document.ts @@ -7,6 +7,7 @@ import { dirname, join } from "path"; import { loadHtml, parseHeading } from "./doc-utils.js"; +import { looksLikeDatatype, looksLikeField } from "./header-detection-heuristics.js"; import { Str } from "./html-translators.js"; import { scanTables } from "./scan-tables.js"; import { HtmlReference, Table } from "./spec-types.js"; @@ -127,11 +128,7 @@ export function* scanDocument(docRef: HtmlReference) { } // Sometimes there isn't even a section marker. In this case we generate the missing section number - if ( - text?.match(/^[a-z0-9]+(?: Field| Value)$/i) && - fakeSection.faking && - !fakeSection.fakingField - ) { + if (looksLikeField(text) && fakeSection.faking && !fakeSection.fakingField) { // Already faking; treat these like a sub-headings to our fake heading yield* emit(); fakeSection.subsection++; @@ -144,9 +141,7 @@ export function* scanDocument(docRef: HtmlReference) { }, }; break; - } else if ( - text?.match(/^[a-z0-9]+(?:Enum|Struct| Attribute| Command| Event| Type| Field| Value| Bits?)$/i) - ) { + } else if (looksLikeDatatype(text)) { // Looks like a section const realSection = currentRef ? currentRef.xref.section : ref.xref.section; yield* emit(); diff --git a/codegen/src/mom/spec/scan-tables.ts b/codegen/src/mom/spec/scan-tables.ts index eac3d75546..09f81dd5dc 100644 --- a/codegen/src/mom/spec/scan-tables.ts +++ b/codegen/src/mom/spec/scan-tables.ts @@ -45,15 +45,33 @@ function convertTable(el: HTMLTableElement, previous: Table | undefined) { if (table === undefined) { // Use the first row to identify whether this is a table split across page boundaries. For the spec the // first row is always replicated on subsequent pages + // + // Well, it was. In 1.4 Joint Fabric Administrator DT broke this like they break everything else by not + // using th's in their tables const firstRowIdentity = Array.from(cells) .map(cell => cell.textContent?.trim()) .join("␜"); - if (previous?.firstRowIdentity === firstRowIdentity) { + const identitiesMatch = previous?.firstRowIdentity === firstRowIdentity; + + if (identitiesMatch) { table = previous; // Skip the first row as it tells us nothing new continue; + } + + // Additional heuristic due to caveate above; this is ugly but works for now + if ( + previous && // We have a previous table + previous.fields.length === cells.length && // with the same number of columns + previous.fields.includes("id") && // with an ID + previous.fields.includes("name") && // and a name + tr.querySelectorAll("th").length === 0 // and this table has no th in first row + ) { + table = previous; + + // Do not skip this row because it holds data } else { table = { firstRowIdentity, diff --git a/codegen/src/mom/spec/translate-datatype.ts b/codegen/src/mom/spec/translate-datatype.ts index 990e5f937e..e53bd61489 100644 --- a/codegen/src/mom/spec/translate-datatype.ts +++ b/codegen/src/mom/spec/translate-datatype.ts @@ -5,7 +5,7 @@ */ import { Logger } from "#general"; -import { AnyElement, DatatypeElement, FabricIndex, FieldElement, Metatype } from "#model"; +import { AnyElement, DatatypeElement, ElementTag, FabricIndex, FieldElement, Metatype } from "#model"; import { addDocumentation } from "./add-documentation.js"; import { Bits, @@ -24,9 +24,9 @@ import { HtmlReference } from "./spec-types.js"; import { Alias, Children, + chooseIdentityAliases, Optional, TableRecord, - chooseIdentityAliases, translateRecordsToMatter, translateTable, } from "./translate-table.js"; @@ -40,9 +40,6 @@ export function translateDatatype(definition: HtmlReference): DatatypeElement | let name = repairTypeIdentifier(definition.name); const text = definition.prose?.[0] ? Str(definition.prose?.[0]) : undefined; - if (!text) { - logger.warn(`no text to search for base type`); - } // Up through 1.1 prose was informal but remarkably consistent; "derived from" always matches let match = text?.match(/derived from ([a-z0-9\-_]+)/i); @@ -106,12 +103,15 @@ export function translateDatatype(definition: HtmlReference): DatatypeElement | if (!type && name.match(/\s/)) { // This isn't actually a datatype + if (!text) { + logger.warn(`${definition.xref.document} § ${definition.xref.section} does not appear to be a datatype`); + } return; } const datatype = DatatypeElement({ type: type, - name, + name: name.replace(/\s+/g, ""), description, constraint, xref: definition.xref, @@ -168,7 +168,9 @@ export function translateFields>( return true; }); - applyAccessNotes(fields, records); + if (type.Tag !== ElementTag.Attribute) { + applyAccessNotes(fields, records); + } return translateRecordsToMatter(type.Tag, records, type) as ReturnType[] | undefined; } diff --git a/codegen/src/mom/spec/translate-global.ts b/codegen/src/mom/spec/translate-global.ts index 59544d22c2..8d5494a5b9 100644 --- a/codegen/src/mom/spec/translate-global.ts +++ b/codegen/src/mom/spec/translate-global.ts @@ -83,11 +83,16 @@ const DatatypeSchema = { * Extract basic datatypes from core spec. We are not functional without these so this code is less lenient. */ function* translateDatatypes(ref: GlobalReference): Generator { - // Patch details so semtag matches correct detail section + // Rename detail sections that do not match the name or description of the corresponding table entry if (ref.details) { for (const detail of ref.details) { - if (detail.name == "SemanticTagStruct") { - detail.name = "semtag"; + switch (detail.name) { + case "SemanticTagStruct Type": + detail.name = "semtag"; + break; + + case "LocationDescriptorStruct": + detail.name = "locationdesc"; } } } diff --git a/codegen/src/mom/spec/translate-table.ts b/codegen/src/mom/spec/translate-table.ts index 5e7fe5b501..98fe56b765 100644 --- a/codegen/src/mom/spec/translate-table.ts +++ b/codegen/src/mom/spec/translate-table.ts @@ -216,50 +216,67 @@ function installPreciseDetails( definitions.map(detail => [detail.name.toLowerCase().replace(/\s*\([^)]+\)\s*/g, " "), detail]), ); - records.forEach(r => { - if (!r.name) { + for (const record of records) { + if (!record.name) { return; } let titleSuffix; - if (r.element?.endsWith("field")) { + if (record.element?.endsWith("field")) { titleSuffix = "field"; - } else if (r.element) { - titleSuffix = r.element; + } else if (record.element) { + titleSuffix = record.element; } else { titleSuffix = tag; } - const name = r.name.toLowerCase(); - let detail = lookup[`${name} ${titleSuffix}`] || lookup[`${name}`]; + // We identify the detail section associated with a row using both "name" and "description", optionally followed + // by a suffix specific to the type of thing + let detail: HtmlReference | undefined; + for (let identifier of [record.name, (record as { description?: string }).description]) { + if (identifier === undefined) { + continue; + } - // Grr WC (at least) doing their own thing per usual and uses "bits" suffix instead of "bit" - if (detail === undefined && titleSuffix === "bit") { - detail = lookup[`${name} bits`]; - } + identifier = identifier.toLowerCase(); - if (detail === undefined) { - const description = (r as { description?: string }).description?.toLowerCase(); - if (description !== undefined) { - detail = lookup[`${description} ${titleSuffix}`] || lookup[`${description}`]; + detail = lookup[`${identifier} ${titleSuffix}`] || lookup[`${identifier}`]; + if (detail) { + break; + } + + // 1.4 added " Type" suffix to global types + if (titleSuffix === "datatype") { + detail = lookup[`${identifier} type`]; + if (detail) { + break; + } + } + + // Grr WC (at least) doing their own thing per usual and uses "bits" suffix instead of "bit" + if (titleSuffix === "bit") { + detail = lookup[`${identifier} bits`]; + if (detail) { + break; + } } } if (detail) { - r.xref = detail.xref; + record.xref = detail.xref; - addDocumentation(r, detail); + addDocumentation(record, detail); - if (r.details && r.details.indexOf("SHALL indicate the of the") !== -1) { + if (record.details && record.details.indexOf("SHALL indicate the of the") !== -1) { // Goofballs copy & pasted this typo a couple times - r.details = r.details.replace("the of the", "the status of the"); + record.details = record.details.replace("the of the", "the status of the"); } if (childTranslator) { - r.children = childTranslator(tag, r, detail); + record.children = childTranslator(tag, record, detail); } } - }); + } } /** The type of data we think is present in a field */ diff --git a/codegen/src/tsconfig.json b/codegen/src/tsconfig.json index e98c4f4394..f369d0f0d3 100644 --- a/codegen/src/tsconfig.json +++ b/codegen/src/tsconfig.json @@ -14,6 +14,9 @@ }, { "path": "../../packages/model/src" + }, + { + "path": "../../packages/tools/src" } ] } \ No newline at end of file diff --git a/codegen/src/util/ScopeFile.ts b/codegen/src/util/ScopeFile.ts index be537c9e98..e6c8038f0d 100644 --- a/codegen/src/util/ScopeFile.ts +++ b/codegen/src/util/ScopeFile.ts @@ -55,15 +55,16 @@ export class ScopeFile extends TsFile { * * @param model the model to reference * @param tlv in the case of structs we define both "TlvFoo" and "Foo". This designates which to import + * @param specific designates the specific instance of the model rather than any scope override */ - reference(model: Model, tlv = false) { + reference(model: Model, tlv = false, specific = false) { let sourceScope; if (this.#scope) { - const location = this.#scope.locationOf(model); + const location = this.#scope.locationOf(model, specific); if (location.isLocal) { if (this.#definesScope) { // Model is defined locally, no import required - return this.#scope.nameFor(model, tlv); + return this.#scope.nameFor(model, tlv, specific); } sourceScope = this.#scope; } diff --git a/codegen/src/util/finalize-model.ts b/codegen/src/util/finalize-model.ts index 2b1387fca4..796dbea944 100644 --- a/codegen/src/util/finalize-model.ts +++ b/codegen/src/util/finalize-model.ts @@ -11,6 +11,7 @@ import { ClusterModel, CommandModel, DatatypeModel, + ElementTag, FieldModel, MatterModel, Metatype, @@ -26,13 +27,16 @@ const logger = Logger.get("create-model"); * Create and validate the final model for export **/ export function finalizeModel(matter: MatterModel) { - matter.children.forEach(c => { - if (c instanceof ClusterModel) { - patchClusterTypes(c); - patchOptionsTypes(c); - patchStatusTypes(c); + const scopedDatatypes = collectScopedDatatypes(matter); + + for (const child of matter.children) { + if (child instanceof ClusterModel) { + patchIllegalCrossClusterReferences(child, scopedDatatypes); + patchClusterTypes(child); + patchOptionsTypes(child); + patchStatusTypes(child); } - }); + } ejectZigbee(matter); @@ -43,6 +47,29 @@ export function finalizeModel(matter: MatterModel) { }); } +export type ScopedDatatypes = Record; + +function collectScopedDatatypes(matter: MatterModel) { + const scopedDatatypes = {} as ScopedDatatypes; + + for (const cluster of matter.children) { + for (const child of cluster.children) { + if (child.tag !== ElementTag.Datatype) { + continue; + } + + if (child.name in scopedDatatypes) { + scopedDatatypes[child.name] = undefined; + continue; + } + + scopedDatatypes[child.name] = child; + } + } + + return scopedDatatypes; +} + /** * Get the properties of children without xrefs so we can compare types using isDeepEqual */ @@ -55,6 +82,38 @@ function childrenIdentity(model: ValueModel) { }); } +/** + * CHIP defines datatypes in a global scope. This is not how the specification actually works but the behavior + * continually leaks into cluster definitions where clusters reference datatypes defined in other clusters. + * + * Repair this by identifying missing datatypes that have a corresponding datatype definition of the same name in + * exactly one other cluster. When detected, replace the datatype name with a qualified name referencing the other + * cluster. + */ +function patchIllegalCrossClusterReferences(cluster: ClusterModel, scopedDatatypes: ScopedDatatypes) { + cluster.visit(model => { + // Only applies to models with a defined type + if (model.type === undefined) { + return; + } + + // If there is a base the type name is already valid + const base = model.base; + if (base !== undefined) { + return; + } + + // Look for the datatype in other clusters + const datatype = scopedDatatypes[model.type]; + if (datatype === undefined) { + return; + } + + // Add qualified name + model.type = `${datatype.parent!.name}.${datatype.name}`; + }); +} + /** * Some enum definitions are left hanging that we can fix with a quick scan comparing names. I believe this only * affects enums in ColorControlCluster from the spec but the logic is generic and safe so applying to all clusters diff --git a/compat/matter-node-ble.js/src/tsconfig.json b/compat/matter-node-ble.js/src/tsconfig.json index 727420bd7c..25523ea78c 100644 --- a/compat/matter-node-ble.js/src/tsconfig.json +++ b/compat/matter-node-ble.js/src/tsconfig.json @@ -8,6 +8,9 @@ "references": [ { "path": "../../../packages/nodejs-ble/src" + }, + { + "path": "../../../packages/tools/src" } ] } \ No newline at end of file diff --git a/compat/matter-node.js-examples/src/examples/BridgedDevicesNodeLegacy.ts b/compat/matter-node.js-examples/src/examples/BridgedDevicesNodeLegacy.ts index bac7e6124a..ce32601086 100644 --- a/compat/matter-node.js-examples/src/examples/BridgedDevicesNodeLegacy.ts +++ b/compat/matter-node.js-examples/src/examples/BridgedDevicesNodeLegacy.ts @@ -188,6 +188,7 @@ class BridgedDevice { nodeLabel: name, // Main end user name for the device productName: name, productLabel: name, + uniqueId: `${uniqueId}`, serialNumber: `node-matter-${uniqueId}-${i}`, reachable: true, }); diff --git a/compat/matter-node.js-examples/src/tsconfig.json b/compat/matter-node.js-examples/src/tsconfig.json index 9e596af645..ff668bb2b5 100644 --- a/compat/matter-node.js-examples/src/tsconfig.json +++ b/compat/matter-node.js-examples/src/tsconfig.json @@ -9,6 +9,9 @@ { "path": "../../../packages/matter.js/src" }, + { + "path": "../../../packages/tools/src" + }, { "path": "../../matter-node-ble.js/src" } diff --git a/compat/matter-node.js/src/tsconfig.json b/compat/matter-node.js/src/tsconfig.json index 44d9c9504f..6789ec78a5 100644 --- a/compat/matter-node.js/src/tsconfig.json +++ b/compat/matter-node.js/src/tsconfig.json @@ -18,6 +18,9 @@ { "path": "../../../packages/testing/src" }, + { + "path": "../../../packages/tools/src" + }, { "path": "../../../packages/types/src" } diff --git a/models/package.json b/models/package.json index 8b2534c01b..ac8bb65b42 100644 --- a/models/package.json +++ b/models/package.json @@ -14,6 +14,9 @@ "types": "./dist/esm/*.d.ts" } }, + "imports": { + "#model": "@matter/model" + }, "scripts": { "clean": "matter-build clean", "build": "matter-build", diff --git a/models/src/local/ChannelOverrides.ts b/models/src/local/ChannelOverrides.ts deleted file mode 100644 index df582b07c5..0000000000 --- a/models/src/local/ChannelOverrides.ts +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @license - * Copyright 2022-2024 Matter.js Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import { LocalMatter } from "../local.js"; - -LocalMatter.children.push({ - tag: "cluster", - name: "Channel", - asOf: "1.3", - - children: [ - // In the Channel cluster definition, the spec references AdditionalInfoStruct from in the ContentLauncher - // cluster without defining it. Probably a case of CHIP behavior leaking into the specification even though - // it's formally invalid. We create a local alias so the type resolves - { - tag: "datatype", - name: "AdditionalInfoStruct", - type: "ContentLauncher.AdditionalInfoStruct", - }, - ], -}); diff --git a/models/src/local/ColorControlOverrides.ts b/models/src/local/ColorControlOverrides.ts index 9071c03e60..fb385a128e 100644 --- a/models/src/local/ColorControlOverrides.ts +++ b/models/src/local/ColorControlOverrides.ts @@ -34,11 +34,6 @@ LocalMatter.children.push({ id: 0x8, name: "ColorMode", default: FieldValue.None, - children: [ - { tag: "field", name: "CurrentHueAndCurrentSaturation", id: 0x0, conformance: "HS" }, - { tag: "field", name: "CurrentXAndCurrentY", id: 0x1, conformance: "XY" }, - { tag: "field", name: "ColorTemperatureMireds", id: 0x2, conformance: "CT" }, - ], }, // Override primary conformance using our ">" extension to conformance syntax @@ -79,12 +74,22 @@ LocalMatter.children.push({ id: 0x4003, name: "ColorLoopDirection", type: "enum16", + until: "1.4", children: [ { tag: "field", name: "Decrement", id: 0 }, { tag: "field", name: "Increment", id: 1 }, ], }, + // In 1.4 they created ColorLoopDirectionEnum but left the type of ColorLoopDirection attribute as uint8 + { + tag: "attribute", + id: 0x4003, + asOf: "1.4", + name: "ColorLoopDirection", + type: "ColorLoopDirectionEnum", + }, + // Spec defines conformance on these as "CT | ColorTemperatureMireds" which doesn't make sense because // conformance on ColorTemperatureMireds is "CT" { @@ -135,6 +140,22 @@ LocalMatter.children.push({ ], }, + // In 1.4 the spec removed default values for these. Unsure why but bring them back as they are mandatory + { + tag: "attribute", + id: 0x400b, + name: "ColorTempPhysicalMinMireds", + default: 1, + }, + { + tag: "attribute", + id: 0x400c, + name: "ColorTempPhysicalMaxMireds", + default: 0xfeff, + }, + + // This field is mandatory but spec + // Set the correct type of MoveMode because just in the description { tag: "command", @@ -142,7 +163,7 @@ LocalMatter.children.push({ name: "MoveColorTemperature", children: [ - { tag: "field", name: "MoveMode", id: 0x0, type: "MoveMode", conformance: "M", constraint: "desc" }, + { tag: "field", name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", constraint: "desc" }, ], }, @@ -153,7 +174,7 @@ LocalMatter.children.push({ name: "StepColorTemperature", children: [ - { tag: "field", name: "StepMode", id: 0x0, type: "StepMode", conformance: "M", constraint: "desc" }, + { tag: "field", name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", constraint: "desc" }, ], }, ], diff --git a/models/src/local/ContentLauncherOverrides.ts b/models/src/local/ContentLauncherOverrides.ts deleted file mode 100644 index 97f146c478..0000000000 --- a/models/src/local/ContentLauncherOverrides.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @license - * Copyright 2022-2024 Matter.js Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -import { LocalMatter } from "../local.js"; - -LocalMatter.children.push({ - tag: "cluster", - name: "ContentLauncher", - asOf: "1.3", - - children: [ - // Alias for missing datatype (see similar alias in ChannelOverrides.ts) - { - tag: "datatype", - name: "CharacteristicEnum", - type: "MediaPlayback.CharacteristicEnum", - }, - ], -}); diff --git a/models/src/local/DoorLockOverrides.ts b/models/src/local/DoorLockOverrides.ts index b469937cba..b207050e5a 100644 --- a/models/src/local/DoorLockOverrides.ts +++ b/models/src/local/DoorLockOverrides.ts @@ -11,14 +11,16 @@ LocalMatter.children.push({ name: "DoorLock", children: [ - // The spec doesn't really define names for these bits, just long-form - // descriptions that make ugly identifiers. Strangely, CHIP defines - // the structures but not the actual attributes so they aren't included - // in our CHIP model. So set the names manually + // The spec doesn't really define names for these bits, just long-form descriptions that make ugly identifiers. + // Strangely, CHIP defines the structures but not the actual attributes so they aren't included in our CHIP + // model. So set the names manually + // + // Aaaand in 1.4 they've disappeared. Weren't provisional, weren't deprecated { tag: "attribute", id: 0x45, name: "KeypadProgrammingEventMask", + until: "1.4", children: [ { tag: "field", constraint: "0", name: "Unknown" }, { tag: "field", constraint: "1", name: "PinCodeChanged" }, @@ -31,6 +33,7 @@ LocalMatter.children.push({ tag: "attribute", id: 0x46, name: "RemoteProgrammingEventMask", + until: "1.4", children: [ { tag: "field", constraint: "0", name: "Unknown" }, { tag: "field", constraint: "2", name: "PinAdded" }, @@ -44,6 +47,7 @@ LocalMatter.children.push({ tag: "attribute", id: 0x47, name: "RfidProgrammingEventMask", + until: "1.4", children: [ { tag: "field", constraint: "0", name: "Unknown" }, { tag: "field", constraint: "5", name: "IdAdded" }, diff --git a/models/src/local/ElectricalPowerMeasurementOverrides.ts b/models/src/local/ElectricalPowerMeasurementOverrides.ts index 0042531e2f..b7c0103b29 100644 --- a/models/src/local/ElectricalPowerMeasurementOverrides.ts +++ b/models/src/local/ElectricalPowerMeasurementOverrides.ts @@ -21,7 +21,7 @@ LocalMatter.children.push({ tag: "field", name: "Ranges", - // 1.3 spec mislabels the "access" column as "default" + // 1.3 spec mislabels the "access" column as "default" (still present in 1.4 as well) default: [], access: "R V", }, diff --git a/models/src/local/OnOffOverrides.ts b/models/src/local/OnOffOverrides.ts deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/models/src/local/index.ts b/models/src/local/index.ts index 9799df9fa4..519171ebbf 100644 --- a/models/src/local/index.ts +++ b/models/src/local/index.ts @@ -15,9 +15,7 @@ import "./AdministratorCommissioningOverrides.js"; import "./any.js"; import "./BasicInformationOverrides.js"; -import "./ChannelOverrides.js"; import "./ColorControlOverrides.js"; -import "./ContentLauncherOverrides.js"; import "./DoorLockOverrides.js"; import "./ElectricalPowerMeasurementOverrides.js"; import "./GroupKeyManagementOverrides.js"; diff --git a/models/src/tsconfig.json b/models/src/tsconfig.json index c6d7b1d901..6d367331f6 100644 --- a/models/src/tsconfig.json +++ b/models/src/tsconfig.json @@ -11,6 +11,9 @@ }, { "path": "../../packages/testing/src" + }, + { + "path": "../../packages/tools/src" } ] } \ No newline at end of file diff --git a/models/src/v1.4/spec.ts b/models/src/v1.4/spec.ts new file mode 100644 index 0000000000..299101759c --- /dev/null +++ b/models/src/v1.4/spec.ts @@ -0,0 +1,42732 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { + MatterElement as Matter, + ClusterElement as Cluster, + AttributeElement as Attribute, + CommandElement as Command, + FieldElement as Field, + DatatypeElement as Datatype, + EventElement as Event, + DeviceTypeElement as DeviceType, + RequirementElement as Requirement, + SemanticNamespaceElement as SemanticNamespace, + SemanticTagElement as SemanticTag +} from "#model"; + +export const SpecMatter = Matter( + { name: "SpecMatter" }, + + Cluster( + { + name: "Identify", id: 0x3, classification: "endpoint", pics: "I", + + details: "This cluster supports an endpoint identification state (e.g., flashing a light), that indicates to " + + "an observer (e.g., an installer) which of several nodes and/or endpoints it is. It also supports a " + + "multicast request that any endpoint that is identifying itself to respond to the initiator." + + "\n" + + "The state of this cluster may be shared on more than one endpoint on a node." + + "\n" + + "For Example: Two endpoints on a single node, one a temperature sensor, and one a humidity sensor, " + + "may both share the same cluster instance and therefore identification state (e.g. single LED on the " + + "node).", + + xref: { document: "cluster", section: "1.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 5 }), + + Attribute({ + name: "IdentifyTime", id: 0x0, type: "uint16", access: "RW VO", conformance: "M", default: 0, + + details: "Indicates the remaining length of time, in seconds, that the endpoint will continue to identify " + + "itself." + + "\n" + + "If this attribute is set to a value other than 0 then the device shall enter its identification " + + "state, in order to indicate to an observer which of several nodes and/or endpoints it is. It is " + + "recommended that this state consists of flashing a light with a period of 0.5 seconds. The " + + "IdentifyTime attribute shall be decremented every second while in this state." + + "\n" + + "If this attribute reaches or is set to the value 0 then the device shall terminate its " + + "identification state.", + + xref: { document: "cluster", section: "1.2.5.1" } + }), + + Attribute({ + name: "IdentifyType", id: 0x1, type: "IdentifyTypeEnum", access: "R V", conformance: "M", + constraint: "desc", + details: "Indicates how the identification state is presented to the user." + + "\n" + + "This attribute shall contain one of the values defined in IdentifyTypeEnum. The value None shall " + + "NOT be used if the device is capable of presenting its identification state using one of the other " + + "methods defined in IdentifyTypeEnum.", + xref: { document: "cluster", section: "1.2.5.2" } + }), + + Command( + { + name: "Identify", id: 0x0, access: "M", conformance: "M", direction: "request", response: "status", + details: "This command starts or stops the receiving device identifying itself.", + xref: { document: "cluster", section: "1.2.6.1" } + }, + Field({ name: "IdentifyTime", id: 0x0, type: "uint16", conformance: "M" }) + ), + + Command( + { + name: "TriggerEffect", id: 0x40, access: "M", conformance: "O", direction: "request", + response: "status", + + details: "This command allows the support of feedback to the user, such as a certain light effect. It is used " + + "to allow an implementation to provide visual feedback to the user under certain circumstances such " + + "as a color light turning green when it has successfully connected to a network. The use of this " + + "command and the effects themselves are entirely up to the implementer to use whenever a visual " + + "feedback is useful but it is not the same as and does not replace the identify mechanism used " + + "during commissioning.", + + xref: { document: "cluster", section: "1.2.6.2" } + }, + + Field({ + name: "EffectIdentifier", id: 0x0, type: "EffectIdentifierEnum", conformance: "M", + constraint: "desc", + + details: "This field shall indicate the identify effect to use and shall contain one of the non-reserved " + + "values in EffectIdentifierEnum." + + "\n" + + "All values of the EffectIdentifierEnum shall be supported. Implementors may deviate from the " + + "example light effects in EffectIdentifierEnum, but they SHOULD indicate during testing how they " + + "handle each effect.", + + xref: { document: "cluster", section: "1.2.6.2.1" } + }), + + Field({ + name: "EffectVariant", id: 0x1, type: "EffectVariantEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate which variant of the effect, indicated in the EffectIdentifier field, " + + "SHOULD be triggered. If a device does not support the given variant, it shall use the default " + + "variant. This field shall contain one of the values in EffectVariantEnum.", + xref: { document: "cluster", section: "1.2.6.2.2" } + }) + ), + + Datatype( + { name: "IdentifyTypeEnum", type: "enum8", xref: { document: "cluster", section: "1.2.4.1" } }, + Field({ name: "None", id: 0x0, conformance: "M", description: "No presentation." }), + Field({ name: "LightOutput", id: 0x1, conformance: "M", description: "Light output of a lighting product." }), + Field({ name: "VisibleIndicator", id: 0x2, conformance: "M", description: "Typically a small LED." }), + Field({ name: "AudibleBeep", id: 0x3, conformance: "M" }), + Field({ + name: "Display", id: 0x4, conformance: "M", + description: "Presentation will be visible on display screen." + }), + Field({ + name: "Actuator", id: 0x5, conformance: "M", + description: "Presentation will be conveyed by actuator functionality such as through a window blind operation or in- wall relay." + }) + ), + + Datatype( + { name: "EffectIdentifierEnum", type: "enum8", xref: { document: "cluster", section: "1.2.4.2" } }, + Field({ name: "Blink", id: 0x0, conformance: "M", description: "e.g., Light is turned on/off once." }), + Field({ + name: "Breathe", id: 0x1, conformance: "M", + description: "e.g., Light is turned on/off over 1 second and repeated 15 times." + }), + Field({ + name: "Okay", id: 0x2, conformance: "M", + description: "e.g., Colored light turns green for 1 second; non-colored light flashes twice." + }), + Field({ + name: "ChannelChange", id: 0xb, conformance: "M", + description: "e.g., Colored light turns orange for 8 seconds; non-colored light switches to the maximum brightness for 0.5s and then minimum brightness for 7.5s." + }), + Field({ + name: "FinishEffect", id: 0xfe, conformance: "M", + description: "Complete the current effect sequence before terminating. e.g., if in the middle of a breathe effect (as above), first complete the current 1s breathe effect and then terminate the effect." + }), + Field({ + name: "StopEffect", id: 0xff, conformance: "M", + description: "Terminate the effect as soon as possible." + }) + ), + + Datatype( + { name: "EffectVariantEnum", type: "enum8", xref: { document: "cluster", section: "1.2.4.3" } }, + Field({ name: "Default", id: 0x0, conformance: "M", description: "Indicates the default effect is used" }) + ) + ), + + Cluster( + { + name: "Groups", id: 0x4, classification: "endpoint", pics: "G", + + details: "The Groups cluster manages, per endpoint, the content of the node-wide Group Table that is part of " + + "the underlying interaction layer." + + "\n" + + "In a network supporting fabrics, group IDs referenced by attributes or other elements of this " + + "cluster are scoped to the accessing fabric." + + "\n" + + "The Groups cluster is scoped to the endpoint. Groups cluster commands support discovering the " + + "endpoint membership in a group, adding the endpoint to a group, removing the endpoint from a group, " + + "removing endpoint membership from all groups. All commands defined in this cluster shall only " + + "affect groups scoped to the accessing fabric." + + "\n" + + "When group names are supported, the server stores a name string, which is set by the client for " + + "each assigned group and indicated in response to a client request." + + "\n" + + "Note that configuration of group addresses for outgoing commands is achieved using the Message " + + "Layer mechanisms where the Group Table is not involved. Hence this cluster does not play a part in " + + "that.", + + xref: { document: "cluster", section: "1.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.3.4" } }, + Field({ + name: "GN", constraint: "0", description: "GroupNames", + details: "The Group Names feature indicates the ability to store a name for a group when a group is added.", + xref: { document: "cluster", section: "1.3.4.1" } + }) + ), + + Attribute({ + name: "NameSupport", id: 0x0, type: "NameSupportBitmap", access: "R V", conformance: "M", + constraint: "desc", default: 0, quality: "F", + details: "This attribute provides legacy, read-only access to whether the Group Names feature is supported. " + + "The most significant bit, bit 7 (GroupNames), shall be equal to bit 0 of the FeatureMap attribute " + + "(GN Feature). All other bits shall be 0.", + xref: { document: "cluster", section: "1.3.6.1" } + }), + + Command( + { + name: "AddGroup", id: 0x0, access: "F M", conformance: "M", direction: "request", + response: "AddGroupResponse", + details: "The AddGroup command allows a client to add group membership in a particular group for the server " + + "endpoint.", + xref: { document: "cluster", section: "1.3.7.1" } + }, + + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", constraint: "min 1", + details: "This field shall be used to identify the group and any associated key material to which the server " + + "endpoint is to be added.", + xref: { document: "cluster", section: "1.3.7.1.1" } + }), + + Field({ + name: "GroupName", id: 0x1, type: "string", conformance: "M", constraint: "max 16", + details: "This field may be set to a human-readable name for the group. If the client has no name for the " + + "group, the GroupName field shall be set to the empty string." + + "\n" + + "Support of group names is optional and is indicated by the FeatureMap and NameSupport attribute.", + xref: { document: "cluster", section: "1.3.7.1.2" } + }) + ), + + Command( + { + name: "ViewGroup", id: 0x1, access: "F O", conformance: "M", direction: "request", + response: "ViewGroupResponse", + details: "The ViewGroup command allows a client to request that the server responds with a ViewGroupResponse " + + "command containing the name string for a particular group.", + xref: { document: "cluster", section: "1.3.7.2" } + }, + + Field({ name: "GroupId", id: 0x0, type: "group-id", conformance: "M", constraint: "min 1" }) + ), + + Command( + { + name: "GetGroupMembership", id: 0x2, access: "F O", conformance: "M", direction: "request", + response: "GetGroupMembershipResponse", + details: "The GetGroupMembership command allows a client to inquire about the group membership of the server " + + "endpoint, in a number of ways.", + xref: { document: "cluster", section: "1.3.7.3" } + }, + + Field( + { name: "GroupList", id: 0x0, type: "list", conformance: "M", constraint: "all[min 1]" }, + Field({ name: "entry", type: "group-id" }) + ) + ), + + Command( + { + name: "RemoveGroup", id: 0x3, access: "F M", conformance: "M", direction: "request", + response: "RemoveGroupResponse", + details: "The RemoveGroup command allows a client to request that the server removes the membership for the " + + "server endpoint, if any, in a particular group.", + xref: { document: "cluster", section: "1.3.7.4" } + }, + + Field({ name: "GroupId", id: 0x0, type: "group-id", conformance: "M", constraint: "min 1" }) + ), + + Command({ + name: "RemoveAllGroups", id: 0x4, access: "F M", conformance: "M", direction: "request", + response: "status", + details: "The RemoveAllGroups command allows a client to direct the server to remove all group associations " + + "for the server endpoint.", + xref: { document: "cluster", section: "1.3.7.5" } + }), + + Command( + { + name: "AddGroupIfIdentifying", id: 0x5, access: "F M", conformance: "M", direction: "request", + response: "status", + + details: "The AddGroupIfIdentifying command allows a client to add group membership in a particular group for " + + "the server endpoint, on condition that the endpoint is identifying itself. Identifying " + + "functionality is controlled using the Identify cluster, (see Identify Cluster)." + + "\n" + + "For correct operation of the AddGroupIfIdentifying command, any endpoint that supports the Groups " + + "server cluster shall also support the Identify server cluster." + + "\n" + + "This command might be used to assist configuring group membership in the absence of a commissioning " + + "tool.", + + xref: { document: "cluster", section: "1.3.7.6" } + }, + + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", constraint: "min 1", + details: "This field shall be used to identify the group and any associated key material to which the server " + + "endpoint is to be added.", + xref: { document: "cluster", section: "1.3.7.6.1" } + }), + + Field({ + name: "GroupName", id: 0x1, type: "string", conformance: "M", constraint: "max 16", + details: "This field may be set to a human-readable name for the group. If the client has no name for the" + + "\n" + + "group, the GroupName field shall be set to the empty string." + + "\n" + + "Support of group names is optional and is indicated by the FeatureMap and NameSupport attribute.", + xref: { document: "cluster", section: "1.3.7.6.2" } + }) + ), + + Command( + { + name: "AddGroupResponse", id: 0x0, conformance: "M", direction: "response", + details: "The AddGroupResponse is sent by the Groups cluster server in response to an AddGroup command.", + xref: { document: "cluster", section: "1.3.7.7" } + }, + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field is set according to the Effect on Receipt section of the AddGroup command.", + xref: { document: "cluster", section: "1.3.7.7.1" } + }), + Field({ + name: "GroupId", id: 0x1, type: "group-id", conformance: "M", constraint: "min 1", + details: "This field is set to the GroupID field of the received AddGroup command.", + xref: { document: "cluster", section: "1.3.7.7.2" } + }) + ), + + Command( + { + name: "ViewGroupResponse", id: 0x1, conformance: "M", direction: "response", + details: "The ViewGroupResponse command is sent by the Groups cluster server in response to a ViewGroup " + + "command.", + xref: { document: "cluster", section: "1.3.7.8" } + }, + + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field is according to the Effect on Receipt section of the ViewGroup command.", + xref: { document: "cluster", section: "1.3.7.8.1" } + }), + Field({ + name: "GroupId", id: 0x1, type: "group-id", conformance: "M", constraint: "min 1", + details: "This field is set to the GroupID field of the received ViewGroup command.", + xref: { document: "cluster", section: "1.3.7.8.2" } + }), + + Field({ + name: "GroupName", id: 0x2, type: "string", conformance: "M", constraint: "max 16", + details: "If the status is SUCCESS, and group names are supported, this field is set to the group name " + + "associated with that group in the Group Table; otherwise it is set to the empty string.", + xref: { document: "cluster", section: "1.3.7.8.3" } + }) + ), + + Command( + { + name: "GetGroupMembershipResponse", id: 0x2, conformance: "M", direction: "response", + details: "The GetGroupMembershipResponse command is sent by the Groups cluster server in response to a " + + "GetGroupMembership command.", + xref: { document: "cluster", section: "1.3.7.9" } + }, + + Field({ + name: "Capacity", id: 0x0, type: "uint8", conformance: "M", quality: "X", + + details: "This field shall contain the remaining capacity of the Group Table of the node. The following " + + "values apply:" + + "\n" + + " • 0 - No further groups may be added." + + "\n" + + " • 0 < Capacity < 0xFE - Capacity holds the number of groups that may be added." + + "\n" + + " • 0xFE - At least 1 further group may be added (exact number is unknown)." + + "\n" + + " • null - It is unknown if any further groups may be added.", + + xref: { document: "cluster", section: "1.3.7.9.1" } + }), + + Field( + { + name: "GroupList", id: 0x1, type: "list", conformance: "M", constraint: "all[min 1]", + + details: "The GroupList field shall contain either the group IDs of all the groups in the Group Table for " + + "which the server endpoint is a member of the group (in the case where the GroupList field of the " + + "received GetGroupMembership command was empty), or the group IDs of all the groups in the Group " + + "Table for which the server endpoint is a member of the group and for which the group ID was " + + "included in the the GroupList field of the received GetGroupMembership command (in the case where " + + "the GroupList field of the received GetGroupMembership command was not empty)." + + "\n" + + "Zigbee: If the total number of groups will cause the maximum payload length of a frame to be " + + "exceeded, then the GroupList field shall contain only as many groups as will fit.", + + xref: { document: "cluster", section: "1.3.7.9.2" } + }, + + Field({ name: "entry", type: "group-id" }) + ) + ), + + Command( + { + name: "RemoveGroupResponse", id: 0x3, conformance: "M", direction: "response", + details: "The RemoveGroupResponse command is generated by the server in response to the receipt of a " + + "RemoveGroup command.", + xref: { document: "cluster", section: "1.3.7.10" } + }, + + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field is according to the Effect on Receipt section of the RemoveGroup command.", + xref: { document: "cluster", section: "1.3.7.10.1" } + }), + Field({ + name: "GroupId", id: 0x1, type: "group-id", conformance: "M", constraint: "min 1", + details: "This field is set to the GroupID field of the received RemoveGroup command.", + xref: { document: "cluster", section: "1.3.7.10.2" } + }) + ), + + Datatype( + { name: "NameSupportBitmap", type: "map8", xref: { document: "cluster", section: "1.3.5.1" } }, + Field({ name: "GroupNames", constraint: "7", description: "The ability to store a name for a group." }) + ) + ), + + Cluster( + { + name: "ScenesManagement", id: 0x62, classification: "application", pics: "S", + + details: "The Scenes Management cluster provides attributes and commands for setting up and recalling scenes. " + + "Each scene corresponds to a set of stored values of specified attributes for one or more clusters " + + "on the same end point as the Scenes Management cluster." + + "\n" + + "In most cases scenes are associated with a particular group identifier. Scenes may also exist " + + "without a group, in which case the value 0 replaces the group identifier. Note that extra care is " + + "required in these cases to avoid a scene identifier collision, and that commands related to scenes " + + "without a group may only be unicast, i.e., they shall NOT be multicast or broadcast." + + "\n" + + "NOTE Support for Scenes Management cluster is provisional.", + + xref: { document: "cluster", section: "1.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.4.4" } }, + Field({ + name: "SN", conformance: "O", constraint: "0", description: "SceneNames", + details: "This feature indicates the ability to store a name for a scene when a scene is added.", + xref: { document: "cluster", section: "1.4.4.1" } + }) + ), + + Attribute({ + name: "LastConfiguredBy", id: 0x0, type: "node-id", access: "R V", conformance: "O", default: null, + quality: "X", + + details: "Indicates the Node ID of the node that last configured the Scene Table." + + "\n" + + "The null value indicates that the server has not been configured, or that the identifier of the " + + "node that last configured the Scenes Management cluster is not known." + + "\n" + + "The Node ID is scoped to the accessing fabric.", + + xref: { document: "cluster", section: "1.4.8.1" } + }), + + Attribute({ + name: "SceneTableSize", id: 0x1, type: "uint16", access: "R V", conformance: "M", + constraint: "desc", default: 16, quality: "F", + details: "Indicates the number of entries in the Scene Table on this endpoint. This is the total across all " + + "fabrics; note that a single fabric cannot use all those entries (see Handling of fabric- scoping). " + + "The minimum size of this table, (i.e., the minimum number of scenes to support across all fabrics " + + "per endpoint) shall be 16, unless a device type in which this cluster is used, defines a larger " + + "value in the device type definition.", + xref: { document: "cluster", section: "1.4.8.2" } + }), + + Attribute( + { + name: "FabricSceneInfo", id: 0x2, type: "list", access: "R F V", conformance: "M", + constraint: "desc", + details: "Indicates a list of fabric scoped information about scenes on this endpoint." + + "\n" + + "The number of list entries for this attribute shall NOT exceed the number of supported fabrics by " + + "the device.", + xref: { document: "cluster", section: "1.4.8.3" } + }, + + Field({ name: "entry", type: "SceneInfoStruct" }) + ), + + Command( + { + name: "AddScene", id: 0x0, access: "F M", conformance: "M", direction: "request", + response: "AddSceneResponse", + details: "It is not mandatory for an extension field set to be included in the command for every cluster on " + + "that endpoint that has a defined extension field set. Extension field sets may be omitted, " + + "including the case of no extension field sets at all.", + xref: { document: "cluster", section: "1.4.9.2" } + }, + + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", + details: "This field shall indicate the group identifier in the Group Table.", + xref: { document: "cluster", section: "1.4.9.2.1" } + }), + Field({ + name: "SceneId", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the scene identifier in the Scene Table.", + xref: { document: "cluster", section: "1.4.9.2.2" } + }), + Field({ + name: "TransitionTime", id: 0x2, type: "uint32", conformance: "M", constraint: "max 60000000", + details: "This field shall indicate the transition time of the scene, measured in milliseconds.", + xref: { document: "cluster", section: "1.4.9.2.3" } + }), + Field({ + name: "SceneName", id: 0x3, type: "string", conformance: "M", constraint: "max 16", + details: "This field shall indicate the name of the scene.", + xref: { document: "cluster", section: "1.4.9.2.4" } + }), + + Field( + { + name: "ExtensionFieldSetStructs", id: 0x4, type: "list", conformance: "M", constraint: "desc", + details: "This field shall contains the list of extension fields.", + xref: { document: "cluster", section: "1.4.9.2.5" } + }, + Field({ name: "entry", type: "ExtensionFieldSetStruct" }) + ) + ), + + Command( + { + name: "AddSceneResponse", id: 0x0, conformance: "M", direction: "response", + xref: { document: "cluster", section: "1.4.9.3" } + }, + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field shall be set according to the Effect on Receipt section for AddScene command.", + xref: { document: "cluster", section: "1.4.9.3.1" } + }), + Field({ + name: "GroupId", id: 0x1, type: "group-id", conformance: "M", + details: "The GroupID field shall be set to the corresponding field of the received AddScene command.", + xref: { document: "cluster", section: "1.4.9.3.2" } + }), + Field({ + name: "SceneId", id: 0x2, type: "uint8", conformance: "M", constraint: "max 254", + details: "The SceneID field shall be set to the corresponding field of the received AddScene command.", + xref: { document: "cluster", section: "1.4.9.3.3" } + }) + ), + + Command( + { + name: "ViewScene", id: 0x1, access: "F O", conformance: "M", direction: "request", + response: "ViewSceneResponse", + xref: { document: "cluster", section: "1.4.9.4" } + }, + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", + details: "This field shall indicate the group identifier in the Group Table.", + xref: { document: "cluster", section: "1.4.9.4.1" } + }), + Field({ + name: "SceneId", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the scene identifier in the Scene Table.", + xref: { document: "cluster", section: "1.4.9.4.2" } + }) + ), + + Command( + { + name: "ViewSceneResponse", id: 0x1, conformance: "M", direction: "response", + xref: { document: "cluster", section: "1.4.9.5" } + }, + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field shall be set according to the Effect on Receipt section for ViewScene command.", + xref: { document: "cluster", section: "1.4.9.5.1" } + }), + Field({ + name: "GroupId", id: 0x1, type: "group-id", conformance: "M", + details: "The GroupID field shall be set to the corresponding field of the received ViewScene command.", + xref: { document: "cluster", section: "1.4.9.5.2" } + }), + Field({ + name: "SceneId", id: 0x2, type: "uint8", conformance: "M", constraint: "max 254", + details: "The SceneID field shall be set to the corresponding field of the received ViewScene command.", + xref: { document: "cluster", section: "1.4.9.5.3" } + }), + + Field({ + name: "TransitionTime", id: 0x3, type: "uint32", conformance: "desc", constraint: "max 60000000", + details: "If the status is SUCCESS, this field shall be copied from the corresponding field in the Scene " + + "Table entry, otherwise it shall be omitted.", + xref: { document: "cluster", section: "1.4.9.5.4" } + }), + + Field({ + name: "SceneName", id: 0x4, type: "string", conformance: "desc", constraint: "max 16", + details: "If the status is SUCCESS, this field shall be copied from the corresponding field in the Scene " + + "Table entry, otherwise it shall be omitted.", + xref: { document: "cluster", section: "1.4.9.5.5" } + }), + + Field( + { + name: "ExtensionFieldSetStructs", id: 0x5, type: "list", conformance: "desc", + details: "If the status is SUCCESS, this field shall be copied from the corresponding field in the Scene " + + "Table entry, otherwise it shall be omitted.", + xref: { document: "cluster", section: "1.4.9.5.6" } + }, + + Field({ name: "entry", type: "ExtensionFieldSetStruct" }) + ) + ), + + Command( + { + name: "RemoveScene", id: 0x2, access: "F M", conformance: "M", direction: "request", + response: "RemoveSceneResponse", + xref: { document: "cluster", section: "1.4.9.6" } + }, + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", + details: "This field shall indicate the group identifier in the Group Table.", + xref: { document: "cluster", section: "1.4.9.6.1" } + }), + Field({ + name: "SceneId", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the scene identifier in the Scene Table.", + xref: { document: "cluster", section: "1.4.9.6.2" } + }) + ), + + Command( + { + name: "RemoveSceneResponse", id: 0x2, conformance: "M", direction: "response", + xref: { document: "cluster", section: "1.4.9.7" } + }, + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field shall be set according to the Effect on Receipt section for RemoveScene command.", + xref: { document: "cluster", section: "1.4.9.7.1" } + }), + Field({ + name: "GroupId", id: 0x1, type: "group-id", conformance: "M", + details: "The GroupID field shall be set to the corresponding field of the received RemoveScene command.", + xref: { document: "cluster", section: "1.4.9.7.2" } + }), + Field({ + name: "SceneId", id: 0x2, type: "uint8", conformance: "M", constraint: "max 254", + details: "The SceneID field shall be set to the corresponding field of the received RemoveScene command.", + xref: { document: "cluster", section: "1.4.9.7.3" } + }) + ), + + Command( + { + name: "RemoveAllScenes", id: 0x3, access: "F M", conformance: "M", direction: "request", + response: "RemoveAllScenesResponse", + xref: { document: "cluster", section: "1.4.9.8" } + }, + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", + details: "This field shall indicate the group identifier in the Group Table.", + xref: { document: "cluster", section: "1.4.9.8.1" } + }) + ), + + Command( + { + name: "RemoveAllScenesResponse", id: 0x3, conformance: "M", direction: "response", + xref: { document: "cluster", section: "1.4.9.9" } + }, + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field shall be set according to the Effect on Receipt section for RemoveAllScenes command.", + xref: { document: "cluster", section: "1.4.9.9.1" } + }), + Field({ + name: "GroupId", id: 0x1, type: "group-id", conformance: "M", + details: "The GroupID field shall be set to the corresponding field of the received RemoveAllScenes command.", + xref: { document: "cluster", section: "1.4.9.9.2" } + }) + ), + + Command( + { + name: "StoreScene", id: 0x4, access: "F M", conformance: "M", direction: "request", + response: "StoreSceneResponse", + xref: { document: "cluster", section: "1.4.9.10" } + }, + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", + details: "This field shall indicate the group identifier in the Group Table.", + xref: { document: "cluster", section: "1.4.9.10.1" } + }), + Field({ + name: "SceneId", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the scene identifier in the Scene Table.", + xref: { document: "cluster", section: "1.4.9.10.2" } + }) + ), + + Command( + { + name: "StoreSceneResponse", id: 0x4, conformance: "M", direction: "response", + xref: { document: "cluster", section: "1.4.9.11" } + }, + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field shall be set according to the Effect on Receipt section for StoreScene command.", + xref: { document: "cluster", section: "1.4.9.11.1" } + }), + Field({ + name: "GroupId", id: 0x1, type: "group-id", conformance: "M", + details: "The GroupID field shall be set to the corresponding field of the received StoreScene command.", + xref: { document: "cluster", section: "1.4.9.11.2" } + }), + Field({ + name: "SceneId", id: 0x2, type: "uint8", conformance: "M", constraint: "max 254", + details: "The SceneID field shall be set to the corresponding field of the received StoreScene command.", + xref: { document: "cluster", section: "1.4.9.11.3" } + }) + ), + + Command( + { + name: "RecallScene", id: 0x5, access: "F O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.4.9.12" } + }, + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", + details: "This field shall indicate the group identifier in the Group Table.", + xref: { document: "cluster", section: "1.4.9.12.1" } + }), + Field({ + name: "SceneId", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the scene identifier in the Scene Table.", + xref: { document: "cluster", section: "1.4.9.12.2" } + }), + + Field({ + name: "TransitionTime", id: 0x2, type: "uint32", conformance: "O", constraint: "max 60000000", + quality: "X", + details: "This field shall indicate the transition time of the scene, measured in milliseconds.", + xref: { document: "cluster", section: "1.4.9.12.3" } + }) + ), + + Command( + { + name: "GetSceneMembership", id: 0x6, access: "F O", conformance: "M", direction: "request", + response: "GetSceneMembershipResponse", + details: "This command can be used to get the used scene identifiers within a certain group, for the endpoint " + + "that implements this cluster.", + xref: { document: "cluster", section: "1.4.9.13" } + }, + + Field({ + name: "GroupId", id: 0x0, type: "group-id", conformance: "M", + details: "This field shall indicate the group identifier in the Group Table.", + xref: { document: "cluster", section: "1.4.9.13.1" } + }) + ), + + Command( + { + name: "GetSceneMembershipResponse", id: 0x6, conformance: "M", direction: "response", + xref: { document: "cluster", section: "1.4.9.14" } + }, + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field shall be set according to the Effect on Receipt section for GetSceneMembership command.", + xref: { document: "cluster", section: "1.4.9.14.1" } + }), + + Field({ + name: "Capacity", id: 0x1, type: "uint8", conformance: "M", quality: "X", + + details: "This field shall contain the remaining capacity of the Scene Table of the server (for all groups " + + "for the accessing fabric). The following values apply:" + + "\n" + + " • 0 - No further scenes may be added." + + "\n" + + " • 0 < Capacity < 0xFE - Capacity holds the number of scenes that may be added." + + "\n" + + " • 0xFE - At least 1 further scene may be added (exact number is unknown)." + + "\n" + + " • null - It is unknown if any further scenes may be added.", + + xref: { document: "cluster", section: "1.4.9.14.2" } + }), + + Field({ + name: "GroupId", id: 0x2, type: "group-id", conformance: "M", + details: "This field shall be set to the corresponding field of the received GetSceneMembership command.", + xref: { document: "cluster", section: "1.4.9.14.3" } + }), + + Field( + { + name: "SceneList", id: 0x3, type: "list", conformance: "Status == Success", + details: "If the status is not SUCCESS then this field shall be omitted, else this field shall contain the " + + "identifiers of all the scenes in the Scene Table with the corresponding Group ID.", + xref: { document: "cluster", section: "1.4.9.14.4" } + }, + + Field({ name: "entry", type: "uint8" }) + ) + ), + + Command( + { + name: "CopyScene", id: 0x40, access: "F M", conformance: "O", direction: "request", + response: "CopySceneResponse", + details: "This command allows a client to efficiently copy scenes from one group/scene identifier pair to " + + "another group/scene identifier pair.", + xref: { document: "cluster", section: "1.4.9.15" } + }, + + Field({ + name: "Mode", id: 0x0, type: "CopyModeBitmap", conformance: "M", constraint: "desc", + details: "This field shall contain the information of how the scene copy is to proceed." + + "\n" + + "The CopyAllScenes bit of the Mode indicates whether all scenes are to be copied. If this value is " + + "set to 1, all scenes are to be copied and the SceneIdentifierFrom and SceneIdentifierTo fields " + + "shall be ignored. Otherwise this bit is set to 0.", + xref: { document: "cluster", section: "1.4.9.15.1" } + }), + + Field({ + name: "GroupIdentifierFrom", id: 0x1, type: "group-id", conformance: "M", + details: "This field shall indicate the identifier of the group from which the scene is to be copied. " + + "Together with the SceneIdentifierFrom field, this field uniquely identifies the scene to copy from " + + "the Scene Table.", + xref: { document: "cluster", section: "1.4.9.15.2" } + }), + + Field({ + name: "SceneIdentifierFrom", id: 0x2, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the identifier of the scene from which the scene is to be copied. " + + "Together with the GroupIdentifierFrom field, this field uniquely identifies the scene to copy from " + + "the Scene Table.", + xref: { document: "cluster", section: "1.4.9.15.3" } + }), + + Field({ + name: "GroupIdentifierTo", id: 0x3, type: "group-id", conformance: "M", + details: "This field shall indicate the identifier of the group to which the scene is to be copied. Together " + + "with the SceneIdentifierTo field, this field uniquely identifies the scene to copy to the Scene " + + "Table.", + xref: { document: "cluster", section: "1.4.9.15.4" } + }), + + Field({ + name: "SceneIdentifierTo", id: 0x4, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the identifier of the scene to which the scene is to be copied. Together " + + "with the GroupIdentifierTo field, this field uniquely identifies the scene to copy to the Scene " + + "Table.", + xref: { document: "cluster", section: "1.4.9.15.5" } + }) + ), + + Command( + { + name: "CopySceneResponse", id: 0x40, conformance: "CopyScene", direction: "response", + xref: { document: "cluster", section: "1.4.9.16" } + }, + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + details: "This field shall be set according to the Effect on Receipt section for the CopyScene command.", + xref: { document: "cluster", section: "1.4.9.16.1" } + }), + + Field({ + name: "GroupIdentifierFrom", id: 0x1, type: "group-id", conformance: "M", + details: "This field shall be set to the same values as in the corresponding fields of the received CopyScene " + + "command.", + xref: { document: "cluster", section: "1.4.9.16.2" } + }), + + Field({ + name: "SceneIdentifierFrom", id: 0x2, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall be set to the same values as in the corresponding fields of the received CopyScene " + + "command.", + xref: { document: "cluster", section: "1.4.9.16.3" } + }) + ), + + Datatype( + { name: "CopyModeBitmap", type: "map8", xref: { document: "cluster", section: "1.4.7.1" } }, + Field({ name: "CopyAllScenes", constraint: "0", description: "Copy all scenes in the scene table" }) + ), + + Datatype( + { name: "SceneInfoStruct", type: "struct", xref: { document: "cluster", section: "1.4.7.2" } }, + + Field({ + name: "SceneCount", id: 0x0, type: "uint8", access: "F", conformance: "M", default: 0, + details: "This field shall indicate the number of scenes currently used in the server’s Scene Table on the " + + "endpoint where the Scenes Management cluster appears." + + "\n" + + "This only includes the count for the associated fabric.", + xref: { document: "cluster", section: "1.4.7.2.1" } + }), + + Field({ + name: "CurrentScene", id: 0x1, type: "uint8", access: "S", conformance: "M", constraint: "desc", + default: 255, + details: "This field shall indicate the scene identifier of the scene last invoked on the associated fabric. " + + "If no scene has been invoked, the value of this field shall be 0xFF, the undefined scene identifier.", + xref: { document: "cluster", section: "1.4.7.2.2" } + }), + + Field({ + name: "CurrentGroup", id: 0x2, type: "group-id", access: "S", conformance: "M", default: 0, + details: "This field shall indicate the group identifier of the scene last invoked on the associated fabric, " + + "or 0 if the scene last invoked is not associated with a group.", + xref: { document: "cluster", section: "1.4.7.2.3" } + }), + + Field({ + name: "SceneValid", id: 0x3, type: "bool", access: "S", conformance: "M", default: false, + + details: "This field shall indicate whether the state of the server corresponds to that associated with the " + + "CurrentScene and CurrentGroup fields of the SceneInfoStruct they belong to. TRUE indicates that " + + "these fields are valid, FALSE indicates that they are not valid." + + "\n" + + "This field shall be set to False for all other fabrics when an attribute with the Scenes (\"S\") " + + "designation in the Quality column of another cluster present on the same endpoint is modified or " + + "when the current scene is modified by a fabric through the RecallScene or StoreScene commands, " + + "regardless of the fabric-scoped access quality of the command." + + "\n" + + "In the event where the SceneValid field is set to False for a fabric, the CurrentScene and " + + "CurrentGroup fields shall be the last invoked scene and group for that fabric. In the event where " + + "no scene was previously invoked for that fabric, the CurrentScene and CurrentGroup fields shall be " + + "their default values.", + + xref: { document: "cluster", section: "1.4.7.2.4" } + }), + + Field({ + name: "RemainingCapacity", id: 0x4, type: "uint8", access: "F", conformance: "M", + constraint: "max 253", + details: "This field shall indicate the remaining capacity of the Scene Table on this endpoint for the " + + "accessing fabric. Note that this value may change between reads, even if no entries are added or " + + "deleted on the accessing fabric, due to other clients associated with other fabrics adding or " + + "deleting entries that impact the resource usage on the device.", + xref: { document: "cluster", section: "1.4.7.2.5" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "AttributeValuePairStruct", type: "struct", + details: "This data type indicates a combination of an identifier and the value of an attribute.", + xref: { document: "cluster", section: "1.4.7.3" } + }, + + Field({ + name: "AttributeId", id: 0x0, type: "attrib-id", conformance: "M", + + details: "This field shall be present for all instances in a given ExtensionFieldSetStruct." + + "\n" + + "Which Value* field is used shall be determined based on the data type of the attribute indicated by " + + "AttributeID, as described in the Value* Fields subsection." + + "\n" + + "The AttributeID field shall NOT refer to an attribute without the Scenes (\"S\") designation in the " + + "Quality column of the cluster specification." + + "\n" + + "### 1.4.7.3.2. ValueUnsigned8, ValueSigned8, ValueUnsigned16, ValueSigned16, ValueUnsigned32, " + + "ValueSigned32, ValueUnsigned64, ValueSigned64 Fields" + + "\n" + + "These fields shall indicate the attribute value as part of an extension field set, associated with " + + "a given AttributeID under an ExtensionFieldSetStruct’s ClusterID. Which of the fields is used shall" + + "\n" + + "be determined by the type of the attribute indicated by AttributeID as follows:" + + "\n" + + " • Data types bool, map8, and uint8 shall map to ValueUnsigned8." + + "\n" + + " • Data types int8 shall map to ValueSigned8." + + "\n" + + " • Data types map16 and uint16 shall map to ValueUnsigned16." + + "\n" + + " • Data types int16 shall map to ValueSigned16." + + "\n" + + " • Data types map32, uint24, and uint32 shall map to ValueUnsigned32." + + "\n" + + " • Data types int24 and int32 shall map to ValueSigned32." + + "\n" + + " • Data types map64, uint40, uint48, uint56 and uint64 shall map to ValueUnsigned64." + + "\n" + + " • Data types int40, int48, int56 and int64 shall map to ValueSigned64." + + "\n" + + " • For derived types, the mapping shall be based on the base type. For example, an attribute of " + + " type percent shall be treated as if it were of type uint8, whereas an attribute of type " + + " percent100ths shall be treated as if it were of type uint16." + + "\n" + + " • For boolean nullable attributes, any value that is not 0 or 1 shall be considered to have the " + + " null value." + + "\n" + + " • For boolean non-nullable attributes, any value that is not 0 or 1 shall be considered to have " + + " the value FALSE." + + "\n" + + " • For non-boolean nullable attributes, any value that is not a valid numeric value for the " + + " attribute’s type after accounting for range reductions due to being nullable and constraints " + + " shall be considered to have the null value for the type." + + "\n" + + " • For non-boolean non-nullable attributes, any value that is not a valid numeric value for the " + + " attribute’s type after accounting for constraints shall be considered to be the valid attribute " + + " value that is closest to the provided value." + + "\n" + + " ◦ In the event that an invalid provided value is of equal numerical distance to the two closest " + + " valid values, the lowest of those values shall be considered the closest valid attribute " + + " value." + + "\n" + + "If the used field does not match the data type of the attribute indicated by AttributeID, the " + + "AttributeValuePairStruct shall be considered invalid." + + "\n" + + "Examples of processing are:" + + "\n" + + " • ColorControl cluster CurrentX (AttributeID 0x0003) has a type of uint16 and is not nullable." + + "\n" + + " ◦ ValueUnsigned16 of 0xAB12 would be used as-is, as it is in range." + + "\n" + + " ◦ ValueUnsigned16 of 0xFF80 is outside of the range allowed for attribute CurrentX, and would " + + " be saturated to the closest valid value, which is the maximum of the attribute’s constraint " + + " range: 0xFEFF." + + "\n" + + " • LevelControl cluster CurrentLevel (AttributeID 0x0000) has a type of uint8 and is nullable." + + "\n" + + " ◦ ValueUnsigned8 of 0xA1 would be used as-is, as it is in range." + + "\n" + + " ◦ ValueUnsigned8 of 0xFF is outside the range allowed for nullable attribute CurrentLevel, and " + + " would be considered as the null value.", + + xref: { document: "cluster", section: "1.4.7.3.1" } + }), + + Field({ name: "ValueUnsigned8", id: 0x1, type: "uint8", conformance: "O.a" }), + Field({ name: "ValueSigned8", id: 0x2, type: "int8", conformance: "O.a" }), + Field({ name: "ValueUnsigned16", id: 0x3, type: "uint16", conformance: "O.a" }), + Field({ name: "ValueSigned16", id: 0x4, type: "int16", conformance: "O.a" }), + Field({ name: "ValueUnsigned32", id: 0x5, type: "uint32", conformance: "O.a" }), + Field({ name: "ValueSigned32", id: 0x6, type: "int32", conformance: "O.a" }), + Field({ name: "ValueUnsigned64", id: 0x7, type: "uint64", conformance: "O.a" }), + Field({ name: "ValueSigned64", id: 0x8, type: "int64", conformance: "O.a" }) + ), + + Datatype( + { + name: "ExtensionFieldSetStruct", type: "struct", + details: "This data type indicates for a given cluster a set of attributes and their values.", + xref: { document: "cluster", section: "1.4.7.4" } + }, + + Field({ + name: "ClusterId", id: 0x0, type: "cluster-id", conformance: "M", + details: "This field shall indicate the cluster-id of the cluster whose attributes are in the " + + "AttributeValueList field.", + xref: { document: "cluster", section: "1.4.7.4.1" } + }), + + Field( + { + name: "AttributeValueList", id: 0x1, type: "list", conformance: "M", constraint: "desc", + details: "This field shall indicate a set of attributes and their values which are stored as part of a scene." + + "\n" + + "Attributes which do not have the Scenes (\"S\") designation in the Quality column of their cluster " + + "specification shall NOT be used in the AttributeValueList field.", + xref: { document: "cluster", section: "1.4.7.4.2" } + }, + + Field({ name: "entry", type: "AttributeValuePairStruct" }) + ) + ), + + Datatype( + { + name: "LogicalSceneTable", type: "struct", + + details: "The Scene Table is used to store information for each scene capable of being invoked on the server. " + + "Each scene is defined for a particular group. The Scene Table is defined here as a conceptual " + + "illustration to assist in understanding the underlying data to be stored when scenes are defined. " + + "Though the Scene Table is defined here using the data model architecture rules and format, the " + + "design is not normative." + + "\n" + + "The Scene table is logically a list of fabric-scoped structs. The logical fields of each Scene " + + "Table entry struct are illustrated below. An ExtensionFieldSetStruct may be present for each " + + "Scenes-supporting cluster implemented on the same endpoint.", + + xref: { document: "cluster", section: "1.4.7.5" } + }, + + Field({ + name: "SceneGroupId", id: 0x0, type: "group-id", conformance: "M", + details: "This field is the group identifier for which this scene applies, or 0 if the scene is not " + + "associated with a group.", + xref: { document: "cluster", section: "1.4.7.5.1" } + }), + + Field({ + name: "SceneId", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field is unique within this group, which is used to identify this scene.", + xref: { document: "cluster", section: "1.4.7.5.2" } + }), + + Field({ + name: "SceneName", id: 0x2, type: "string", conformance: "SN", constraint: "max 16", + details: "The field is the name of the scene." + + "\n" + + "If scene names are not supported, any commands that write a scene name shall simply discard the " + + "name, and any command that returns a scene name shall return an empty string.", + xref: { document: "cluster", section: "1.4.7.5.3" } + }), + + Field({ + name: "SceneTransitionTime", id: 0x3, type: "uint32", conformance: "M", constraint: "max 60000000", + default: 0, + details: "This field is the amount of time, in milliseconds, it will take for a cluster to change from its " + + "current state to the requested state.", + xref: { document: "cluster", section: "1.4.7.5.4" } + }), + + Field( + { + name: "ExtensionFields", id: 0x4, type: "list", conformance: "M", default: [], + details: "See the Scene Table Extensions subsections of individual clusters. A Scene Table Extension shall " + + "only use attributes with the Scene quality. Each ExtensionFieldSetStruct holds a set of values of " + + "these attributes for a cluster implemented on the same endpoint where the Scene (\"S\") designation " + + "appears in the quality column. A scene is the aggregate of all such fields across all clusters on " + + "the endpoint.", + xref: { document: "cluster", section: "1.4.7.5.5" } + }, + + Field({ name: "entry", type: "ExtensionFieldSetStruct" }) + ) + ) + ), + + Cluster( + { + name: "OnOff", id: 0x6, classification: "application", pics: "OO", + details: "Attributes and commands for turning devices on and off.", + xref: { document: "cluster", section: "1.5" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 6 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.5.4" } }, + + Field({ + name: "LT", conformance: "[!OFFONLY]", constraint: "0", description: "Lighting", + + details: "This cluster is used for a lighting application." + + "\n" + + "On receipt of a Level Control cluster command that causes the OnOff attribute to be set to FALSE, " + + "the OnTime attribute shall be set to 0." + + "\n" + + "On receipt of a Level Control cluster command that causes the OnOff attribute to be set to TRUE, if " + + "the value of the OnTime attribute is equal to 0, the server shall set the OffWaitTime attribute to " + + "0.", + + xref: { document: "cluster", section: "1.5.4.1" } + }), + + Field({ + name: "DF", conformance: "[!OFFONLY]", constraint: "1", description: "DeadFrontBehavior", + + details: "When this feature is supported, the device exposing this server cluster exhibits \"dead front\" " + + "behavior when the \"OnOff\" attribute is FALSE (Off). This \"dead front\" behavior includes:" + + "\n" + + " • clusters other than this cluster that are also exposed may respond with failures to Invoke and " + + " Write interactions. Such failure responses when in a \"dead front\" shall be with an " + + " INVALID_IN_STATE status code." + + "\n" + + " • clusters other than this cluster may change the values of their attributes to best-effort " + + " values, due to the actual values not being defined or available in this state. Device type " + + " specifications that require support for the DF feature SHOULD define what these best-effort " + + " values are." + + "\n" + + " • Report Transactions shall continue to be generated. Such transactions may include best-effort " + + " values as noted above." + + "\n" + + " • Event generation logic for clusters other than this cluster is unchanged (noting possible use " + + " of best-effort attribute values as in the preceding bullets)." + + "\n" + + "When this feature is supported and the OnOff attribute changes from TRUE to FALSE (e.g. when " + + "receiving an Off Command, or due to a manual interaction on the device), it shall start executing " + + "this \"dead front\" behavior." + + "\n" + + "When this feature is supported and the OnOff attribute changes from FALSE to TRUE (e.g. when " + + "receiving an On Command, or due to a manual interaction on the device), it shall stop executing " + + "this \"dead front\" behavior." + + "\n" + + "When this feature is supported, and any change of the \"dead front\" state leads to changes in " + + "attributes of other clusters due to the \"dead front\" feature, these attribute changes shall NOT be " + + "skipped or omitted from the usual processing associated with attribute changes. For example, if an " + + "attribute changes from value 4 to null on \"dead front\" behavior due to an Off command being " + + "received, this change shall be processed for reporting and subscriptions.", + + xref: { document: "cluster", section: "1.5.4.2" } + }), + + Field({ + name: "OFFONLY", conformance: "[!LT | DF]", constraint: "2", description: "OffOnly", + + details: "When this feature is supported, the Off command shall be supported and the On and Toggle commands " + + "shall NOT be supported." + + "\n" + + "This feature is useful for devices which can be turned off via the Off command received by an " + + "instance of this cluster but cannot be turned on via commands received by an instance of this " + + "cluster due to regulatory requirements.", + + xref: { document: "cluster", section: "1.5.4.3" } + }) + ), + + Attribute({ + name: "OnOff", id: 0x0, type: "bool", access: "R V", conformance: "M", default: false, + quality: "N S", + details: "This attribute indicates whether the device type implemented on the endpoint is turned off or " + + "turned on, in these cases the value of the OnOff attribute equals FALSE, or TRUE respectively.", + xref: { document: "cluster", section: "1.5.6.2" } + }), + + Attribute({ + name: "GlobalSceneControl", id: 0x4000, type: "bool", access: "R V", conformance: "LT", + default: true, + + details: "In order to support the use case where the user gets back the last setting of a set of devices " + + "(e.g. level settings for lights), a global scene is introduced which is stored when the devices are " + + "turned off and recalled when the devices are turned on. The global scene is defined as the scene " + + "that is stored with group identifier 0 and scene identifier 0." + + "\n" + + "This attribute is defined in order to prevent a second Off command storing the all-devices-off " + + "situation as a global scene, and to prevent a second On command destroying the current settings by " + + "going back to the global scene." + + "\n" + + "This attribute shall be set to TRUE after the reception of a command which causes the OnOff " + + "attribute to be set to TRUE, such as a standard On command, a MoveToLevel(WithOnOff) command, a " + + "RecallScene command or a OnWithRecallGlobalScene command." + + "\n" + + "This attribute is set to FALSE after reception of a OffWithEffect command.", + + xref: { document: "cluster", section: "1.5.6.3" } + }), + + Attribute({ + name: "OnTime", id: 0x4001, type: "uint16", access: "RW VO", conformance: "LT", default: 0, + details: "This attribute specifies the length of time (in 1/10ths second) that the On state shall be " + + "maintained before automatically transitioning to the Off state when using the OnWithTimedOff " + + "command. This attribute can be written at any time, but writing a value only has effect when in the " + + "Timed On state. See OnWithTimedOff for more details.", + xref: { document: "cluster", section: "1.5.6.4" } + }), + + Attribute({ + name: "OffWaitTime", id: 0x4002, type: "uint16", access: "RW VO", conformance: "LT", default: 0, + + details: "This attribute specifies the length of time (in 1/10ths second) that the Off state shall be guarded " + + "to prevent another OnWithTimedOff command turning the server back to its On state (e.g., when " + + "leaving a room, the lights are turned off but an occupancy sensor detects the leaving person and " + + "attempts to turn the lights back on). This attribute can be written at any time, but writing a " + + "value only has an effect when in the Timed On state followed by a transition to the Delayed Off " + + "state, or in the Delayed Off state. See OnWithTimedOff for more details.", + + xref: { document: "cluster", section: "1.5.6.5" } + }), + + Attribute({ + name: "StartUpOnOff", id: 0x4003, type: "StartUpOnOffEnum", access: "RW VM", conformance: "LT", + constraint: "desc", quality: "X N", + + details: "This attribute shall define the desired startup behavior of a device when it is supplied with power " + + "and this state shall be reflected in the OnOff attribute. If the value is null, the OnOff attribute " + + "is set to its previous value. Otherwise, the behavior is defined in the table defining " + + "StartUpOnOffEnum." + + "\n" + + "This behavior does not apply to reboots associated with OTA. After an OTA restart, the OnOff " + + "attribute shall return to its value prior to the restart.", + + xref: { document: "cluster", section: "1.5.6.6" } + }), + + Command({ + name: "Off", id: 0x0, access: "O", conformance: "M", direction: "request", response: "status", + xref: { document: "cluster", section: "1.5.7.1" } + }), + Command({ + name: "On", id: 0x1, access: "O", conformance: "!OFFONLY", direction: "request", response: "status", + xref: { document: "cluster", section: "1.5.7.2" } + }), + Command({ + name: "Toggle", id: 0x2, access: "O", conformance: "!OFFONLY", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.5.7.3" } + }), + + Command( + { + name: "OffWithEffect", id: 0x40, access: "O", conformance: "LT", direction: "request", + response: "status", + details: "The OffWithEffect command allows devices to be turned off using enhanced ways of fading.", + xref: { document: "cluster", section: "1.5.7.4" } + }, + + Field({ + name: "EffectIdentifier", id: 0x0, type: "EffectIdentifierEnum", conformance: "M", + constraint: "desc", + details: "This field specifies the fading effect to use when turning the device off. This field shall contain " + + "one of the non-reserved values listed in EffectIdentifierEnum.", + xref: { document: "cluster", section: "1.5.7.4.1" } + }), + + Field({ + name: "EffectVariant", id: 0x1, type: "enum8", conformance: "M", constraint: "desc", default: 0, + details: "This field is used to indicate which variant of the effect, indicated in the EffectIdentifier " + + "field, SHOULD be triggered. If the server does not support the given variant, it shall use the " + + "default variant. This field is dependent on the value of the EffectIdentifier field and shall " + + "contain one of the non-reserved values listed in either DelayedAllOffEffectVariantEnum or " + + "DyingLightEffectVariantEnum.", + xref: { document: "cluster", section: "1.5.7.4.2" } + }) + ), + + Command({ + name: "OnWithRecallGlobalScene", id: 0x41, access: "O", conformance: "LT", direction: "request", + response: "status", + details: "This command allows the recall of the settings when the device was turned off.", + xref: { document: "cluster", section: "1.5.7.5" } + }), + + Command( + { + name: "OnWithTimedOff", id: 0x42, access: "O", conformance: "LT", direction: "request", + response: "status", + details: "This command allows devices to be turned on for a specific duration with a guarded off duration so " + + "that SHOULD the device be subsequently turned off, further OnWithTimedOff commands, received during " + + "this time, are prevented from turning the devices back on. Further OnWithTimedOff commands received " + + "while the server is turned on, will update the period that the device is turned on.", + xref: { document: "cluster", section: "1.5.7.6" } + }, + + Field({ + name: "OnOffControl", id: 0x0, type: "OnOffControlBitmap", conformance: "M", constraint: "0 to 1", + details: "This field contains information on how the server is to be operated.", + xref: { document: "cluster", section: "1.5.7.6.1" } + }), + Field({ + name: "OnTime", id: 0x1, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field is used to adjust the value of the OnTime attribute.", + xref: { document: "cluster", section: "1.5.7.6.2" } + }), + Field({ + name: "OffWaitTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field is used to adjust the value of the OffWaitTime attribute.", + xref: { document: "cluster", section: "1.5.7.6.3" } + }) + ), + + Datatype( + { name: "OnOffControlBitmap", type: "map8", xref: { document: "cluster", section: "1.5.5.1" } }, + Field({ + name: "AcceptOnlyWhenOn", constraint: "0", + description: "Indicates a command is only accepted when in On state." + }) + ), + + Datatype( + { name: "StartUpOnOffEnum", type: "enum8", xref: { document: "cluster", section: "1.5.5.2" } }, + Field({ name: "Off", id: 0x0, conformance: "M", description: "Set the OnOff attribute to FALSE" }), + Field({ name: "On", id: 0x1, conformance: "M", description: "Set the OnOff attribute to TRUE" }), + Field({ + name: "Toggle", id: 0x2, conformance: "M", + description: "If the previous value of the OnOff attribute is equal to FALSE, set the OnOff attribute to TRUE. If the previous value of the OnOff attribute is equal to TRUE, set the OnOff attribute to FALSE (toggle)." + }) + ), + + Datatype( + { name: "EffectIdentifierEnum", type: "enum8", xref: { document: "cluster", section: "1.5.5.3" } }, + Field({ name: "DelayedAllOff", id: 0x0, conformance: "M", description: "Delayed All Off" }), + Field({ name: "DyingLight", id: 0x1, conformance: "M", description: "Dying Light" }) + ), + + Datatype( + { + name: "DelayedAllOffEffectVariantEnum", type: "enum8", + xref: { document: "cluster", section: "1.5.5.4" } + }, + Field({ name: "DelayedOffFastFade", id: 0x0, conformance: "M", description: "Fade to off in 0.8 seconds" }), + Field({ name: "NoFade", id: 0x1, conformance: "M", description: "No fade" }), + Field({ + name: "DelayedOffSlowFade", id: 0x2, conformance: "M", + description: "50% dim down in 0.8 seconds then fade to off in 12 seconds" + }) + ), + + Datatype( + { name: "DyingLightEffectVariantEnum", type: "enum8", xref: { document: "cluster", section: "1.5.5.5" } }, + Field({ + name: "DyingLightFadeOff", id: 0x0, conformance: "M", + description: "20% dim up in 0.5s then fade to off in 1 second" + }) + ) + ), + + Cluster( + { + name: "LevelControl", id: 0x8, classification: "application", pics: "LVL", + details: "This cluster provides an interface for controlling a characteristic of a device that can be set to " + + "a level, for example the brightness of a light, the degree of closure of a door, or the power " + + "output of a heater.", + xref: { document: "cluster", section: "1.6" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 6 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.6.4" } }, + Field({ + name: "OO", conformance: "O", constraint: "0", default: 1, description: "OnOff", + details: "Dependency with the On/Off cluster" + }), + + Field({ + name: "LT", conformance: "O", constraint: "1", default: 0, description: "Lighting", + + details: "This feature supports an interface for controlling the level of a light source. For the " + + "CurrentLevel attribute:" + + "\n" + + "A value of 0x00 shall NOT be used." + + "\n" + + "A value of 0x01 shall indicate the minimum level that can be attained on a device. A value of 0xFE " + + "shall indicate the maximum level that can be attained on a device. A value of null shall represent " + + "an undefined value." + + "\n" + + "All other values are application specific gradations from the minimum to the maximum level.", + + xref: { document: "cluster", section: "1.6.4.2" } + }), + + Field({ + name: "FQ", conformance: "P", constraint: "2", default: 0, description: "Frequency", + details: "NOTE The Frequency feature is provisional.", + xref: { document: "cluster", section: "1.6.4.3" } + }) + ), + + Attribute({ + name: "CurrentLevel", id: 0x0, type: "uint8", access: "R V", conformance: "M", + constraint: "minLevel to maxLevel", default: null, quality: "X N S Q", + + details: "Indicates the current level of this device. The meaning of 'level' is device dependent." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second, or" + + "\n" + + " • At the end of the movement/transition, or" + + "\n" + + " • When it changes from null to any other value and vice versa.", + + xref: { document: "cluster", section: "1.6.6.2" } + }), + + Attribute({ + name: "RemainingTime", id: 0x1, type: "uint16", access: "R V", conformance: "LT", default: 0, + quality: "Q", + + details: "Indicates the time remaining until the current command is complete - it is specified in 1/10ths of " + + "a second." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • When it changes from 0 to any value higher than 10, or" + + "\n" + + " • When it changes, with a delta larger than 10, caused by the invoke of a command, or" + + "\n" + + " • When it changes to 0." + + "\n" + + "For commands with a transition time or changes to the transition time less than 1 second, changes " + + "to this attribute shall NOT be reported." + + "\n" + + "As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the " + + "reporting of this attribute in order to keep track of the remaining duration.", + + xref: { document: "cluster", section: "1.6.6.3" } + }), + + Attribute({ + name: "MinLevel", id: 0x2, type: "uint8", access: "R V", conformance: "[LT]", + constraint: "1 to 254", default: 1, + details: "Indicates the minimum value of CurrentLevel that is capable of being assigned.", + xref: { document: "cluster", section: "1.6.6.4" } + }), + + Attribute({ + name: "MinLevel", id: 0x2, type: "uint8", access: "R V", conformance: "[!LT]", + constraint: "max 254", default: 0, + details: "Indicates the minimum value of CurrentLevel that is capable of being assigned.", + xref: { document: "cluster", section: "1.6.6.4" } + }), + + Attribute({ + name: "MaxLevel", id: 0x3, type: "uint8", access: "R V", conformance: "O", + constraint: "minLevel to 254", default: 254, + details: "Indicates the maximum value of CurrentLevel that is capable of being assigned.", + xref: { document: "cluster", section: "1.6.6.5" } + }), + + Attribute({ + name: "CurrentFrequency", id: 0x4, type: "uint16", access: "R V", conformance: "FQ", + constraint: "minFrequency to maxFrequency", default: 0, quality: "S P Q", + + details: "Indicates the frequency at which the device is at CurrentLevel. A CurrentFrequency of 0 is unknown." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second, or" + + "\n" + + " • At the start of the movement/transition, or" + + "\n" + + " • At the end of the movement/transition.", + + xref: { document: "cluster", section: "1.6.6.6" } + }), + + Attribute({ + name: "MinFrequency", id: 0x5, type: "uint16", access: "R V", conformance: "FQ", default: 0, + details: "Indicates the minimum value of CurrentFrequency that is capable of being assigned. MinFrequency " + + "shall be less than or equal to MaxFrequency. A value of 0 indicates undefined.", + xref: { document: "cluster", section: "1.6.6.7" } + }), + + Attribute({ + name: "MaxFrequency", id: 0x6, type: "uint16", access: "R V", conformance: "FQ", + constraint: "min minFrequency", default: 0, + details: "Indicates the maximum value of CurrentFrequency that is capable of being assigned. MaxFrequency " + + "shall be greater than or equal to MinFrequency. A value of 0 indicates undefined.", + xref: { document: "cluster", section: "1.6.6.8" } + }), + + Attribute({ + name: "OnOffTransitionTime", id: 0x10, type: "uint16", access: "RW VO", conformance: "O", + default: 0, + + details: "Indicates the time taken to move to or from the target level when On or Off commands are received " + + "by an On/Off cluster on the same endpoint. It is specified in 1/10ths of a second." + + "\n" + + "The actual time taken SHOULD be as close to OnOffTransitionTime as the device is able. Please note " + + "that if the device is not able to move at a variable rate, the OnOffTransitionTime attribute SHOULD " + + "NOT be implemented.", + + xref: { document: "cluster", section: "1.6.6.10" } + }), + + Attribute({ + name: "OnLevel", id: 0x11, type: "uint8", access: "RW VO", conformance: "M", + constraint: "minLevel to maxLevel", default: null, quality: "X", + + details: "Indicates the value that the CurrentLevel attribute is set to when the OnOff attribute of an On/Off " + + "cluster on the same endpoint is set to TRUE, as a result of processing an On/Off cluster command. " + + "If the OnLevel attribute is not implemented, or is set to the null value, it has no effect. For " + + "more details see Effect of On/Off Commands on the CurrentLevel attribute." + + "\n" + + "OnLevel represents a mandatory field that was previously not present or optional. Implementers " + + "should be aware that older devices may not implement it.", + + xref: { document: "cluster", section: "1.6.6.11" } + }), + + Attribute({ + name: "OnTransitionTime", id: 0x12, type: "uint16", access: "RW VO", conformance: "O", + default: null, quality: "X", + details: "Indicates the time taken to move the current level from the minimum level to the maximum level when " + + "an On command is received by an On/Off cluster on the same endpoint. It is specified in 1/10ths of " + + "a second. If this attribute is not implemented, or contains a null value, the OnOffTransitionTime " + + "shall be used instead.", + xref: { document: "cluster", section: "1.6.6.12" } + }), + + Attribute({ + name: "OffTransitionTime", id: 0x13, type: "uint16", access: "RW VO", conformance: "O", + default: null, quality: "X", + details: "Indicates the time taken to move the current level from the maximum level to the minimum level when " + + "an Off command is received by an On/Off cluster on the same endpoint. It is specified in 1/10ths of " + + "a second. If this attribute is not implemented, or contains a null value, the OnOffTransitionTime " + + "shall be used instead.", + xref: { document: "cluster", section: "1.6.6.13" } + }), + + Attribute({ + name: "DefaultMoveRate", id: 0x14, type: "uint8", access: "RW VO", conformance: "O", + constraint: "min 1", quality: "X", + details: "Indicates the movement rate, in units per second, when a Move command is received with a null value " + + "Rate parameter.", + xref: { document: "cluster", section: "1.6.6.14" } + }), + + Attribute({ + name: "Options", id: 0xf, type: "OptionsBitmap", access: "RW VO", conformance: "M", + constraint: "desc", default: 0, + + details: "Indicates the selected options of the device." + + "\n" + + "The Options attribute is a bitmap that determines the default behavior of some cluster commands. " + + "Each command that is dependent on the Options attribute shall first construct a temporary Options " + + "bitmap that is in effect during the command processing. The temporary Options bitmap has the same " + + "format and meaning as the Options attribute, but includes any bits that may be overridden by " + + "command fields." + + "\n" + + "This attribute is meant to be changed only during commissioning." + + "\n" + + "Command execution shall NOT continue beyond the Options processing if all of these criteria are " + + "true:" + + "\n" + + " • The command is one of the ‘without On/Off’ commands: Move, Move to Level, Step, or Stop." + + "\n" + + " • The On/Off cluster exists on the same endpoint as this cluster." + + "\n" + + " • The OnOff attribute of the On/Off cluster, on this endpoint, is FALSE." + + "\n" + + " • The value of the ExecuteIfOff bit is 0.", + + xref: { document: "cluster", section: "1.6.6.9" } + }), + + Attribute({ + name: "StartUpCurrentLevel", id: 0x4000, type: "uint8", access: "RW VM", conformance: "LT", + constraint: "desc", quality: "X N", + + details: "Indicates the desired startup level for a device when it is supplied with power and this level " + + "shall be reflected in the CurrentLevel attribute. The values of the StartUpCurrentLevel attribute " + + "are listed below:" + + "\n" + + "This behavior does not apply to reboots associated with OTA. After an OTA restart, the CurrentLevel " + + "attribute shall return to its value prior to the restart.", + + xref: { document: "cluster", section: "1.6.6.15" } + }), + + Command( + { + name: "MoveToLevel", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.6.7.1" } + }, + Field({ name: "Level", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254" }), + Field({ name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", quality: "X" }), + Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "Move", id: 0x1, access: "O", conformance: "M", direction: "request", response: "status", + xref: { document: "cluster", section: "1.6.7.2" } + }, + Field({ + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", constraint: "desc", + details: "This field shall be one of the non-reserved values in MoveModeEnum.", + xref: { document: "cluster", section: "1.6.7.2.1" } + }), + + Field({ + name: "Rate", id: 0x1, type: "uint8", conformance: "M", quality: "X", + + details: "This field shall indicate the rate of movement in units per second. The actual rate of movement " + + "SHOULD be as close to this rate as the device is able. If the Rate field is null, then the value of " + + "the DefaultMoveRate attribute shall be used if that attribute is supported and its value is not " + + "null. If the Rate field is null and the DefaultMoveRate attribute is either not supported or set to " + + "null, then the device SHOULD move as fast as it is able. If the device is not able to move at a " + + "variable rate, this" + + "\n" + + "field may be disregarded.", + + xref: { document: "cluster", section: "1.6.7.2.2" } + }), + + Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "Step", id: 0x2, access: "O", conformance: "M", direction: "request", response: "status", + xref: { document: "cluster", section: "1.6.7.3" } + }, + Field({ + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", constraint: "desc", + details: "This field shall be one of the non-reserved values in StepModeEnum.", + xref: { document: "cluster", section: "1.6.7.3.1" } + }), + Field({ + name: "StepSize", id: 0x1, type: "uint8", conformance: "M", + details: "This field shall indicate the change to CurrentLevel.", + xref: { document: "cluster", section: "1.6.7.3.2" } + }), + + Field({ + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", quality: "X", + + details: "This field shall indicate the time that shall be taken to perform the step, in tenths of a second. " + + "A step is a change in the CurrentLevel of StepSize units. The actual time taken SHOULD be as close " + + "to" + + "\n" + + "this as the device is able. If the TransitionTime field is equal to null, the device SHOULD move as " + + "fast as it is able." + + "\n" + + "If the device is not able to move at a variable rate, the TransitionTime field may be disregarded.", + + xref: { document: "cluster", section: "1.6.7.3.3" } + }), + + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "Stop", id: 0x3, access: "O", conformance: "M", direction: "request", response: "status", + xref: { document: "cluster", section: "1.6.7.4" } + }, + Field({ name: "OptionsMask", id: 0x0, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x1, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command({ + name: "MoveToLevelWithOnOff", id: 0x4, access: "O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.6.7" } + }), + Command({ + name: "MoveWithOnOff", id: 0x5, access: "O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.6.7" } + }), + Command({ + name: "StepWithOnOff", id: 0x6, access: "O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.6.7" } + }), + Command({ + name: "StopWithOnOff", id: 0x7, access: "O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.6.7" } + }), + + Command( + { + name: "MoveToClosestFrequency", id: 0x8, access: "O", conformance: "FQ", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.6.7.5" } + }, + Field({ name: "Frequency", id: 0x0, type: "uint16", conformance: "M", default: 0 }) + ), + + Datatype( + { name: "OptionsBitmap", type: "map8", xref: { document: "cluster", section: "1.6.5.1" } }, + Field({ + name: "ExecuteIfOff", constraint: "0", description: "Dependency on On/Off cluster", + details: "This bit indicates if this cluster has a dependency with the On/Off cluster.", + xref: { document: "cluster", section: "1.6.5.1.1" } + }), + Field({ + name: "CoupleColorTempToLevel", constraint: "1", description: "Dependency on Color Control cluster", + details: "This bit indicates if this cluster has a dependency with the Color Control cluster.", + xref: { document: "cluster", section: "1.6.5.1.2" } + }) + ), + + Datatype( + { name: "MoveModeEnum", type: "enum8", xref: { document: "cluster", section: "1.6.5.2" } }, + Field({ name: "Up", id: 0x0, conformance: "M", description: "Increase the level" }), + Field({ name: "Down", id: 0x1, conformance: "M", description: "Decrease the level" }) + ), + Datatype( + { name: "StepModeEnum", type: "enum8", xref: { document: "cluster", section: "1.6.5.3" } }, + Field({ name: "Up", id: 0x0, conformance: "M", description: "Step upwards" }), + Field({ name: "Down", id: 0x1, conformance: "M", description: "Step downwards" }) + ) + ), + + Cluster( + { + name: "BooleanState", id: 0x45, classification: "application", pics: "BOOL", + details: "This cluster provides an interface to a boolean state.", + xref: { document: "cluster", section: "1.7" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "StateValue", id: 0x0, type: "bool", access: "R V", conformance: "M", quality: "P", + details: "This represents a boolean state." + + "\n" + + "The semantics of this boolean state are defined by the device type using this cluster." + + "\n" + + "For example, in a Contact Sensor device type, FALSE=open or no contact, TRUE=closed or contact.", + xref: { document: "cluster", section: "1.7.4.1" } + }), + + Event( + { + name: "StateChange", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "If this event is supported, it shall be generated when the StateValue attribute changes.", + xref: { document: "cluster", section: "1.7.5.1" } + }, + Field({ + name: "StateValue", id: 0x0, type: "bool", conformance: "M", + details: "This field shall indicate the new value of the StateValue attribute.", + xref: { document: "cluster", section: "1.7.5.1.1" } + }) + ) + ), + + Cluster( + { + name: "BooleanStateConfiguration", id: 0x80, classification: "application", pics: "BOOLCFG", + details: "This cluster is used to configure a boolean sensor, including optional state change alarm features " + + "and configuration of the sensitivity level associated with the sensor.", + xref: { document: "cluster", section: "1.8" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.8.4" } }, + Field({ + name: "VIS", conformance: "O", constraint: "0", description: "Visual", + details: "Supports visual alarms" + }), + Field({ + name: "AUD", conformance: "O", constraint: "1", description: "Audible", + details: "Supports audible alarms" + }), + + Field({ + name: "SPRS", conformance: "[VIS | AUD]", constraint: "2", description: "AlarmSuppress", + + details: "This feature shall indicate that the device is able to suppress the supported alarm modes, when the " + + "user acknowledges the alarm. This is intended to stop visual and/or audible alarms, when the user " + + "has become aware that the sensor is triggered, but it is no longer desired to have the alarm modes " + + "active on the device, e.g.:" + + "\n" + + " • The triggering cause have been resolved by the user, but the sensor has not yet stopped " + + " detecting the triggering cause." + + "\n" + + " • The user is not able to address the triggering cause, but is aware of the alarm and " + + " suppress/acknowledge it be addressed at a later point." + + "\n" + + "Acknowledge of alarms will for the remainder of this cluster be referred to as suppress." + + "\n" + + "A suppressed alarm is still considered active and will remain so unless it is actively disabled or " + + "the triggering condition is not longer present. The action of suppressing an alarm mode is only " + + "applicable to and is intended to stop the physical alarming, e.g. emitting a sound or blinking a " + + "light; it does not impact alarm reporting in AlarmsActive.", + + xref: { document: "cluster", section: "1.8.4.1" } + }), + + Field({ + name: "SENSLVL", conformance: "O", constraint: "3", description: "SensitivityLevel", + details: "Supports ability to set sensor sensitivity" + }) + ), + + Attribute({ + name: "CurrentSensitivityLevel", id: 0x0, type: "uint8", access: "RW VO", conformance: "SENSLVL", + constraint: "max supportedSensitivityLevels - 1", quality: "N", + details: "Indicates the currently selected sensitivity level." + + "\n" + + "If a write interaction to this attribute contains an unsupported sensitivity value, a " + + "CONSTRAINT_ERROR status shall be returned.", + xref: { document: "cluster", section: "1.8.6.1" } + }), + + Attribute({ + name: "SupportedSensitivityLevels", id: 0x1, type: "uint8", access: "R V", conformance: "SENSLVL", + constraint: "2 to 10", quality: "F", + + details: "Indicates the number of supported sensitivity levels by the device." + + "\n" + + "These supported sensitivity levels shall be ordered by sensitivity, where a value of 0 shall be " + + "considered the lowest sensitivity level (least sensitive) and the highest supported value shall be " + + "considered the highest sensitivity level." + + "\n" + + "The number of supported sensitivity levels SHOULD represent unique sensitivity levels supported by " + + "the device.", + + xref: { document: "cluster", section: "1.8.6.2" } + }), + + Attribute({ + name: "DefaultSensitivityLevel", id: 0x2, type: "uint8", access: "R V", conformance: "[SENSLVL]", + constraint: "max supportedSensitivityLevels - 1", quality: "F", + details: "Indicates the default sensitivity level selected by the manufacturer.", + xref: { document: "cluster", section: "1.8.6.3" } + }), + + Attribute( + { + name: "AlarmsActive", id: 0x3, type: "AlarmModeBitmap", access: "R V", conformance: "VIS | AUD", + default: 0, + + details: "Indicates which specific alarm modes on the server are currently active. When the sensor is no " + + "longer triggered, this attribute shall be set to the inactive state, by setting the bit to 0, for " + + "all supported alarm modes." + + "\n" + + "If an alarm mode is not supported, the bit indicating this alarm mode shall always be 0. A bit " + + "shall indicate whether the alarm mode inactive or not:" + + "\n" + + " • 0 = Inactive" + + "\n" + + " • 1 = Active", + + xref: { document: "cluster", section: "1.8.6.4" } + } + ), + + Attribute( + { + name: "AlarmsSuppressed", id: 0x4, type: "AlarmModeBitmap", access: "R V", conformance: "SPRS", + default: 0, + + details: "Indicates which specific alarm modes on the server are currently suppressed. When the sensor is no " + + "longer triggered, this attribute shall be set to the unsuppressed state, by setting the bit to 0, " + + "for all supported alarm modes." + + "\n" + + "If an alarm mode is not supported, the bit indicating this alarm mode shall always be 0. A bit " + + "shall indicate whether the alarm mode is suppressed or not:" + + "\n" + + " • 0 = Not suppressed" + + "\n" + + " • 1 = Suppressed", + + xref: { document: "cluster", section: "1.8.6.5" } + } + ), + + Attribute( + { + name: "AlarmsEnabled", id: 0x5, type: "AlarmModeBitmap", access: "R V", conformance: "[VIS | AUD]", + quality: "N", + + details: "Indicates the alarm modes that will be emitted if the sensor is triggered. If an alarm mode is not " + + "supported, the bit indicating this alarm mode shall always be 0." + + "\n" + + "A bit shall indicate whether the alarm mode is enabled or disabled:" + + "\n" + + " • 0 = Disabled" + + "\n" + + " • 1 = Enabled", + + xref: { document: "cluster", section: "1.8.6.6" } + } + ), + + Attribute( + { + name: "AlarmsSupported", id: 0x6, type: "AlarmModeBitmap", access: "R V", conformance: "VIS | AUD", + default: 0, quality: "F", + + details: "Indicates the alarms supported by the sensor. A bit shall indicate whether the alarm mode is " + + "supported:" + + "\n" + + " • 0 = Not supported" + + "\n" + + " • 1 = Supported", + + xref: { document: "cluster", section: "1.8.6.7" } + } + ), + + Attribute({ + name: "SensorFault", id: 0x7, type: "SensorFaultBitmap", access: "R V", conformance: "O", + default: 0, + details: "Indicates any faults registered by the device.", + xref: { document: "cluster", section: "1.8.6.8" } + }), + + Event( + { + name: "AlarmsStateChanged", id: 0x0, access: "V", conformance: "VIS | AUD", priority: "info", + + details: "This event shall be generated after any bits in the AlarmsActive and/or AlarmsSuppressed attributes " + + "change. This may occur in situations such as when internal processing by the server determines that " + + "an alarm mode becomes active or inactive, or when the SuppressAlarm or EnableDisableAlarm commands " + + "are processed in a way that some alarm modes becomes suppressed, active or inactive." + + "\n" + + "If several alarm modes change state at the same time, a single event combining multiple changes may " + + "be emitted instead of multiple events each representing a single change.", + + xref: { document: "cluster", section: "1.8.8.1" } + }, + + Field({ + name: "AlarmsActive", id: 0x0, type: "AlarmModeBitmap", conformance: "M", + details: "This field shall indicate the state of active alarm modes, as indicated by the AlarmsActive " + + "attribute, at the time the event was generated.", + xref: { document: "cluster", section: "1.8.8.1.1" } + }), + + Field({ + name: "AlarmsSuppressed", id: 0x1, type: "AlarmModeBitmap", conformance: "SPRS", + details: "This field shall indicate the state of suppressed alarm modes, as indicated by the AlarmsSuppressed " + + "attribute, at the time the event was generated.", + xref: { document: "cluster", section: "1.8.8.1.2" } + }) + ), + + Event( + { + name: "SensorFault", id: 0x1, access: "V", conformance: "O", priority: "info", + details: "This event shall be generated when the device registers or clears a fault.", + xref: { document: "cluster", section: "1.8.8.2" } + }, + + Field({ + name: "SensorFault", id: 0x0, type: "SensorFaultBitmap", conformance: "M", + details: "This field shall indicate the value of the SensorFault attribute, at the time this event is " + + "generated.", + xref: { document: "cluster", section: "1.8.8.2.1" } + }) + ), + + Command( + { + name: "SuppressAlarm", id: 0x0, access: "O", conformance: "SPRS", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.8.7.1" } + }, + Field({ + name: "AlarmsToSuppress", id: 0x0, type: "AlarmModeBitmap", conformance: "M", + details: "This field shall indicate the alarm modes to suppress.", + xref: { document: "cluster", section: "1.8.7.1.1" } + }) + ), + + Command( + { + name: "EnableDisableAlarm", id: 0x1, access: "O", conformance: "VIS | AUD", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.8.7.2" } + }, + + Field({ + name: "AlarmsToEnableDisable", id: 0x0, type: "AlarmModeBitmap", conformance: "M", + details: "This field shall indicate the alarm modes to either enable or disable depending on the bit status, " + + "as specified for the AlarmsEnabled attribute.", + xref: { document: "cluster", section: "1.8.7.2.1" } + }) + ), + + Datatype( + { name: "AlarmModeBitmap", type: "map8", xref: { document: "cluster", section: "1.8.5.1" } }, + Field({ name: "Visual", constraint: "0", description: "Visual alarming" }), + Field({ name: "Audible", constraint: "1", description: "Audible alarming" }) + ), + Datatype( + { name: "SensorFaultBitmap", type: "map16", xref: { document: "cluster", section: "1.8.5.2" } }, + Field({ name: "GeneralFault", constraint: "0", description: "Unspecified fault detected" }) + ) + ), + + Cluster( + { + name: "ModeSelect", id: 0x50, classification: "application", pics: "MOD", + + details: "This cluster provides an interface for controlling a characteristic of a device that can be set to " + + "one of several predefined values. For example, the light pattern of a disco ball, the mode of a " + + "massage chair, or the wash cycle of a laundry machine." + + "\n" + + "The server allows the client to set a mode on the server. A mode is one of a list of options that " + + "may be presented by a client for a user choice, or understood by the client, via the semantic tags " + + "on the" + + "\n" + + "mode." + + "\n" + + "A semantic tag is either a standard tag within a standard category namespace, or a manufacturer " + + "specific tag, within the namespace of the vendor ID of the manufacturer. If there is no semantic " + + "tag, the mode is anonymous, and the selection is made by the user solely based on the Label string." + + "\n" + + "Each cluster ID that indicates this specification shall define a distinct purpose for the cluster " + + "instance. For example: A LightBlinking cluster ID supports blinking modes for a light (and is " + + "described that way)." + + "\n" + + "An anonymous mode shall support the derived cluster purpose. A manufacturer specific semantic tag " + + "shall support the derived cluster purpose. An anonymous mode shall NOT replace the meaning of a " + + "standard semantic tag, when one exists, for the cluster purpose.", + + xref: { document: "cluster", section: "1.9" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.9.4" } }, + + Field({ + name: "DEPONOFF", constraint: "0", description: "OnOff", + details: "This feature creates a dependency between an OnOff cluster instance and this cluster instance on " + + "the same endpoint. See OnMode for more information.", + xref: { document: "cluster", section: "1.9.4.1" } + }) + ), + + Attribute({ + name: "Description", id: 0x0, type: "string", access: "R V", conformance: "M", constraint: "max 64", + quality: "F", + + details: "This attribute describes the purpose of the server, in readable text." + + "\n" + + "For example, a coffee machine may have a Mode Select cluster for the amount of milk to add, and " + + "another Mode Select cluster for the amount of sugar to add. In this case, the first instance can " + + "have the description Milk and the second instance can have the description Sugar. This allows the " + + "user to tell the purpose of each of the instances.", + + xref: { document: "cluster", section: "1.9.6.1" } + }), + + Attribute({ + name: "StandardNamespace", id: 0x1, type: "enum16", access: "R V", conformance: "M", + constraint: "desc", default: null, quality: "X F", + details: "This attribute, when not null, shall indicate a single standard namespace for any standard semantic " + + "tag value supported in this or any other cluster instance with the same value of this attribute. A " + + "null value indicates no standard namespace, and therefore, no standard semantic tags are provided " + + "in this cluster instance. Each standard namespace and corresponding values and value meanings shall " + + "be defined in another document.", + xref: { document: "cluster", section: "1.9.6.2" } + }), + + Attribute( + { + name: "SupportedModes", id: 0x2, type: "list", access: "R V", conformance: "M", + constraint: "max 255", quality: "F", + details: "This attribute is the list of supported modes that may be selected for the CurrentMode attribute. " + + "Each item in this list represents a unique mode as indicated by the Mode field of the " + + "ModeOptionStruct. Each entry in this list shall have a unique value for the Mode field.", + xref: { document: "cluster", section: "1.9.6.3" } + }, + + Field({ name: "entry", type: "ModeOptionStruct" }) + ), + + Attribute({ + name: "CurrentMode", id: 0x3, type: "uint8", access: "R V", conformance: "M", constraint: "desc", + quality: "N", + details: "This attribute represents the current mode of the server." + + "\n" + + "The value of this field must match the Mode field of one of the entries in the SupportedModes" + + "\n" + + "attribute.", + xref: { document: "cluster", section: "1.9.6.4" } + }), + + Attribute({ + name: "StartUpMode", id: 0x4, type: "uint8", access: "RW VO", conformance: "O", constraint: "desc", + quality: "X N", + + details: "The StartUpMode attribute value indicates the desired startup mode for the server when it is " + + "supplied with power." + + "\n" + + "If this attribute is not null, the CurrentMode attribute shall be set to the StartUpMode value, " + + "when the server is powered up, except in the case when the OnMode attribute overrides the " + + "StartUpMode attribute (see OnModeWithPowerUp)." + + "\n" + + "This behavior does not apply to reboots associated with OTA. After an OTA restart, the CurrentMode " + + "attribute shall return to its value prior to the restart." + + "\n" + + "The value of this field shall match the Mode field of one of the entries in the SupportedModes" + + "\n" + + "attribute." + + "\n" + + "If this attribute is not implemented, or is set to the null value, it shall have no effect.", + + xref: { document: "cluster", section: "1.9.6.5" } + }), + + Attribute({ + name: "OnMode", id: 0x5, type: "uint8", access: "RW VO", conformance: "DEPONOFF", + constraint: "desc", default: null, quality: "X N", + + details: "Indicates the value of CurrentMode that depends on the state of the On/Off cluster on the same " + + "endpoint. If this attribute is not present or is set to null, it shall NOT have an effect, " + + "otherwise the CurrentMode attribute shall depend on the OnOff attribute of the On/Off cluster" + + "\n" + + "The value of this field shall match the Mode field of one of the entries in the SupportedModes" + + "\n" + + "attribute.", + + xref: { document: "cluster", section: "1.9.6.6" } + }), + + Command( + { + name: "ChangeToMode", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "status", + details: "On receipt of this command, if the NewMode field indicates a valid mode transition within the " + + "supported list, the server shall set the CurrentMode attribute to the NewMode value, otherwise, the " + + "server shall respond with an INVALID_COMMAND status response.", + xref: { document: "cluster", section: "1.9.7.1" } + }, + + Field({ name: "NewMode", id: 0x0, type: "uint8", conformance: "M", constraint: "desc" }) + ), + + Datatype( + { + name: "SemanticTagStruct", type: "struct", + details: "A Semantic Tag is meant to be interpreted by the client for the purpose the cluster serves.", + xref: { document: "cluster", section: "1.9.5.1" } + }, + + Field({ + name: "MfgCode", id: 0x0, type: "vendor-id", conformance: "M", constraint: "desc", quality: "F", + details: "This field shall indicate a manufacturer code (Vendor ID), and the Value field shall indicate a " + + "semantic tag defined by the manufacturer. Each manufacturer code supports a single namespace of " + + "values. The same manufacturer code and semantic tag value in separate cluster instances are part of " + + "the same namespace and have the same meaning. For example: a manufacturer tag meaning \"pinch\", has " + + "the same meaning in a cluster whose purpose is to choose the amount of sugar, or amount of salt.", + xref: { document: "cluster", section: "1.9.5.1.2" } + }), + + Field({ + name: "Value", id: 0x1, type: "enum16", conformance: "M", quality: "F", + details: "This field shall indicate the semantic tag within a semantic tag namespace which is either " + + "manufacturer specific or standard. For semantic tags in a standard namespace, see Standard " + + "Namespace.", + xref: { document: "cluster", section: "1.9.5.1.1" } + }) + ), + + Datatype( + { + name: "ModeOptionStruct", type: "struct", + details: "This is a struct representing a possible mode of the server.", + xref: { document: "cluster", section: "1.9.5.2" } + }, + + Field({ + name: "Label", id: 0x0, type: "string", conformance: "M", constraint: "max 64", quality: "F", + details: "This field is readable text that describes the mode option that can be used by a client to indicate " + + "to the user what this option means. This field is meant to be readable and understandable by the " + + "user.", + xref: { document: "cluster", section: "1.9.5.2.1" } + }), + + Field({ + name: "Mode", id: 0x1, type: "uint8", conformance: "M", quality: "F", + details: "The Mode field is used to identify the mode option. The value shall be unique for every item in the " + + "SupportedModes attribute.", + xref: { document: "cluster", section: "1.9.5.2.2" } + }), + + Field( + { + name: "SemanticTags", id: 0x2, type: "list", conformance: "M", constraint: "max 64", quality: "F", + + details: "This field is a list of semantic tags that map to the mode option. This may be used by clients to " + + "determine the meaning of the mode option as defined in a standard or manufacturer specific " + + "namespace. Semantic tags can help clients look for options that meet certain criteria. A semantic " + + "tag shall be either a standard tag or manufacturer specific tag as defined in each " + + "SemanticTagStruct list entry." + + "\n" + + "A mode option may have more than one semantic tag. A mode option may be mapped to a mixture of " + + "standard and manufacturer specific semantic tags." + + "\n" + + "All standard semantic tags are from a single namespace indicated by the StandardNamespace attribute." + + "\n" + + "For example: A mode labeled \"100%\" can have both the HIGH (MS) and MAX (standard) semantic tag. " + + "Clients seeking the option for either HIGH or MAX will find the same option in this case.", + + xref: { document: "cluster", section: "1.9.5.2.3" } + }, + + Field({ name: "entry", type: "SemanticTagStruct" }) + ) + ) + ), + + Cluster( + { + name: "ModeBase", classification: "application", pics: "MODB", + + details: "This cluster provides an interface for controlling a characteristic of a device that can be set to " + + "one of several predefined values. For example, the light pattern of a disco ball, the mode of a " + + "massage chair, or the wash cycle of a laundry machine." + + "\n" + + "The server allows the client to set a mode on the server. A mode is one of a list of options that " + + "may be presented by a client for a user choice, or understood by the client, via the mode’s tags." + + "\n" + + "A mode tag is either a standard tag within a standard category namespace, or a manufacturer " + + "specific tag, within the namespace of the vendor ID of the manufacturer." + + "\n" + + "Any derived cluster specification based on this cluster shall support the standard mode tag value " + + "definitions and command status definitions defined in this cluster and may define additional " + + "standard mode tag values and standard command status values that are supported in the respective " + + "derived cluster instances." + + "\n" + + "Each cluster ID that indicates this specification shall define a distinct purpose for the cluster " + + "instance. For example: A LightBlinking cluster ID supports blinking modes for a light (and is " + + "described that way)." + + "\n" + + "An anonymous mode shall NOT replace the meaning of a standard mode tag, when one exists, for the " + + "cluster purpose.", + + xref: { document: "cluster", section: "1.10" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.10.4" } }, + + Field({ + name: "DEPONOFF", constraint: "0", description: "OnOff", + details: "This feature creates a dependency between an OnOff cluster instance and this cluster instance on " + + "the same endpoint. See OnMode for more information.", + xref: { document: "cluster", section: "1.10.4.1" } + }) + ), + + Attribute( + { + name: "SupportedModes", id: 0x0, type: "list", access: "R V", conformance: "M", + constraint: "2 to 255", quality: "F", + + details: "This attribute shall contain the list of supported modes that may be selected for the CurrentMode " + + "attribute. Each item in this list represents a unique mode as indicated by the Mode field of the " + + "ModeOptionStruct." + + "\n" + + "Each entry in this list shall have a unique value for the Mode field. Each entry in this list shall " + + "have a unique value for the Label field.", + + xref: { document: "cluster", section: "1.10.6.1" } + }, + + Field({ name: "entry", type: "ModeOptionStruct" }) + ), + + Attribute({ + name: "CurrentMode", id: 0x1, type: "uint8", access: "R V", conformance: "M", constraint: "desc", + quality: "N", + + details: "Indicates the current mode of the server." + + "\n" + + "The value of this field shall match the Mode field of one of the entries in the SupportedModes " + + "attribute." + + "\n" + + "The value of this attribute may change at any time via an out-of-band interaction outside of the " + + "server, such as interactions with a user interface, via internal mode changes due to autonomously " + + "progressing through a sequence of operations, on system time-outs or idle delays, or via " + + "interactions coming from a fabric other than the one which last executed a ChangeToMode.", + + xref: { document: "cluster", section: "1.10.6.2" } + }), + + Attribute({ + name: "StartUpMode", id: 0x2, type: "uint8", access: "RW VO", conformance: "O", constraint: "desc", + quality: "X N", + + details: "Indicates the desired startup mode for the server when it is supplied with power." + + "\n" + + "If this attribute is not null, the CurrentMode attribute shall be set to the StartUpMode value, " + + "when the server is powered up, except in the case when the OnMode attribute overrides the " + + "StartUpMode attribute (see OnModeWithPowerUp)." + + "\n" + + "This behavior does not apply to reboots associated with OTA. After an OTA restart, the CurrentMode " + + "attribute shall return to its value prior to the restart." + + "\n" + + "The value of this field shall match the Mode field of one of the entries in the SupportedModes " + + "attribute." + + "\n" + + "If this attribute is not implemented, or is set to the null value, it shall have no effect.", + + xref: { document: "cluster", section: "1.10.6.3" } + }), + + Attribute({ + name: "OnMode", id: 0x3, type: "uint8", access: "RW VO", conformance: "DEPONOFF", + constraint: "desc", default: null, quality: "X N", + + details: "Indicates whether the value of CurrentMode depends on the state of the On/Off cluster on the same " + + "endpoint. If this attribute is not present or is set to null, there is no dependency, otherwise the " + + "CurrentMode attribute shall depend on the OnOff attribute in the On/Off cluster" + + "\n" + + "The value of this field shall match the Mode field of one of the entries in the SupportedModes " + + "attribute.", + + xref: { document: "cluster", section: "1.10.6.4" } + }), + + Command( + { + name: "ChangeToMode", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "ChangeToModeResponse", + details: "This command is used to change device modes." + + "\n" + + "On receipt of this command the device shall respond with a ChangeToModeResponse command.", + xref: { document: "cluster", section: "1.10.7.1" } + }, + + Field({ + name: "NewMode", id: 0x0, type: "uint8", conformance: "M", constraint: "desc", + + details: "If the NewMode field doesn’t match the Mode field of any entry of the SupportedModes list, the " + + "ChangeToModeResponse command’s Status field shall indicate UnsupportedMode and the StatusText field " + + "shall be included and may be used to indicate the issue, with a human readable string, or include " + + "an empty string." + + "\n" + + "If the NewMode field matches the Mode field of one entry of the SupportedModes list, but the device " + + "is not able to transition as requested, the ChangeToModeResponse command shall:" + + "\n" + + " • Have the Status set to a product-specific Status value representing the error, or " + + " GenericFailure if a more specific error cannot be provided. See Status field for details." + + "\n" + + " • Provide a human readable string in the StatusText field." + + "\n" + + "If the NewMode field matches the Mode field of one entry of the SupportedModes list and the device " + + "is able to transition as requested, the server shall transition into the mode associated with " + + "NewMode, the ChangeToModeResponse command shall have the Status field set to Success, the " + + "StatusText field may be supplied with a human readable string or include an empty string and the " + + "CurrentMode field shall be set to the value of the NewMode field." + + "\n" + + "If the NewMode field is the same as the value of the CurrentMode attribute the ChangeToModeResponse " + + "command shall have the Status field set to Success and the StatusText field may be supplied with a " + + "human readable string or include an empty string.", + + xref: { document: "cluster", section: "1.10.7.1.1" } + }) + ), + + Command( + { + name: "ChangeToModeResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command is sent by the device on receipt of the ChangeToMode command. This command" + + "\n" + + "shall have the following data fields:", + xref: { document: "cluster", section: "1.10.7.2" } + }, + + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + xref: { document: "cluster", section: "1.10.7.2.1" } + }), + Field({ + name: "StatusText", id: 0x1, type: "string", conformance: "[Status == Success], M", + constraint: "max 64" + }) + ), + + Datatype( + { + name: "ModeTagStruct", type: "struct", + details: "A Mode Tag is meant to be interpreted by the client for the purpose the cluster serves.", + xref: { document: "cluster", section: "1.10.5.1" } + }, + + Field({ + name: "MfgCode", id: 0x0, type: "vendor-id", conformance: "O", constraint: "desc", + + details: "If the MfgCode field exists, the Value field shall be in the manufacturer-specific value range (see " + + "Section 1.10.8, “Mode Namespace”)." + + "\n" + + "This field shall indicate the manufacturer’s VendorID and it shall determine the meaning of the " + + "Value field." + + "\n" + + "The same manufacturer code and mode tag value in separate cluster instances are part of the same " + + "namespace and have the same meaning. For example: a manufacturer tag meaning \"pinch\" can be used " + + "both in a cluster whose purpose is to choose the amount of sugar, or in a cluster whose purpose is " + + "to choose the amount of salt.", + + xref: { document: "cluster", section: "1.10.5.1.1" } + }), + + Field({ + name: "Value", id: 0x1, type: "enum16", conformance: "M", + details: "This field shall indicate the mode tag within a mode tag namespace which is either manufacturer " + + "specific or standard.", + xref: { document: "cluster", section: "1.10.5.1.2" } + }) + ), + + Datatype( + { + name: "ModeOptionStruct", type: "struct", + details: "This is a struct representing a possible mode of the server.", + xref: { document: "cluster", section: "1.10.5.2" } + }, + + Field({ + name: "Label", id: 0x0, type: "string", conformance: "M", constraint: "max 64", quality: "F", + details: "This field shall indicate readable text that describes the mode option, so that a client can " + + "provide it to the user to indicate what this option means. This field is meant to be readable and " + + "understandable by the user.", + xref: { document: "cluster", section: "1.10.5.2.1" } + }), + + Field({ + name: "Mode", id: 0x1, type: "uint8", conformance: "M", quality: "F", + details: "This field is used to identify the mode option.", + xref: { document: "cluster", section: "1.10.5.2.2" } + }), + + Field( + { + name: "ModeTags", id: 0x2, type: "list", conformance: "M", constraint: "max 8", quality: "F", + + details: "This field shall contain a list of tags that are associated with the mode option. This may be used " + + "by clients to determine the full or the partial semantics of a certain mode, depending on which " + + "tags they understand, using standard definitions and/or manufacturer specific namespace definitions." + + "\n" + + "The standard mode tags are defined in this cluster specification. For the derived cluster " + + "instances, if the specification of the derived cluster defines a namespace, the set of standard " + + "mode tags also includes the mode tag values from that namespace." + + "\n" + + "Mode tags can help clients look for options that meet certain criteria, render the user interface, " + + "use" + + "\n" + + "the mode in an automation, or to craft help text their voice-driven interfaces. A mode tag shall be " + + "either a standard tag or a manufacturer specific tag, as defined in each ModeTagStruct list entry." + + "\n" + + "A mode option may have more than one mode tag. A mode option may be associated with a mixture of " + + "standard and manufacturer specific mode tags. A mode option shall be associated with at least one " + + "standard mode tag." + + "\n" + + "A few examples are provided below." + + "\n" + + " • A mode named \"100%\" can have both the High (manufacturer specific) and Max (standard) mode tag. " + + " Clients seeking the mode for either High or Max will find the same mode in this case." + + "\n" + + " • A mode that includes a LowEnergy tag can be displayed by the client using a widget icon that " + + " shows a green leaf." + + "\n" + + " • A mode that includes a LowNoise tag may be used by the client when the user wishes for a lower " + + " level of audible sound, less likely to disturb the household’s activities." + + "\n" + + " • A mode that includes a LowEnergy tag (standard, defined in this cluster specification) and also " + + " a Delicate tag (standard, defined in the namespace of a Laundry Mode derived cluster)." + + "\n" + + " • A mode that includes both a generic Quick tag (defined here), and Vacuum and Mop tags, (defined " + + " in the RVC Clean cluster that is a derivation of this cluster).", + + xref: { document: "cluster", section: "1.10.5.2.3" } + }, + + Field({ name: "entry", type: "ModeTagStruct" }) + ) + ), + + Datatype( + { name: "ModeChangeStatus", type: "enum8" }, + Field({ + name: "Success", id: 0x0, + description: "Switching to the mode indicated by the NewMode field is allowed and possible. The CurrentMode attribute is set to the value of the NewMode field.", + xref: { document: "cluster", section: "1.10.7.2.1.2" } + }), + Field({ + name: "UnsupportedMode", id: 0x1, + description: "The value of the NewMode field doesn’t match any entries in the SupportedModes attribute.", + xref: { document: "cluster", section: "1.10.7.2.1.2" } + }), + Field({ + name: "GenericFailure", id: 0x2, + description: "Generic failure code, indicating that switching to the mode indicated by the NewMode field is not allowed or not possible.", + xref: { document: "cluster", section: "1.10.7.2.1.2" } + }), + Field({ + name: "InvalidInMode", id: 0x3, + description: "The received request cannot be handled due to the current mode of the device", + xref: { document: "cluster", section: "1.10.7.2.1.2" } + }) + ), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "1.10.8" } }) + ) + ), + + Cluster( + { + name: "LowPower", id: 0x508, classification: "application", pics: "LOWPOWER", + + details: "This cluster provides an interface for managing low power mode on a device." + + "\n" + + "This cluster would be supported on an endpoint that represents a physical device with a low power " + + "mode. This cluster provides a sleep() command to allow clients to manually put the device into low " + + "power mode. There is no command here to wake up a sleeping device because that operation often " + + "involves other protocols such as Wake On LAN. Most devices automatically enter low power mode based " + + "upon inactivity." + + "\n" + + "The cluster server for Low Power is implemented by a device that supports a low power mode, such as " + + "a TV, Set-top box, or Smart Speaker." + + "\n" + + "NOTE" + + "\n" + + "We have considered a “DisableLowPowerMode” command but have not added it due to suspected issues " + + "with energy consumption regulations. This can be added in the future.", + + xref: { document: "cluster", section: "1.11" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Command({ + name: "Sleep", id: 0x0, access: "O", conformance: "M", direction: "request", response: "status", + details: "This command shall put the device into low power mode.", + xref: { document: "cluster", section: "1.11.4.1" } + }) + ), + + Cluster( + { + name: "WakeOnLan", id: 0x503, classification: "application", pics: "WAKEONLAN", + + details: "This cluster provides an interface for managing low power mode on a device that supports the Wake " + + "On LAN or Wake On Wireless LAN (WLAN) protocol (see [Wake On LAN])." + + "\n" + + "This cluster would be supported on IP devices that have a low power mode AND support the ability to " + + "be woken up using the Wake on LAN or Wake on WLAN protocol. This cluster provides the device MAC " + + "address which is a required input to the Wake on LAN protocol. Besides the MAC address, this " + + "cluster provides an optional link-local IPv6 address which is useful to support \"Wake on Direct " + + "Packet\" used by some Ethernet and Wi-Fi devices." + + "\n" + + "Acting on the MAC address or link-local IPv6 address information does require the caller to be in " + + "the same broadcast domain as the destination. To wake the destination up, the caller sends a " + + "multicast-based magic UDP packet that contains destination’s MAC address in the UDP payload to " + + "FF02::1, the IPv6 all-nodes link-local multicast group address. If the optional link-local address " + + "is provided by the destination through this cluster, the caller also sends the magic UDP packet in " + + "unicast to that link-local address. This unicast-based method is particularly useful for Wi-Fi " + + "devices, since due to lack of MAC layer retransmission mechanism, multicast over Wi-Fi is not as " + + "reliable as unicast. If a device provides the link-local address in this cluster, its Ethernet " + + "controller or Wi-Fi radio shall respond to the IPv6 neighbor solicitation message for the " + + "link-local address without the need to wake host CPU up. In order to receive the magic or neighbor " + + "solicitation packets in multicast, the Wi-Fi devices must support Group Temporal Key (GTK) rekey " + + "operation in low power mode." + + "\n" + + "Most devices automatically enter low power mode based upon inactivity." + + "\n" + + "The cluster server for Wake on LAN or Wake on WLAN is implemented by a device that supports the " + + "Wake on LAN/WLAN protocol, such as a TV, Set-top Box, or Smart Speaker.", + + xref: { document: "cluster", section: "1.12" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "MacAddress", id: 0x0, type: "string", access: "R V", conformance: "O", constraint: "max 12", + quality: "F", + details: "Indicates the current MAC address of the device. Only 48-bit MAC Addresses shall be used for this " + + "attribute as required by the Wake on LAN protocol." + + "\n" + + "Format of this attribute shall be an upper-case hex-encoded string representing the hex address, " + + "like 12345678ABCD.", + xref: { document: "cluster", section: "1.12.4.1" } + }), + + Attribute({ + name: "LinkLocalAddress", id: 0x1, type: "ipv6adr", access: "R V", conformance: "O", + constraint: "desc", quality: "F", + + details: "Indicates the current link-local address of the device. Only 128-bit IPv6 link- local addresses " + + "shall be used for this attribute." + + "\n" + + "NOTE" + + "\n" + + "Some companies may consider MAC Address to be protected data subject to PII handling considerations " + + "and will therefore choose not to include it or read it. The MAC Address can often be determined " + + "using ARP in IPv4 or NDP in IPv6.", + + xref: { document: "cluster", section: "1.12.4.2" } + }) + ), + + Cluster( + { + name: "Switch", id: 0x3b, classification: "application", pics: "SWTCH", + + details: "This cluster exposes interactions with a switch device, for the purpose of using those interactions " + + "by other devices." + + "\n" + + "Two types of switch devices are supported: latching switch (e.g. rocker switch) and momentary " + + "switch (e.g. push button), distinguished with their feature flags." + + "\n" + + "Interactions with the switch device are exposed as attributes (for the latching switch) and as " + + "events (for both types of switches)." + + "\n" + + "An interested client may subscribe to these attributes/events and thus be informed of the " + + "interactions, and can perform actions based on this, for example by sending commands to perform an " + + "action such as controlling a light or a window shade.", + + xref: { document: "cluster", section: "1.13" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.13.4" } }, + Field({ + name: "LS", conformance: "O.a", constraint: "0", description: "LatchingSwitch", + details: "This feature flag is for a switch that maintains its position after being pressed (or turned).", + xref: { document: "cluster", section: "1.13.4.1" } + }), + + Field({ + name: "MS", conformance: "O.a", constraint: "1", description: "MomentarySwitch", + details: "This feature flag is for a switch that does not maintain its position after being pressed (or " + + "turned). After releasing, it goes back to its idle position.", + xref: { document: "cluster", section: "1.13.4.2" } + }), + + Field({ + name: "MSR", conformance: "[MS & !AS]", constraint: "2", description: "MomentarySwitchRelease", + details: "This feature flag is for a momentary switch that can distinguish and report release events.", + xref: { document: "cluster", section: "1.13.4.3" } + }), + + Field({ + name: "MSL", conformance: "[MS & (MSR | AS)]", constraint: "3", + description: "MomentarySwitchLongPress", + details: "This feature flag is for a momentary switch that can distinguish and report long presses from short " + + "presses.", + xref: { document: "cluster", section: "1.13.4.4" } + }), + + Field({ + name: "MSM", conformance: "AS, [MS & MSR]", constraint: "4", + description: "MomentarySwitchMultiPress", + details: "This feature flag is for a momentary switch that can distinguish and report double press and " + + "potentially multiple presses with more events, such as triple press, etc.", + xref: { document: "cluster", section: "1.13.4.5" } + }), + + Field({ + name: "AS", conformance: "[MS]", constraint: "5", description: "ActionSwitch", + details: "This feature flag indicates simplified handling of events for multi-press-capable switches. See " + + "Multi Press Details.", + xref: { document: "cluster", section: "1.13.4.6" } + }) + ), + + Attribute({ + name: "NumberOfPositions", id: 0x0, type: "uint8", access: "R V", conformance: "M", + constraint: "min 2", default: 2, quality: "F", + details: "Indicates the maximum number of positions the switch has. Any kind of switch has a minimum of 2 " + + "positions. Also see Multi Position Details for the case NumberOfPositions>2.", + xref: { document: "cluster", section: "1.13.5.1" } + }), + + Attribute({ + name: "CurrentPosition", id: 0x1, type: "uint8", access: "R V", conformance: "M", + constraint: "max numberOfPositions - 1", default: 0, quality: "N", + details: "Indicates the position of the switch. The valid range is zero to NumberOfPositions - 1." + + "\n" + + "CurrentPosition value 0 shall be assigned to the default position of the switch: for example the " + + "\"open\" state of a rocker switch, or the \"idle\" state of a push button switch.", + xref: { document: "cluster", section: "1.13.5.2" } + }), + + Attribute({ + name: "MultiPressMax", id: 0x2, type: "uint8", access: "R V", conformance: "MSM", + constraint: "min 2", default: 2, quality: "F", + + details: "Indicates how many consecutive presses can be detected and reported by a momentary switch which " + + "supports multi-press (MSM feature flag set)." + + "\n" + + "For example, a momentary switch supporting single press, double press and triple press, but not " + + "quad press and beyond, would return the value 3." + + "\n" + + "When more than MultiPressMax presses are detected within a multi-press sequence:" + + "\n" + + " • The server for cluster revision < 2 SHOULD generate a MultiPressComplete event with the " + + " TotalNumberOfPressesCounted field set to the value of the MultiPressMax attribute, and avoid " + + " generating any further InitialPress and MultiPressOngoing events until the switch has become " + + " fully idle (i.e. no longer in the process of counting presses within the multipress)." + + "\n" + + " • The server for cluster revision >= 2 shall generate a MultiPressComplete event with the " + + " TotalNumberOfPressesCounted field set to zero (indicating an aborted sequence), and shall NOT " + + " generate any further InitialPress and MultiPressOngoing events until the switch has become " + + " fully idle (i.e. no longer in the process of counting presses within the multipress)." + + "\n" + + "This approach avoids unintentionally causing intermediate actions where there is a very long " + + "sequence of presses beyond MultiPressMax that may be taken in account specially by switches (e.g. " + + "to trigger special behavior such as factory reset for which generating events towards the client is " + + "not appropriate).", + + xref: { document: "cluster", section: "1.13.5.3" } + }), + + Event( + { + name: "SwitchLatched", id: 0x0, access: "V", conformance: "LS", priority: "info", + details: "This event shall be generated, when the latching switch is moved to a new position. It may have " + + "been delayed by debouncing within the switch.", + xref: { document: "cluster", section: "1.13.6.1" } + }, + + Field({ + name: "NewPosition", id: 0x0, type: "uint8", conformance: "M", + constraint: "0 to numberOfPositions - 1", + details: "This field shall indicate the new value of the CurrentPosition attribute, i.e. after the move.", + xref: { document: "cluster", section: "1.13.6.1.1" } + }) + ), + + Event( + { + name: "InitialPress", id: 0x1, access: "V", conformance: "MS", priority: "info", + details: "This event shall be generated, when the momentary switch starts to be pressed (after debouncing).", + xref: { document: "cluster", section: "1.13.6.2" } + }, + + Field({ + name: "NewPosition", id: 0x0, type: "uint8", conformance: "M", + constraint: "0 to numberOfPositions - 1", + details: "This field shall indicate the new value of the CurrentPosition attribute, i.e. while pressed.", + xref: { document: "cluster", section: "1.13.6.2.1" } + }) + ), + + Event( + { + name: "LongPress", id: 0x2, access: "V", conformance: "MSL", priority: "info", + + details: "This event shall be generated when the momentary switch has been pressed for a \"long\" time. The " + + "time interval constituting a \"long\" time is manufacturer-determined, since it depends on the switch " + + "physics." + + "\n" + + " • When the AS feature flag is set, this event:" + + "\n" + + " ◦ shall NOT be generated during a multi-press sequence (since a long press is a separate cycle " + + " from any multi-press cycles);" + + "\n" + + " ◦ shall only be generated after the first InitialPress following a MultiPressComplete when a " + + " long press is detected after the idle time." + + "\n" + + " • Else, when the MSM feature flag is set, this event:" + + "\n" + + " ◦ shall NOT be generated during a multi-press sequence (since a long press is a separate cycle " + + " from any multi-press cycles);" + + "\n" + + " ◦ shall only be generated after the first InitialPress following a MultiPressComplete when a " + + " long press is detected after the idle time;" + + "\n" + + " ◦ shall NOT be generated after a MultiPressOngoing event without an intervening " + + " MultiPressComplete event." + + "\n" + + "The above constraints imply that for a given activity detection cycle of a switch having MSM and/or " + + "MSL feature flags set, the entire activity is either a single long press detection cycle of " + + "(InitialPress, LongPress, LongRelease), or a single multi-press detection cycle (ending in " + + "MultiPressComplete), where presses that would otherwise be reported as long presses are instead " + + "reported as a counted press in the MultiPressComplete event, and as InitialPress/ShortRelease pairs " + + "otherwise (where applicable)." + + "\n" + + "The rationale for this constraint is the ambiguity of interpretation of events when mixing long " + + "presses and multi-press events.", + + xref: { document: "cluster", section: "1.13.6.3" } + }, + + Field({ + name: "NewPosition", id: 0x0, type: "uint8", conformance: "M", + constraint: "0 to numberOfPositions - 1", + details: "This field shall indicate the new value of the CurrentPosition attribute, i.e. while pressed.", + xref: { document: "cluster", section: "1.13.6.3.1" } + }) + ), + + Event( + { + name: "ShortRelease", id: 0x3, access: "V", conformance: "MSR", priority: "info", + + details: "If the server has the Action Switch (AS) feature flag set, this event shall NOT be generated at " + + "all, since setting the Action Switch feature flag forbids the Momentary Switch ShortRelease (MSR) " + + "feature flag from being set. Otherwise, the following paragraphs describe the situations where this " + + "event is generated." + + "\n" + + "This event shall be generated, when the momentary switch has been released (after debouncing)." + + "\n" + + " • If the server has the Momentary Switch LongPress (MSL) feature flag set, then this event shall " + + " be generated when the switch is released if no LongPress event had been generated since the " + + " previous InitialPress event." + + "\n" + + " • If the server does not have the Momentary Switch LongPress (MSL) feature flag set, this event " + + " shall be generated when the switch is released - even when the switch was pressed for a long " + + " time." + + "\n" + + " • Also see Section 1.13.7, “Sequence of generated events”.", + + xref: { document: "cluster", section: "1.13.6.4" } + }, + + Field({ + name: "PreviousPosition", id: 0x0, type: "uint8", conformance: "M", + constraint: "0 to numberOfPositions - 1", + details: "This field shall indicate the previous value of the CurrentPosition attribute, i.e. just prior to " + + "release.", + xref: { document: "cluster", section: "1.13.6.4.1" } + }) + ), + + Event( + { + name: "LongRelease", id: 0x4, access: "V", conformance: "MSL", priority: "info", + details: "This event shall be generated, when the momentary switch has been released (after debouncing) and " + + "after having been pressed for a long time, i.e. this event shall be generated when the switch is " + + "released if a LongPress event has been generated since the previous InitialPress event. Also see " + + "Section 1.13.7, “Sequence of generated events”.", + xref: { document: "cluster", section: "1.13.6.5" } + }, + + Field({ + name: "PreviousPosition", id: 0x0, type: "uint8", conformance: "M", + constraint: "0 to numberOfPositions - 1", + details: "This field shall indicate the previous value of the CurrentPosition attribute, i.e. just prior to " + + "release.", + xref: { document: "cluster", section: "1.13.6.5.1" } + }) + ), + + Event( + { + name: "MultiPressOngoing", id: 0x5, access: "V", conformance: "MSM & !AS", priority: "info", + details: "If the server has the Action Switch (AS) feature flag set, this event shall NOT be generated at " + + "all. Otherwise, the following paragraphs describe the situations where this event is generated." + + "\n" + + "This event shall be generated to indicate how many times the momentary switch has been pressed in a " + + "multi-press sequence, during that sequence. See Multi Press Details below.", + xref: { document: "cluster", section: "1.13.6.6" } + }, + + Field({ + name: "NewPosition", id: 0x0, type: "uint8", conformance: "M", + constraint: "0 to numberOfPositions - 1", + details: "This field shall indicate the new value of the CurrentPosition attribute, i.e. while pressed.", + xref: { document: "cluster", section: "1.13.6.6.1" } + }), + + Field({ + name: "CurrentNumberOfPressesCounted", id: 0x1, type: "uint8", conformance: "M", + constraint: "2 to multiPressMax", + + details: "This field shall contain:" + + "\n" + + " • a value of 2 when the second press of a multi-press sequence has been detected," + + "\n" + + " • a value of 3 when the third press of a multi-press sequence has been detected," + + "\n" + + " • a value of N when the Nth press of a multi-press sequence has been detected.", + + xref: { document: "cluster", section: "1.13.6.6.2" } + }) + ), + + Event( + { + name: "MultiPressComplete", id: 0x6, access: "V", conformance: "MSM", priority: "info", + + details: "This event shall be generated to indicate how many times the momentary switch has been pressed in a " + + "multi-press sequence, after it has been detected that the sequence has ended. See Multi Press " + + "Details." + + "\n" + + "The PreviousPosition field shall indicate the previous value of the CurrentPosition attribute, i.e. " + + "just prior to release." + + "\n" + + "The TotalNumberOfPressesCounted field shall contain:" + + "\n" + + " • a value of 0 when there was an aborted multi-press sequence, where the number of presses goes " + + " beyond MultiPressMax presses," + + "\n" + + " • a value of 1 when there was exactly one press in a multi-press sequence (and the sequence has " + + " ended), i.e. there was no double press (or more)," + + "\n" + + " • a value of 2 when there were exactly two presses in a multi-press sequence (and the sequence " + + " has ended)," + + "\n" + + " • a value of 3 when there were exactly three presses in a multi-press sequence (and the sequence " + + " has ended)," + + "\n" + + " • a value of N when there were exactly N presses in a multi-press sequence (and the sequence has " + + " ended)." + + "\n" + + "NOTE" + + "\n" + + "The introduction of TotalNumberOfPressesCounted supporting the value 0 may impact clients of " + + "switches using cluster revision 1 since such servers would not use this value of " + + "TotalNumberOfPressesCounted to indicate an aborted sequence. Clients SHOULD always act using the " + + "TotalNumberOfPressesCounted field taken into account since for values from 1 to MultiPressMax, the " + + "user action that led to the event was different depending on the count.", + + xref: { document: "cluster", section: "1.13.6.7" } + }, + + Field({ + name: "PreviousPosition", id: 0x0, type: "uint8", conformance: "M", + constraint: "0 to numberOfPositions - 1" + }), + Field({ + name: "TotalNumberOfPressesCounted", id: 0x1, type: "uint8", conformance: "M", + constraint: "max multiPressMax" + }) + ) + ), + + Cluster( + { + name: "OperationalState", id: 0x60, classification: "application", pics: "OPSTATE", + + details: "This cluster supports remotely monitoring and, where supported, changing the operational state of " + + "any device where a state machine is a part of the operation." + + "\n" + + "This cluster defines common states, scoped to this cluster (e.g. Stopped, Running, Paused, Error). " + + "A derived cluster specification may define more states scoped to the derivation. Manufacturer " + + "specific states are supported in this cluster and any derived clusters thereof. When defined in a " + + "derived instance, such states are scoped to the derivation." + + "\n" + + "Actual state transitions are dependent on both the implementation, and the requirements that may " + + "additionally be imposed by a derived cluster." + + "\n" + + "An implementation that supports remotely starting its operation can make use of this cluster’s " + + "Start command to do so. A device that supports remote pause or stop of its currently selected " + + "operation can similarly make use of this cluster’s Pause and Stop commands to do so. The ability to " + + "remotely pause or stop is independent of how the operation was started (for example, an operation " + + "started by using a manual button press can be stopped by using a Stop command if the device " + + "supports remotely stopping the operation)." + + "\n" + + "Additionally, this cluster provides events for monitoring the operational state of the device.", + + xref: { document: "cluster", section: "1.14" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { + name: "PhaseList", id: 0x0, type: "list", access: "R V", conformance: "M", + constraint: "max 32[max 64]", quality: "X", + + details: "Indicates a list of names of different phases that the device can go through for the selected " + + "function or mode. The list may not be in sequence order. For example in a washing machine this " + + "could include items such as \"pre-soak\", \"rinse\", and \"spin\". These phases are manufacturer specific " + + "and may change when a different function or mode is selected." + + "\n" + + "A null value indicates that the device does not present phases during its operation. When this " + + "attribute’s value is null, the CurrentPhase attribute shall also be set to null.", + + xref: { document: "cluster", section: "1.14.5.1" } + }, + + Field({ name: "entry", type: "string" }) + ), + + Attribute({ + name: "CurrentPhase", id: 0x1, type: "uint8", access: "R V", conformance: "M", constraint: "desc", + quality: "X", + + details: "This attribute represents the current phase of operation being performed by the server. This shall " + + "be the positional index representing the value from the set provided in the PhaseList Attribute," + + "\n" + + "where the first item in that list is an index of 0. Thus, this attribute shall have a maximum value " + + "that is \"length(PhaseList) - 1\"." + + "\n" + + "Null if the PhaseList attribute is null or if the PhaseList attribute is an empty list.", + + xref: { document: "cluster", section: "1.14.5.2" } + }), + + Attribute({ + name: "CountdownTime", id: 0x2, type: "elapsed-s", access: "R V", conformance: "O", + constraint: "max 259200", default: null, quality: "X Q", + + details: "Indicates the estimated time left before the operation is completed, in seconds." + + "\n" + + "A value of 0 (zero) means that the operation has completed." + + "\n" + + "A value of null represents that there is no time currently defined until operation completion. This " + + "may happen, for example, because no operation is in progress or because the completion time is " + + "unknown." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • If it has changed due to a change in the CurrentPhase or OperationalState attributes, or" + + "\n" + + " • When it changes from 0 to any other value and vice versa, or" + + "\n" + + " • When it changes from null to any other value and vice versa, or" + + "\n" + + " • When it increases, or" + + "\n" + + " • When there is any increase or decrease in the estimated time remaining that was due to " + + " progressing insight of the server’s control logic, or" + + "\n" + + " • When it changes at a rate significantly different from one unit per second." + + "\n" + + "Changes to this attribute merely due to the normal passage of time with no other dynamic change of " + + "device state shall NOT be reported." + + "\n" + + "As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the " + + "reporting of this attribute in order to keep track of the remaining duration.", + + xref: { document: "cluster", section: "1.14.5.3" } + }), + + Attribute( + { + name: "OperationalStateList", id: 0x3, type: "list", access: "R V", conformance: "M", + constraint: "desc", + + details: "This attribute describes the set of possible operational states that the device exposes. An " + + "operational state is a fundamental device state such as Running or Error. Details of the phase of a " + + "device when, for example, in a state of Running are provided by the CurrentPhase attribute." + + "\n" + + "All devices shall, at a minimum, expose the set of states matching the commands that are also " + + "supported by the cluster instance, in addition to Error. The set of possible device states are " + + "defined in the OperationalStateEnum. A device type requiring implementation of this cluster shall " + + "define the set of states that are applicable to that specific device type.", + + xref: { document: "cluster", section: "1.14.5.4" } + }, + + Field({ name: "entry", type: "OperationalStateStruct" }) + ), + + Attribute({ + name: "OperationalState", id: 0x4, type: "OperationalStateEnum", access: "R V", conformance: "M", + details: "This attribute specifies the current operational state of a device. This shall be populated with a " + + "valid OperationalStateID from the set of values in the OperationalStateList Attribute.", + xref: { document: "cluster", section: "1.14.5.5" } + }), + + Attribute({ + name: "OperationalError", id: 0x5, type: "ErrorStateStruct", access: "R V", conformance: "M", + constraint: "desc", + details: "This attribute shall specify the details of any current error condition being experienced on the " + + "device when the OperationalState attribute is populated with Error. Please see ErrorStateStruct for " + + "general requirements on the population of this attribute." + + "\n" + + "When there is no error detected, this shall have an ErrorStateID of NoError.", + xref: { document: "cluster", section: "1.14.5.6" } + }), + + Event( + { + name: "OperationalError", id: 0x0, access: "V", conformance: "M", priority: "critical", + details: "This event is generated when a reportable error condition is detected. A device that generates this " + + "event shall also set the OperationalState attribute to Error, indicating an error condition." + + "\n" + + "This event shall contain the following fields:", + xref: { document: "cluster", section: "1.14.7.1" } + }, + + Field({ name: "ErrorState", id: 0x0, type: "ErrorStateStruct", conformance: "M" }) + ), + + Event( + { + name: "OperationCompletion", id: 0x1, access: "V", conformance: "O", priority: "info", + + details: "This event SHOULD be generated when the overall operation ends, successfully or otherwise. For " + + "example, the completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a " + + "wash cycle in a Washing Machine." + + "\n" + + "It is highly recommended that appliances device types employing the Operational State cluster " + + "support this event, even if it is optional. This assists clients in executing automations or " + + "issuing notifications at critical points in the device operation cycles." + + "\n" + + "This event shall contain the following fields:", + + xref: { document: "cluster", section: "1.14.7.2" } + }, + + Field({ + name: "CompletionErrorCode", id: 0x0, type: "enum8", conformance: "M", + details: "This field provides an indication of the state at the end of the operation. This field shall have a " + + "value from the ErrorStateEnum set. A value of NoError indicates success, that is, no error has been " + + "detected.", + xref: { document: "cluster", section: "1.14.7.2.1" } + }), + + Field({ + name: "TotalOperationalTime", id: 0x1, type: "elapsed-s", conformance: "O", quality: "X", + + details: "The total operational time, in seconds, from when the operation was started via an initial Start " + + "command or autonomous/manual starting action, until the operation completed. This includes any time" + + "\n" + + "spent while paused. There may be cases whereby the total operational time exceeds the maximum value " + + "that can be conveyed by this attribute, in such instances, this attribute shall be populated with " + + "null.", + + xref: { document: "cluster", section: "1.14.7.2.2" } + }), + + Field({ + name: "PausedTime", id: 0x2, type: "elapsed-s", conformance: "O", quality: "X", + details: "The total time spent in the paused state, in seconds. There may be cases whereby the total paused " + + "time exceeds the maximum value that can be conveyed by this attribute, in such instances, this " + + "attribute shall be populated with null.", + xref: { document: "cluster", section: "1.14.7.2.3" } + }) + ), + + Command({ + name: "Pause", id: 0x0, access: "O", conformance: "Resume, O", direction: "request", + response: "OperationalCommandResponse", + + details: "This command shall be supported if the device supports remotely pausing the operation. If this " + + "command is supported, the Resume command shall also be supported." + + "\n" + + "On receipt of this command, the device shall pause its operation if it is possible based on the " + + "current function of the server. For example, if it is at a point where it is safe to do so and/or " + + "permitted, but can be restarted from the point at which pause occurred." + + "\n" + + "If this command is received when already in the Paused state the device shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of NoError but take no further action." + + "\n" + + "A device that receives this command in any state which is not Pause-compatible shall respond" + + "\n" + + "with an OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState and shall " + + "take no further action." + + "\n" + + "States are defined as Pause-compatible as follows:" + + "\n" + + " • For states defined in this cluster specification, in Table 3, “Pause Compatibility”." + + "\n" + + " • For states defined by derived cluster specifications, in the corresponding specifications." + + "\n" + + " • For manufacturer-specific states, by the manufacturer." + + "\n" + + "A device that is unable to honor the Pause command for whatever reason shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState but take no " + + "further action." + + "\n" + + "Otherwise, on success:" + + "\n" + + " • The OperationalState attribute shall be set to Paused." + + "\n" + + " • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of " + + " NoError." + + "\n" + + "The following table defines the compatibility of this cluster’s states with the Pause command." + + "\n" + + "### Table 3. Pause Compatibility", + + xref: { document: "cluster", section: "1.14.6.1" } + }), + + Command({ + name: "Stop", id: 0x1, access: "O", conformance: "Start, O", direction: "request", + response: "OperationalCommandResponse", + + details: "This command shall be supported if the device supports remotely stopping the operation." + + "\n" + + "On receipt of this command, the device shall stop its operation if it is at a position where it is " + + "safe to do so and/or permitted. Restart of the device following the receipt of the Stop command " + + "shall require attended operation unless remote start is allowed by the device type and any " + + "jurisdiction governing remote operation of the device." + + "\n" + + "If this command is received when already in the Stopped state the device shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of NoError but take no further action." + + "\n" + + "A device that is unable to honor the Stop command for whatever reason shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState but take no " + + "further action." + + "\n" + + "Otherwise, on success:" + + "\n" + + " • The OperationalState attribute shall be set to Stopped." + + "\n" + + " • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of " + + " NoError.", + + xref: { document: "cluster", section: "1.14.6.2" } + }), + + Command({ + name: "Start", id: 0x2, access: "O", conformance: "O", direction: "request", + response: "OperationalCommandResponse", + + details: "This command shall be supported if the device supports remotely starting the operation. If this " + + "command is supported, the 'Stop command shall also be supported." + + "\n" + + "On receipt of this command, the device shall start its operation if it is safe to do so and the " + + "device is in an operational state from which it can be started. There may be either regulatory or " + + "manufacturer-imposed safety and security requirements that first necessitate some specific action " + + "at the device before a Start command can be honored. In such instances, a device shall respond with " + + "a status code of CommandInvalidInState if a Start command is received prior to the required on- " + + "device action." + + "\n" + + "If this command is received when already in the Running state the device shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of NoError but take no further action." + + "\n" + + "A device that is unable to honor the Start command for whatever reason shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of UnableToStartOrResume but take no " + + "further action." + + "\n" + + "Otherwise, on success:" + + "\n" + + " • The OperationalState attribute shall be set to Running." + + "\n" + + " • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of " + + " NoError.", + + xref: { document: "cluster", section: "1.14.6.3" } + }), + + Command({ + name: "Resume", id: 0x3, access: "O", conformance: "Pause, O", direction: "request", + response: "OperationalCommandResponse", + + details: "This command shall be supported if the device supports remotely resuming the operation. If this " + + "command is supported, the Pause command shall also be supported." + + "\n" + + "On receipt of this command, the device shall resume its operation from the point it was at when it " + + "received the Pause command, or from the point when it was paused by means outside of this cluster " + + "(for example by manual button press)." + + "\n" + + "If this command is received when already in the Running state the device shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of NoError but take no further action." + + "\n" + + "A device that receives this command in any state which is not Resume-compatible shall respond with " + + "an OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState and shall take " + + "no further action." + + "\n" + + "States are defined as Resume-compatible as follows:" + + "\n" + + " • For states defined in this cluster specification, in Table 4, “Resume Compatibility”." + + "\n" + + " • For states defined by derived cluster specifications, in the corresponding specifications." + + "\n" + + " • For manufacturer-specific states, by the manufacturer." + + "\n" + + "The following table defines the compatibility of this cluster’s states with the Resume command." + + "\n" + + "### Table 4. Resume Compatibility" + + "\n" + + "A device that is unable to honor the Resume command for any other reason shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of UnableToStartOrResume but take no " + + "further action." + + "\n" + + "Otherwise, on success:" + + "\n" + + " • The OperationalState attribute shall be set to the most recent non-Error operational state " + + " prior to entering the Paused state." + + "\n" + + " • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of " + + " NoError.", + + xref: { document: "cluster", section: "1.14.6.4" } + }), + + Command( + { + name: "OperationalCommandResponse", id: 0x4, access: "O", + conformance: "Pause | Stop | Start | Resume", direction: "response", + + details: "This command shall be supported by an implementation if any of the other commands defined by this " + + "cluster are supported (i.e. listed in the AcceptedCommandList global attribute). This command shall " + + "also be supported by an implementation of a derived cluster as a response to any commands that may " + + "be additionally defined therein." + + "\n" + + "This command shall be generated in response to any of the Start, Stop, Pause, or Resume commands.", + + xref: { document: "cluster", section: "1.14.6.5" } + }, + + Field({ + name: "CommandResponseState", id: 0x0, type: "ErrorStateStruct", conformance: "M", + details: "This shall indicate the success or otherwise of the attempted command invocation. On a successful " + + "invocation of the attempted command, the ErrorStateID shall be populated with NoError. Please see " + + "the individual command sections for additional specific requirements on population.", + xref: { document: "cluster", section: "1.14.6.5.1" } + }) + ), + + Datatype( + { + name: "OperationalStateEnum", type: "enum8", + + details: "This type defines the set of known operational state values, and is derived from enum8. The " + + "following table defines the applicable ranges for values that are defined within this type. All " + + "values that are undefined shall be treated as reserved. As shown by the table, states that may be " + + "specific to a certain Device Type or other modality shall be defined in a derived cluster of this " + + "cluster." + + "\n" + + "The derived cluster-specific state definitions shall NOT duplicate any general state definitions. " + + "That is, a derived cluster specification of this cluster cannot define states with the same " + + "semantics as the general states defined below." + + "\n" + + "A manufacturer-specific state definition shall NOT duplicate the general state definitions or " + + "derived cluster state definitions. That is, a manufacturer-defined state defined for this cluster " + + "or a derived cluster thereof cannot define a state with the same semantics as the general states " + + "defined below or states defined in a derived cluster. Such manufacturer-specific state definitions " + + "shall be scoped in the context of the Vendor ID present in the Basic Information cluster." + + "\n" + + "The following table defines the generally applicable states.", + + xref: { document: "cluster", section: "1.14.4.1" } + }, + + Field({ name: "Stopped", id: 0x0, conformance: "M", description: "The device is stopped" }), + Field({ name: "Running", id: 0x1, conformance: "M", description: "The device is operating" }), + Field({ name: "Paused", id: 0x2, conformance: "M", description: "The device is paused during an operation" }), + Field({ name: "Error", id: 0x3, conformance: "M", description: "The device is in an error state" }) + ), + + Datatype( + { + name: "OperationalStateStruct", type: "struct", + details: "The OperationalStateStruct is used to indicate a possible state of the device.", + xref: { document: "cluster", section: "1.14.4.2" } + }, + Field({ + name: "OperationalStateId", id: 0x0, type: "OperationalStateEnum", conformance: "M", default: 0, + details: "This shall be populated with a value from the OperationalStateEnum.", + xref: { document: "cluster", section: "1.14.4.2.1" } + }), + + Field({ + name: "OperationalStateLabel", id: 0x1, type: "string", conformance: "desc", constraint: "max 64", + details: "This field shall be present if the OperationalStateID is from the set reserved for Manufacturer " + + "Specific States, otherwise it shall NOT be present. If present, this shall contain a human-readable " + + "description of the operational state.", + xref: { document: "cluster", section: "1.14.4.2.2" } + }) + ), + + Datatype( + { + name: "ErrorStateEnum", type: "enum8", + + details: "This type defines the set of known operational error values, and is derived from enum8. The " + + "following table defines the applicable ranges for values that are defined within this type. All " + + "values that are undefined shall be treated as reserved. As shown by the table, errors that may be " + + "specific to a certain Device Type or other modality shall be defined in a derived cluster of this " + + "cluster." + + "\n" + + "The derived cluster-specific error definitions shall NOT duplicate the general error definitions." + + "\n" + + "That is, a derived cluster specification of this cluster cannot define errors with the same " + + "semantics as the general errors defined below." + + "\n" + + "The manufacturer-specific error definitions shall NOT duplicate the general error definitions or " + + "derived cluster-specific error definitions. That is, a manufacturer-defined error defined for this " + + "cluster or a derived cluster thereof cannot define errors with the same semantics as the general " + + "errors defined below or errors defined in a derived cluster. Such manufacturer-specific error " + + "definitions shall be scoped in the context of the Vendor ID present in the Basic Information " + + "cluster." + + "\n" + + "The set of ErrorStateID field values defined in each of the generic or derived Operational State " + + "cluster specifications is called ErrorState.", + + xref: { document: "cluster", section: "1.14.4.3" } + }, + + Field({ name: "NoError", id: 0x0, conformance: "M", description: "The device is not in an error state" }), + Field({ + name: "UnableToStartOrResume", id: 0x1, conformance: "M", + description: "The device is unable to start or resume operation" + }), + Field({ + name: "UnableToCompleteOperation", id: 0x2, conformance: "M", + description: "The device was unable to complete the current operation" + }), + Field({ + name: "CommandInvalidInState", id: 0x3, conformance: "M", + description: "The device cannot process the command in its current state" + }) + ), + + Datatype( + { name: "ErrorStateStruct", type: "struct", xref: { document: "cluster", section: "1.14.4.4" } }, + Field({ + name: "ErrorStateID", id: 0x0, type: "ErrorStateEnum", conformance: "M", default: 0, + details: "This shall be populated with a value from the ErrorStateEnum.", + xref: { document: "cluster", section: "1.14.4.4.1" } + }), + + Field({ + name: "ErrorStateLabel", id: 0x1, type: "string", conformance: "desc", constraint: "max 64", + details: "This field shall be present if the ErrorStateID is from the set reserved for Manufacturer Specific " + + "Errors, otherwise it shall NOT be present. If present, this shall contain a human-readable " + + "description of the ErrorStateID; e.g. for a manufacturer specific ErrorStateID of \"0x80\" the " + + "ErrorStateLabel may contain \"My special error\".", + xref: { document: "cluster", section: "1.14.4.4.2" } + }), + + Field({ + name: "ErrorStateDetails", id: 0x2, type: "string", conformance: "O", constraint: "max 64", + details: "This shall be a human-readable string that provides details about the error condition. As an " + + "example, if the ErrorStateID indicates that the device is a Robotic Vacuum that is stuck, the " + + "ErrorStateDetails contains \"left wheel blocked\".", + xref: { document: "cluster", section: "1.14.4.4.3" } + }) + ) + ), + + Cluster( + { + name: "AlarmBase", classification: "application", pics: "ALARM", + details: "This cluster is a base cluster from which clusters for particular alarms for a device type can be " + + "derived. Each derivation shall define the values for the AlarmBitmap data type used in this " + + "cluster. Each derivation shall define which alarms are latched.", + xref: { document: "cluster", section: "1.15" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.15.4" } }, + Field({ + name: "RESET", constraint: "0", description: "Reset", + details: "This feature indicates that alarms can be reset via the Reset command.", + xref: { document: "cluster", section: "1.15.4.1" } + }) + ), + + Attribute({ + name: "Mask", id: 0x0, type: "AlarmBitmap", access: "R V", conformance: "M", default: 0, + details: "Indicates a bitmap where each bit set in the Mask attribute corresponds to an alarm that shall be " + + "enabled.", + xref: { document: "cluster", section: "1.15.6.1" } + }), + + Attribute({ + name: "Latch", id: 0x1, type: "AlarmBitmap", access: "R V", conformance: "RESET", default: 0, + quality: "F", + details: "Indicates a bitmap where each bit set in the Latch attribute shall indicate that the corresponding " + + "alarm will be latched when set, and will not reset to inactive when the underlying condition which " + + "caused the alarm is no longer present, and so requires an explicit reset using the Reset command.", + xref: { document: "cluster", section: "1.15.6.2" } + }), + + Attribute({ + name: "State", id: 0x2, type: "AlarmBitmap", access: "R V", conformance: "M", default: 0, + details: "Indicates a bitmap where each bit shall represent the state of an alarm. The value of true means " + + "the alarm is active, otherwise the alarm is inactive.", + xref: { document: "cluster", section: "1.15.6.3" } + }), + + Attribute({ + name: "Supported", id: 0x3, type: "AlarmBitmap", access: "R V", conformance: "M", default: 0, + quality: "F", + details: "Indicates a bitmap where each bit shall represent whether or not an alarm is supported. The value " + + "of true means the alarm is supported, otherwise the alarm is not supported." + + "\n" + + "If an alarm is not supported, the corresponding bit in Mask, Latch, and State shall be false.", + xref: { document: "cluster", section: "1.15.6.4" } + }), + + Event( + { + name: "Notify", id: 0x0, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when one or more alarms change state, and shall have these fields:", + xref: { document: "cluster", section: "1.15.8.1" } + }, + Field({ + name: "Active", id: 0x1, type: "AlarmBitmap", conformance: "M", default: 0, + details: "This field shall indicate those alarms that have become active.", + xref: { document: "cluster", section: "1.15.8.1.1" } + }), + Field({ + name: "Inactive", id: 0x2, type: "AlarmBitmap", conformance: "M", default: 0, + details: "This field shall indicate those alarms that have become inactive.", + xref: { document: "cluster", section: "1.15.8.1.2" } + }), + + Field({ + name: "State", id: 0x3, type: "AlarmBitmap", conformance: "M", default: 0, + details: "This field shall be a copy of the new State attribute value that resulted in the event being " + + "generated. That is, this field shall have all the bits in Active set and shall NOT have any of the " + + "bits in Inactive set.", + xref: { document: "cluster", section: "1.15.8.1.4" } + }), + + Field({ + name: "Mask", id: 0x4, type: "AlarmBitmap", conformance: "M", default: 0, + details: "This field shall be a copy of the Mask attribute when this event was generated.", + xref: { document: "cluster", section: "1.15.8.1.3" } + }) + ), + + Command( + { + name: "Reset", id: 0x0, access: "O", conformance: "RESET", direction: "request", response: "status", + details: "This command resets active and latched alarms (if possible). Any generated Notify event shall " + + "contain fields that represent the state of the server after the command has been processed.", + xref: { document: "cluster", section: "1.15.7.1" } + }, + + Field({ + name: "Alarms", id: 0x0, type: "AlarmBitmap", conformance: "M", default: 0, + details: "This field shall indicate a bitmap where each bit set in this field corresponds to an alarm that " + + "shall be reset to inactive in the State attribute unless the alarm definition requires manual " + + "intervention. If the alarms indicated are successfully reset, the response status code shall be " + + "SUCCESS, otherwise, the response status code shall be FAILURE.", + xref: { document: "cluster", section: "1.15.7.1.1" } + }) + ), + + Command( + { + name: "ModifyEnabledAlarms", id: 0x1, access: "O", conformance: "O", direction: "request", + response: "status", + details: "This command allows a client to request that an alarm be enabled or suppressed at the server.", + xref: { document: "cluster", section: "1.15.7.2" } + }, + + Field({ + name: "Mask", id: 0x0, type: "AlarmBitmap", conformance: "M", default: 0, + + details: "This field shall indicate a bitmap where each bit set in the this field corresponds to an alarm " + + "that SHOULD be enabled or suppressed. A value of 1 shall indicate that the alarm SHOULD be enabled " + + "while a value of 0 shall indicate that the alarm SHOULD be suppressed." + + "\n" + + "A server that receives this command with a Mask that includes bits that are set for unknown alarms " + + "shall respond with a status code of INVALID_COMMAND." + + "\n" + + "A server that receives this command with a Mask that includes bits that are set for alarms which " + + "are not supported, as indicated in the Supported attribute, shall respond with a status code of " + + "INVALID_COMMAND." + + "\n" + + "A server that is unable to enable a currently suppressed alarm, or is unable to suppress a " + + "currently enabled alarm shall respond with a status code of FAILURE; otherwise the server shall " + + "respond with a status code of SUCCESS." + + "\n" + + "On a SUCCESS case, the server shall also change the value of the Mask attribute to the value of the " + + "Mask field from this command. After that the server shall also update the value of its State " + + "attribute to reflect the status of the new alarm set as indicated by the new value of the Mask " + + "attribute.", + + xref: { document: "cluster", section: "1.15.7.2.1" } + }) + ), + + Datatype({ + name: "AlarmBitmap", type: "map32", + details: "This data type shall be a map32 with values defined by the derived cluster. The meaning of each bit " + + "position shall be consistent for all attributes in a derived cluster. That is, if bit 0 is defined " + + "for an alarm, the Latch, State, and Supported information for that alarm are also bit 0.", + xref: { document: "cluster", section: "1.15.5.1" } + }) + ), + + Cluster( + { + name: "Messages", id: 0x97, classification: "application", pics: "MESS", + details: "This cluster provides an interface for passing messages to be presented by a device.", + xref: { document: "cluster", section: "1.16" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.16.4" } }, + + Field({ + name: "CONF", conformance: "O", constraint: "0", description: "ReceivedConfirmation", + details: "This feature shall indicate that the device can get confirmation from a user that the message was " + + "received.", + xref: { document: "cluster", section: "1.16.4.1" } + }), + + Field({ + name: "RESP", conformance: "[CONF]", constraint: "1", description: "ConfirmationResponse", + details: "This feature shall indicate that the device is capable of presenting a list of responses to the " + + "user and recording the user’s choice of response.", + xref: { document: "cluster", section: "1.16.4.2" } + }), + + Field({ + name: "RPLY", conformance: "[CONF]", constraint: "2", description: "ConfirmationReply", + details: "This feature shall indicate that the device is capable of collecting a free-form text response to a " + + "message.", + xref: { document: "cluster", section: "1.16.4.3" } + }), + + Field({ + name: "PROT", conformance: "O", constraint: "3", description: "ProtectedMessages", + details: "This feature shall indicate that the device is capable of requiring the user to authenticate before " + + "viewing a message; e.g. entering a PIN or password before viewing a message with billing " + + "information.", + xref: { document: "cluster", section: "1.16.4.4" } + }) + ), + + Attribute( + { + name: "Messages", id: 0x0, type: "list", access: "R F V", conformance: "M", constraint: "max 8", + default: [], + details: "Indicates a list of queued messages." + + "\n" + + "In addition to filtering based upon fabric, to preserve user privacy, the server may further limit " + + "the set of messages returned in a read request. At minimum, the server shall return to a client " + + "those messages that the client itself created/submitted.", + xref: { document: "cluster", section: "1.16.6.1" } + }, + + Field({ name: "entry", type: "MessageStruct" }) + ), + + Attribute( + { + name: "ActiveMessageIDs", id: 0x1, type: "list", access: "R V", conformance: "M", + constraint: "max 8", default: [], + details: "Indicates a list of the MessageIDs of the Messages currently being presented. If this list is " + + "empty, no messages are currently being presented." + + "\n" + + "This list shall NOT be fabric-scoped; it shall contain MessageIDs for all Messages being presented, " + + "no matter what fabric the client that queued them is on.", + xref: { document: "cluster", section: "1.16.6.2" } + }, + + Field({ name: "entry", type: "MessageID" }) + ), + + Event( + { + name: "MessageQueued", id: 0x0, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when a message is added to the messages attribute.", + xref: { document: "cluster", section: "1.16.8.1" } + }, + Field({ + name: "MessageId", id: 0x0, type: "MessageID", access: "S", conformance: "M", + details: "This field shall indicate the MessageID for newly added message.", + xref: { document: "cluster", section: "1.16.8.1.1" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Event( + { + name: "MessagePresented", id: 0x1, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when the message is presented to the user.", + xref: { document: "cluster", section: "1.16.8.2" } + }, + Field({ + name: "MessageId", id: 0x0, type: "MessageID", access: "S", conformance: "M", + details: "This field shall indicate the MessageID for the message being presented.", + xref: { document: "cluster", section: "1.16.8.2.1" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Event( + { + name: "MessageComplete", id: 0x2, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when the message is confirmed by the user, or when the Duration of " + + "the message has elapsed without confirmation.", + xref: { document: "cluster", section: "1.16.8.3" } + }, + + Field({ + name: "MessageId", id: 0x0, type: "MessageID", access: "S", conformance: "M", + details: "This field shall indicate the MessageID for the message being confirmed.", + xref: { document: "cluster", section: "1.16.8.3.1" } + }), + + Field({ + name: "ResponseId", id: 0x1, type: "uint32", access: "S", conformance: "RESP", default: null, + quality: "X", + details: "This field shall indicate the MessageResponseID selected by the user. If there was no response " + + "before the Duration of the message has elapsed, this field shall be null.", + xref: { document: "cluster", section: "1.16.8.3.2" } + }), + + Field({ + name: "Reply", id: 0x2, type: "string", access: "S", conformance: "RPLY", constraint: "max 256", + default: null, quality: "X", + details: "This field shall indicate a user-provided reply to the message. If there was no reply, or the " + + "message did not have the ReplyRequired bit set, this field shall be null.", + xref: { document: "cluster", section: "1.16.8.3.3" } + }), + + Field({ + name: "FutureMessagesPreference", id: 0x3, type: "FutureMessagePreferenceEnum", access: "S", + conformance: "M", default: null, quality: "X" + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Command( + { + name: "PresentMessagesRequest", id: 0x0, access: "F O", conformance: "M", direction: "request", + response: "status", + + details: "Upon receipt, this shall cause the message in the passed fields to be appended to the Messages " + + "attribute." + + "\n" + + "If appending the message would cause the number of messages to be greater than the capacity of the " + + "list, the device shall NOT append any message to Messages, and shall return a status code of " + + "RESOURCE_EXHAUSTED." + + "\n" + + "When displaying a message in response to this command, an indication (ex. visual) of the origin " + + "node of the command shall be provided. This could be in the form of a friendly name label which " + + "uniquely identifies the node to the user. This friendly name label is typically assigned by the " + + "Matter Admin at the time of commissioning and, when it’s a device, is often editable by the user. " + + "It might be a combination of a company name and friendly name, for example, ”Acme” or “Acme " + + "Streaming Service on Alice’s Phone”." + + "\n" + + "NOTE" + + "\n" + + "It is currently not specified where the friendly name label can be found on the node, meaning that " + + "clients SHOULD NOT rely on a certain method they happen to observe in a particular server instance, " + + "since other instances could employ a different method." + + "\n" + + "The device SHOULD make it possible for the user to view which nodes have access to this cluster and " + + "to individually remove privileges for each node.", + + xref: { document: "cluster", section: "1.16.7.1" } + }, + + Field({ + name: "MessageId", id: 0x0, type: "MessageID", conformance: "M", + details: "This field shall indicate a globally unique ID for this message. See MessageID.", + xref: { document: "cluster", section: "1.16.7.1.1" } + }), + Field({ + name: "Priority", id: 0x1, type: "MessagePriorityEnum", conformance: "M", default: 0, + details: "This field shall indicate the priority level for this message. See Priority.", + xref: { document: "cluster", section: "1.16.7.1.2" } + }), + Field({ + name: "MessageControl", id: 0x2, type: "MessageControlBitmap", conformance: "M", default: 0, + details: "This field shall indicate control information related to the message. See MessageControl.", + xref: { document: "cluster", section: "1.16.7.1.3" } + }), + + Field({ + name: "StartTime", id: 0x3, type: "epoch-s", conformance: "M", default: 0, quality: "X", + details: "This field shall indicate the time in UTC at which the message becomes available to be presented. A " + + "null value shall indicate \"now.\" See StartTime.", + xref: { document: "cluster", section: "1.16.7.1.4" } + }), + + Field({ + name: "Duration", id: 0x4, type: "uint64", conformance: "M", default: 0, quality: "X", + details: "This field shall indicate the amount of time, in milliseconds, after the StartTime during which the " + + "message is available to be presented. A null value shall indicate \"until changed\". See Duration.", + xref: { document: "cluster", section: "1.16.7.1.5" } + }), + + Field({ + name: "MessageText", id: 0x5, type: "string", conformance: "M", constraint: "max 256", + details: "This field shall indicate a string containing the message to be presented. See MessageText.", + xref: { document: "cluster", section: "1.16.7.1.6" } + }), + + Field( + { + name: "Responses", id: 0x6, type: "list", conformance: "RESP", constraint: "max 4", default: [], + + details: "This field shall indicate a list of potential responses to the message. The entries in this list " + + "shall have unique values of MessageResponseID." + + "\n" + + "If the ResponseRequired bit is set on the message but this list is empty, the device shall provide " + + "a generic acknowledgement button, e.g. \"OK\"." + + "\n" + + "If the ResponseRequired bit is not set on the message, this list shall be ignored. See Responses.", + + xref: { document: "cluster", section: "1.16.7.1.7" } + }, + + Field({ name: "entry", type: "MessageResponseOptionStruct" }) + ) + ), + + Command( + { + name: "CancelMessagesRequest", id: 0x1, access: "F O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "1.16.7.2" } + }, + + Field( + { + name: "MessageIDs", id: 0x0, type: "list", conformance: "M", constraint: "max 8", + + details: "This field shall indicate the MessageIDs for the messages being cancelled." + + "\n" + + "Cancelling a message shall cause it to be removed from Messages, cause its MessageID to be removed " + + "from ActiveMessageIDs and cause any active presentation of the message to cease." + + "\n" + + "Message IDs in this command that indicate messages that do not exist in Messages, or that are not " + + "scoped to the fabric of the sender, shall be ignored.", + + xref: { document: "cluster", section: "1.16.7.2.1" } + }, + + Field({ name: "entry", type: "MessageID" }) + ) + ), + + Datatype({ + name: "MessageID", type: "octstr", constraint: "16", + details: "This data type is an octstr of fixed length 16, containing the binary encoding of a UUID as " + + "specified in RFC 4122.", + xref: { document: "cluster", section: "1.16.5.1" } + }), + + Datatype( + { + name: "MessageControlBitmap", type: "map16", + details: "This data type is derived from map16, and indicates control information related to a message.", + xref: { document: "cluster", section: "1.16.5.2" } + }, + + Field({ + name: "ConfirmationRequired", constraint: "0", + description: "Message requires confirmation from user", + details: "This bit shall indicate that the message originator requests a confirmation of receipt by the user. " + + "If confirmation is required, the device SHOULD present the message until it is either confirmed by " + + "the user selecting a confirmation option, or the message expires.", + xref: { document: "cluster", section: "1.16.5.2.1" } + }), + + Field({ + name: "ResponseRequired", constraint: "1", description: "Message requires response from user", + details: "This bit shall indicate that a MessagePresented event SHOULD be generated based on the response of " + + "the user to the message.", + xref: { document: "cluster", section: "1.16.5.2.2" } + }), + + Field({ + name: "ReplyMessage", constraint: "2", description: "Message supports reply message from user", + details: "This bit shall indicate that a free-form user reply is to be included in the confirmation of " + + "receipt.", + xref: { document: "cluster", section: "1.16.5.2.3" } + }), + + Field({ + name: "MessageConfirmed", constraint: "3", description: "Message has already been confirmed", + details: "This bit shall indicate the current confirmation state of a message, which is useful in the event " + + "that there are multiple Messages cluster client devices on a network.", + xref: { document: "cluster", section: "1.16.5.2.4" } + }), + + Field({ + name: "MessageProtected", constraint: "4", description: "Message required PIN/password protection", + details: "This bit shall indicate that user authentication (e.g. by password or PIN) is required before " + + "viewing a message.", + xref: { document: "cluster", section: "1.16.5.2.5" } + }) + ), + + Datatype( + { + name: "FutureMessagePreferenceEnum", type: "enum8", + details: "A display device may include this preference in the MessageComplete event as a hint to clients " + + "about how to handle future similar messages.", + xref: { document: "cluster", section: "1.16.5.3" } + }, + + Field({ name: "Allowed", id: 0x0, conformance: "M", description: "Similar messages are allowed" }), + Field({ name: "Increased", id: 0x1, conformance: "M", description: "Similar messages should be sent more often" }), + Field({ name: "Reduced", id: 0x2, conformance: "M", description: "Similar messages should be sent less often" }), + Field({ name: "Disallowed", id: 0x3, conformance: "M", description: "Similar messages should not be sent" }), + Field({ name: "Banned", id: 0x4, conformance: "M", description: "No further messages should be sent" }) + ), + + Datatype( + { + name: "MessagePriorityEnum", type: "enum8", + details: "Priority SHOULD be used to decide which messages to show when the number of eligible messages is " + + "larger than the device’s capacity to present them.", + xref: { document: "cluster", section: "1.16.5.4" } + }, + + Field({ + name: "Low", id: 0x0, conformance: "M", + description: "Message to be transferred with a low level of importance" + }), + Field({ + name: "Medium", id: 0x1, conformance: "M", + description: "Message to be transferred with a medium level of importance" + }), + Field({ + name: "High", id: 0x2, conformance: "M", + description: "Message to be transferred with a high level of importance" + }), + Field({ + name: "Critical", id: 0x3, conformance: "M", + description: "Message to be transferred with a critical level of importance" + }) + ), + + Datatype( + { + name: "MessageStruct", type: "struct", + details: "This represents a single message.", + xref: { document: "cluster", section: "1.16.5.5" } + }, + Field({ + name: "MessageId", id: 0x0, type: "MessageID", access: "S", conformance: "M", + details: "This field shall indicate a globally unique ID for this message.", + xref: { document: "cluster", section: "1.16.5.5.1" } + }), + Field({ + name: "Priority", id: 0x1, type: "MessagePriorityEnum", access: "S", conformance: "M", default: 0, + details: "This field shall indicate the priority level for this message.", + xref: { document: "cluster", section: "1.16.5.5.2" } + }), + + Field({ + name: "MessageControl", id: 0x2, type: "MessageControlBitmap", access: "S", conformance: "M", + default: 0, + details: "This field shall indicate control information related to the message.", + xref: { document: "cluster", section: "1.16.5.5.3" } + }), + + Field({ + name: "StartTime", id: 0x3, type: "epoch-s", access: "S", conformance: "M", default: 0, + quality: "X", + details: "This field shall indicate the time in UTC at which the message becomes available to be presented. A " + + "null value shall indicate \"now.\"", + xref: { document: "cluster", section: "1.16.5.5.4" } + }), + + Field({ + name: "Duration", id: 0x4, type: "uint64", access: "S", conformance: "M", default: 0, quality: "X", + details: "This field shall indicate the amount of time, in milliseconds, after the StartTime during which the " + + "message is available to be presented. A null value shall indicate \"until changed\".", + xref: { document: "cluster", section: "1.16.5.5.5" } + }), + + Field({ + name: "MessageText", id: 0x5, type: "string", access: "S", conformance: "M", constraint: "max 256", + details: "This field shall indicate a string containing the message to be presented.", + xref: { document: "cluster", section: "1.16.5.5.6" } + }), + + Field( + { + name: "Responses", id: 0x6, type: "list", access: "S", conformance: "RESP", constraint: "max 4", + default: [], + + details: "This field shall indicate a list of potential responses to the message. The entries in this list " + + "shall have unique values of MessageResponseID." + + "\n" + + "If the ResponseRequired bit is set on the message but this list is empty, the device shall provide " + + "a generic acknowledgement button, e.g. \"OK\"." + + "\n" + + "If the ResponseRequired bit is not set on the message, this list shall be ignored.", + + xref: { document: "cluster", section: "1.16.5.5.7" } + }, + + Field({ name: "entry", type: "MessageResponseOptionStruct" }) + ), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "MessageResponseOptionStruct", type: "struct", + details: "This represents a possible response to a message.", + xref: { document: "cluster", section: "1.16.5.6" } + }, + + Field({ + name: "MessageResponseId", id: 0x0, type: "uint32", conformance: "M", constraint: "min 1", + details: "This field shall indicate a unique unsigned 32-bit number identifier for this message response " + + "option.", + xref: { document: "cluster", section: "1.16.5.6.1" } + }), + + Field({ + name: "Label", id: 0x1, type: "string", conformance: "M", constraint: "max 32", + details: "This field shall indicate the text for this option; e.g. \"Yes\", \"No\", etc.", + xref: { document: "cluster", section: "1.16.5.6.2" } + }) + ) + ), + + Cluster( + { + name: "ServiceArea", id: 0x150, classification: "application", pics: "SEAR", + + details: "This cluster provides an interface for controlling the areas where a device should operate, for " + + "reporting the status at each area, and for querying the current area." + + "\n" + + "The device may operate at one area at a time, as in the case of a mobile device, such as a robot. " + + "Other devices may operate at (service) multiple areas simultaneously, as in the case of a sensor " + + "that can monitor multiple areas. This cluster specification uses the term \"operate\" to describe " + + "both the operating and servicing actions, regardless of the device type." + + "\n" + + "The cluster allows the client to select one or more areas on the server, to indicate where the " + + "device SHOULD attempt to operate. An area is one of a list of options that may be presented by a " + + "client for a user choice, or understood by the client, via the semantic data of the area." + + "\n" + + "The area semantic data is a combination of semantic tags, indicating one or more of the following: " + + "the building floor, area type, landmark, and relative position.", + + xref: { document: "cluster", section: "1.17" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.17.4" } }, + + Field({ + name: "SELRUN", constraint: "0", description: "SelectWhileRunning", + details: "This feature indicates whether this device allows changing the selected areas, by using the " + + "SelectAreas command, while operating.", + xref: { document: "cluster", section: "1.17.4.1" } + }), + + Field({ + name: "PROG", constraint: "1", description: "ProgressReporting", + details: "The device implements the progress reporting feature" + }), + Field({ name: "MAPS", constraint: "2", description: "Maps", details: "The device has map support" }) + ), + + Attribute( + { + name: "SupportedAreas", id: 0x0, type: "list", access: "R V", conformance: "M", + constraint: "max 255", + + details: "This attribute shall contain the list of areas that can be included in the SelectedAreas " + + "attribute’s list. Each item in this list represents a unique area, as indicated by the AreaID field " + + "of AreaStruct." + + "\n" + + "Each entry in this list shall have a unique value for the AreaID field." + + "\n" + + "If the SupportedMaps attribute is not empty, each entry in this list shall have a unique value for " + + "the combination of the MapID and AreaInfo fields." + + "\n" + + "If the SupportedMaps attribute is empty, each entry in this list shall have a unique value for the " + + "AreaInfo field and shall have the MapID field set to null." + + "\n" + + "An empty value indicates that the device is currently unable to provide the list of supported areas." + + "\n" + + "NOTE" + + "\n" + + "due to the maximum size of this list and to the fact that the entries may include strings (see " + + "LocationName), care must be taken by implementers to avoid creating a data structure that is overly " + + "large, which can result in significant latency in accessing this attribute." + + "\n" + + "The value of this attribute may change at any time via an out-of-band interaction outside of the " + + "server, such as interactions with a user interface, or due to internal device changes." + + "\n" + + "When removing entries in the SupportedAreas attribute list the server shall adjust the values of " + + "the SelectedAreas, CurrentArea, and Progress attributes such that they only reference valid entries " + + "in the updated SupportedAreas attribute list. These changes to the SelectedAreas, CurrentArea, and " + + "Progress attributes may result in the server setting some or all of them to empty (for " + + "SelectedAreas and Progress) or null (for CurrentArea), or updating them with data that matches the " + + "constraints from the description of the respective attributes. These actions are required to ensure " + + "having a consistent representation of the maps and locations available to the clients." + + "\n" + + "The SupportedAreas attribute list changes mentioned above SHOULD NOT be allowed while the device is " + + "operating, to reduce the impact on the clients, and the potential confusion for the users." + + "\n" + + "A few examples are provided below. Valid list of areas:" + + "\n" + + " • AreaID=0, LocationName=\"yellow bedroom\", MapID=null" + + "\n" + + " • AreaID=1, LocationName=\"orange bedroom\", MapID=null Valid list of areas:" + + "\n" + + " • AreaID=5, LocationName=\"hallway\", MapID=1" + + "\n" + + " • AreaID=3, LocationName=\"hallway\", MapID=2", + + xref: { document: "cluster", section: "1.17.6.1" } + }, + + Field({ name: "entry", type: "AreaStruct" }) + ), + + Attribute( + { + name: "SupportedMaps", id: 0x1, type: "list", access: "R V", conformance: "MAPS", + constraint: "max 255", + + details: "This attribute shall contain the list of supported maps." + + "\n" + + "A map is a full or a partial representation of a home, known to the device. For example:" + + "\n" + + " • a single level home may be represented using a single map" + + "\n" + + " • a two level home may be represented using two maps, one for each level" + + "\n" + + " • a single level home may be represented using two maps, each including a different set of rooms, " + + " such as \"map of living room and kitchen\" and \"map of bedrooms and hallway\"" + + "\n" + + " • a single level home may be represented using one map for the indoor areas (living room, " + + " bedrooms etc.) and one for the outdoor areas (garden, swimming pool etc.)" + + "\n" + + "Each map includes one or more areas - see the SupportedAreas attribute. In the context of this " + + "cluster specification, a map is effectively a group label for a set of areas, rather than a " + + "graphical representation that the clients can display to the users. The clients that present the " + + "list of available areas for user selection (see the SelectAreas command) may choose to filter the " + + "SupportedAreas list based on the associated map. For example, the clients may allow the user to " + + "indicate that the device is to operate on the first floor, and allow the user to choose only from " + + "the areas situated on that level." + + "\n" + + "If empty, that indicates that the device is currently unable to provide this information. Each " + + "entry in this list shall have a unique value for the MapID field." + + "\n" + + "Each entry in this list shall have a unique value for the Name field." + + "\n" + + "NOTE" + + "\n" + + "due to the maximum size of this list and to the fact that the entries may include strings (see the " + + "Name field of the MapStruct data type), care must be taken by implementers to avoid creating a data " + + "structure that is overly large, which can result in significant latency in accessing this attribute." + + "\n" + + "The value of this attribute may change at any time via an out-of-band interaction outside of the " + + "server, such as interactions with a user interface." + + "\n" + + "When updating the SupportedMaps attribute list by deleting entries, or by setting the attribute to " + + "an empty list, the SupportedLocations attribute shall be updated such that all entries in that list " + + "meet the constraints indicated in the description of the SupportedLocations attribute. This may " + + "result in" + + "\n" + + "the server removing entries from the SupportedAreas attribute list. See the SupportedAreas " + + "attribute description for the implications of changing that attribute." + + "\n" + + "The SupportedMaps attribute list changes mentioned above SHOULD NOT be allowed while the device is " + + "operating, to reduce the impact on the clients, and the potential confusion for the users.", + + xref: { document: "cluster", section: "1.17.6.2" } + }, + + Field({ name: "entry", type: "MapStruct" }) + ), + + Attribute( + { + name: "SelectedAreas", id: 0x2, type: "list", access: "R V", conformance: "M", constraint: "desc", + default: [], + + details: "Indicates the set of areas where the device SHOULD attempt to operate." + + "\n" + + "The mobile devices may travel without operating across any areas while attempting to reach the " + + "areas indicated by the SelectedAreas attribute. For example, a robotic vacuum cleaner may drive " + + "without cleaning when traveling without operating." + + "\n" + + "If this attribute is empty, the device is not constrained to operate in any specific areas. If this " + + "attribute is not empty:" + + "\n" + + " • each item in this list shall match the AreaID field of an entry in the SupportedAreas " + + " attribute’s list" + + "\n" + + " • each entry in this list shall have a unique value", + + xref: { document: "cluster", section: "1.17.6.3" } + }, + + Field({ name: "entry", type: "uint32" }) + ), + + Attribute({ + name: "CurrentArea", id: 0x3, type: "uint32", access: "R V", conformance: "desc", + constraint: "desc", default: null, quality: "X", + + details: "If the device is mobile, this attribute shall indicate the area where the device is currently " + + "located, regardless of whether it is operating or not, such as while traveling between areas." + + "\n" + + "If the device is not mobile and can operate at multiple areas sequentially, this attribute shall " + + "indicate the area which is currently being serviced, or the area which is currently traversed by " + + "the device. For example, a camera device may use this attribute to indicate which area it currently " + + "takes video of (serviced area) or which area it currently has in view but not taking video of (e.g. " + + "an area which is traversed while panning)." + + "\n" + + "NOTE" + + "\n" + + "A device may traverse an area regardless of the status of the area (pending, skipped, or completed)." + + "\n" + + "If a device can simultaneously operate at multiple areas, such as in the case of a sensor that can " + + "monitor multiple areas at the same time, the CurrentArea attribute shall NOT be implemented, since " + + "it doesn’t apply. Else this attribute shall be optionally implemented." + + "\n" + + "A null value indicates that the device is currently unable to provide this information. For " + + "example, the device is traversing an unknown area, or the SupportedAreas attribute was updated and " + + "the area where the device is located was removed from that list." + + "\n" + + "If not null, the value of this attribute shall match the AreaID field of an entry on the " + + "SupportedAreas attribute’s list.", + + xref: { document: "cluster", section: "1.17.6.4" } + }), + + Attribute({ + name: "EstimatedEndTime", id: 0x4, type: "epoch-s", access: "R V", conformance: "[CurrentArea]", + default: null, quality: "X Q", + + details: "Indicates the estimated Epoch time for completing operating at the area indicated by the " + + "CurrentArea attribute, in seconds." + + "\n" + + "A value of 0 means that the operation has completed." + + "\n" + + "When this attribute is null, that represents that there is no time currently defined until " + + "operation completion. This may happen, for example, because no operation is in progress or because " + + "the completion time is unknown." + + "\n" + + "Null if the CurrentArea attribute is null." + + "\n" + + "If the Progress attribute is available, and it contains an entry matching CurrentArea, the server " + + "may use the time estimate provided in the InitialTimeEstimate field of that entry to compute the " + + "EstimatedEndTime attribute." + + "\n" + + "The value of this attribute shall only be reported in the following cases:" + + "\n" + + " • when it changes to or from 0" + + "\n" + + " • when it decreases" + + "\n" + + " • when it changes to or from null" + + "\n" + + "NOTE" + + "\n" + + "If the device is capable of pausing its operation, this attribute may be set to null, to indicate " + + "that completion time is unknown, or increment the value while being in the paused state.", + + xref: { document: "cluster", section: "1.17.6.5" } + }), + + Attribute( + { + name: "Progress", id: 0x5, type: "list", access: "R V", conformance: "PROG", constraint: "max 255", + default: [], + + details: "Indicates the operating status at one or more areas. Each entry in this list shall have a unique " + + "value for the AreaID field." + + "\n" + + "For each entry in this list, the AreaID field shall match an entry on the SupportedAreas " + + "attribute’s list." + + "\n" + + "When this attribute is empty, that represents that no progress information is currently available." + + "\n" + + "If the SelectedAreas attribute is empty, indicating the device is not constrained to operate in any " + + "specific areas, the Progress attribute list may change while the device operates, due to the device " + + "adding new entries dynamically, when it determines which ones it can attempt to operate at." + + "\n" + + "If the SelectedAreas attribute is not empty, and the device starts operating:" + + "\n" + + " • the Progress attribute list shall be updated so each entry of SelectedAreas has a matching " + + " Progress list entry, based on the AreaID field" + + "\n" + + " • the length of the Progress and SelectedAreas list shall be the same" + + "\n" + + " • the entries in the Progress list shall be initialized by the server, by having their status set " + + " to Pending or Operating, and the TotalOperationalTime field set to null" + + "\n" + + "When the device ends operation unexpectedly, such as due to an error, the server shall update all " + + "Progress list entries with the Status field set to Operating or Pending to Skipped." + + "\n" + + "When the device finishes operating, successfully or not, it shall NOT change the Progress " + + "attribute, except in the case of an unexpected end of operation as described above, or due to " + + "changes to the SupportedMaps or SupportedAreas attributes, so the clients can retrieve the progress " + + "information at that time." + + "\n" + + "NOTE" + + "\n" + + "if the device implements the Operational Status cluster, or a derivation of it, in case the device " + + "fails to service any locations in the SelectedAreas list before ending the operation, it SHOULD use " + + "the Operational Status cluster to indicate that the device was unable to complete the operation " + + "(see the UnableToCompleteOperation error from that cluster specification). The clients SHOULD then " + + "read the Progress attribute, and indicate which areas have been successfully serviced (marked as " + + "completed).", + + xref: { document: "cluster", section: "1.17.6.6" } + }, + + Field({ name: "entry", type: "ProgressStruct" }) + ), + + Command( + { + name: "SelectAreas", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "SelectAreasResponse", + details: "This command is used to select a set of device areas, where the device is to operate." + + "\n" + + "On receipt of this command the device shall respond with a SelectAreasResponse command.", + xref: { document: "cluster", section: "1.17.7.1" } + }, + + Field( + { + name: "NewAreas", id: 0x0, type: "list", conformance: "M", constraint: "desc", + + details: "This field indicates which areas the device is to operate at." + + "\n" + + "If this field is empty, that indicates that the device is to operate without being constrained to " + + "any specific areas, and the operation will not allow skipping using the SkipArea Command, otherwise " + + "the field shall be a list of unique values that match the AreaID field of entries on the " + + "SupportedAreas list.", + + xref: { document: "cluster", section: "1.17.7.1.1" } + }, + + Field({ name: "entry", type: "uint32" }) + ) + ), + + Command( + { + name: "SelectAreasResponse", id: 0x1, access: "O", conformance: "M", direction: "response", + details: "This command is sent by the device on receipt of the SelectAreas command.", + xref: { document: "cluster", section: "1.17.7.2" } + }, + + Field({ + name: "Status", id: 0x0, type: "SelectAreasStatus", conformance: "M", + + details: "If the Status field is set to Success or UnsupportedArea, the server may use a non-empty string for " + + "the StatusText field to provide additional information. For example, if Status is set to Unsupport" + + "\n" + + "edArea, the server may use StatusText to indicate which areas are unsupported." + + "\n" + + "If the Status field is not set to Success, or UnsupportedArea, the StatusText field shall include a " + + "vendor-defined error description which can be used to explain the error to the user. For example, " + + "if the Status field is set to InvalidInMode, the StatusText field SHOULD indicate why the request " + + "is not allowed, given the current mode of the device, which may involve other clusters.", + + xref: { document: "cluster", section: "1.17.7.2.1" } + }), + + Field({ name: "StatusText", id: 0x1, type: "string", conformance: "M", constraint: "max 256" }) + ), + + Command( + { + name: "SkipArea", id: 0x2, access: "O", conformance: "desc", direction: "request", + response: "SkipAreaResponse", + + details: "This command is used to skip the given area, and to attempt operating at other areas on the " + + "SupportedAreas attribute list." + + "\n" + + "This command shall NOT be implemented if the CurrentArea attribute and the Progress attribute are " + + "both not implemented. Else, this command shall be optionally implemented." + + "\n" + + "On receipt of this command the device shall respond with a SkipAreaResponse command.", + + xref: { document: "cluster", section: "1.17.7.3" } + }, + + Field({ + name: "SkippedArea", id: 0x0, type: "uint32", conformance: "M", constraint: "desc", + details: "The SkippedArea field indicates the area to be skipped." + + "\n" + + "The SkippedArea field shall match an entry in the SupportedAreas list.", + xref: { document: "cluster", section: "1.17.7.3.1" } + }) + ), + + Command( + { + name: "SkipAreaResponse", id: 0x3, access: "O", conformance: "SkipArea", direction: "response", + details: "This command is sent by the device on receipt of the SkipArea command.", + xref: { document: "cluster", section: "1.17.7.4" } + }, + + Field({ + name: "Status", id: 0x0, type: "SkipAreaStatus", conformance: "M", + + details: "If the Status field is set to Success or InvalidAreaList, the server may use a non-empty string for " + + "the StatusText field to provide additional information. For example, if Status is set to " + + "InvalidAreaList, the server may use StatusText to indicate why this list is invalid." + + "\n" + + "If the Status field is not set to Success or InvalidAreaList, the StatusText field shall include a " + + "vendor defined error description which can be used to explain the error to the user. For example, " + + "if the Status field is set to InvalidInMode, the StatusText field SHOULD indicate why the request " + + "is not allowed, given the current mode of the device, which may involve other clusters.", + + xref: { document: "cluster", section: "1.17.7.4.1" } + }), + + Field({ name: "StatusText", id: 0x1, type: "string", conformance: "M", constraint: "max 256" }) + ), + + Datatype( + { + name: "LandmarkInfoStruct", type: "struct", + details: "The data from this structure indicates a landmark and position relative to the landmark.", + xref: { document: "cluster", section: "1.17.5.1" } + }, + + Field({ + name: "LandmarkTag", id: 0x0, type: "tag", conformance: "M", + details: "This field shall indicate that the area is associated with a landmark." + + "\n" + + "This field shall be the ID of a landmark semantic tag, located within the Common Landmark " + + "Namespace. For example, this tag may indicate that the area refers to an area next to a table.", + xref: { document: "cluster", section: "1.17.5.1.1" } + }), + + Field({ + name: "RelativePositionTag", id: 0x1, type: "tag", conformance: "M", quality: "X", + + details: "This field shall identify the position of the area relative to a landmark. This is a static " + + "description of a zone known to the server, and this field never reflects the device’s own proximity " + + "or position relative to the landmark, but that of the zone." + + "\n" + + "This field shall be the ID of a relative position semantic tag, located within the Common Relative " + + "Position Namespace." + + "\n" + + "If the RelativePositionTag field is null, this field indicates proximity to the landmark. " + + "Otherwise, the RelativePositionTag field indicates the position of the area relative to the " + + "landmark indicated by the LandmarkTag field. For example, this tag, in conjunction with the " + + "LandmarkTag field, may indicate that the area refers to a zone under a table.", + + xref: { document: "cluster", section: "1.17.5.1.2" } + }) + ), + + Datatype( + { + name: "AreaInfoStruct", type: "struct", + + details: "The data from this structure indicates the name and/or semantic data describing an area, as " + + "detailed below." + + "\n" + + "This data type includes the LocationInfo field, with the following fields: LocationName, " + + "FloorNumber, AreaType. Additional semantic data may be available in the LandmarkInfo field." + + "\n" + + "For an area description to be meaningful, it shall have at least one of the following:" + + "\n" + + " • a non-empty name (LocationInfo’s LocationName field) OR" + + "\n" + + " • some semantic data (one or more of these: FloorNumber, AreaType or LandmarkTag) The normative " + + " text from the remainder of this section describes these constraints." + + "\n" + + "If the LocationInfo field is null, the LandmarkInfo field shall NOT be null. If the LandmarkInfo " + + "field is null, the LocationInfo field shall NOT be null." + + "\n" + + "If LocationInfo is not null, and its LocationName field is an empty string, at least one of the " + + "following shall NOT be null:" + + "\n" + + " • LocationInfo’s FloorNumber field" + + "\n" + + " • LocationInfo’s AreaType field" + + "\n" + + " • LandmarkInfo field" + + "\n" + + "If all three of the following are null, LocationInfo’s LocationName field shall NOT be an empty " + + "string:" + + "\n" + + " • LocationInfo’s FloorNumber field" + + "\n" + + " • LocationInfo’s AreaType field" + + "\n" + + " • LandmarkInfo field", + + xref: { document: "cluster", section: "1.17.5.2" } + }, + + Field({ + name: "LocationInfo", id: 0x0, type: "locationdesc", conformance: "M", quality: "X", + + details: "This field shall indicate the name of the area, floor number and/or area type. A few examples are " + + "provided below." + + "\n" + + " • An area can have LocationInfo’s LocationName field set to \"blue room\", and the AreaType field " + + " set to the ID of a \"Living Room\" semantic tag. Clients wishing to direct the device to operate " + + " in (or service) the living room can use this area." + + "\n" + + " • An area can have LocationInfo set to null, the LandmarkInfo’s LandmarkTag field set to the ID " + + " of the \"Table\" landmark semantic tag, and the RelativePositionTag field set to the ID of the " + + " \"Under\" position semantic tag. With such an area indication, the client can request the device " + + " to operate in (or service) the area located under the table.", + + xref: { document: "cluster", section: "1.17.5.2.1" } + }), + + Field({ + name: "LandmarkInfo", id: 0x1, type: "LandmarkInfoStruct", conformance: "M", quality: "X", + + details: "This field shall indicate an association with a landmark. A value of null indicates that the " + + "information is not available or known. For example, this may indicate that the area refers to a " + + "zone next to a table." + + "\n" + + "If this field is not null, that indicates that the area is restricted to the zone where the " + + "landmark is located, as indicated by the LandmarkTag and, if not null, by the RelativePositionTag " + + "fields, rather than to the entire room or floor where the landmark is located, if those are " + + "indicated by the LocationInfo field.", + + xref: { document: "cluster", section: "1.17.5.2.2" } + }) + ), + + Datatype( + { + name: "MapStruct", type: "struct", + details: "This is a struct representing a map.", + xref: { document: "cluster", section: "1.17.5.3" } + }, + Field({ + name: "MapId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall represent the map’s identifier.", + xref: { document: "cluster", section: "1.17.5.3.1" } + }), + + Field({ + name: "Name", id: 0x1, type: "string", conformance: "M", constraint: "max 64", + details: "This field shall represent a human understandable map description. For example: \"Main Floor\", or " + + "\"Second Level\".", + xref: { document: "cluster", section: "1.17.5.3.2" } + }) + ), + + Datatype( + { + name: "AreaStruct", type: "struct", + details: "This is a struct representing an area known to the server.", + xref: { document: "cluster", section: "1.17.5.4" } + }, + Field({ + name: "AreaId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall represent the identifier of the area.", + xref: { document: "cluster", section: "1.17.5.4.1" } + }), + + Field({ + name: "MapId", id: 0x1, type: "uint32", conformance: "M", constraint: "desc", quality: "X", + + details: "This field shall indicate the map identifier which the area is associated with. A value of null " + + "indicates that the area is not associated with a map." + + "\n" + + "If the SupportedMaps attribute is not empty, this field shall match the MapID field of an entry " + + "from the SupportedMaps attribute’s list. If the SupportedMaps attribute is empty, this field shall " + + "be null.", + + xref: { document: "cluster", section: "1.17.5.4.2" } + }), + + Field({ + name: "AreaInfo", id: 0x2, type: "AreaInfoStruct", conformance: "M", + + details: "This field shall contain data describing the area." + + "\n" + + "This SHOULD be used by clients to determine the name and/or the full, or the partial, semantics of " + + "a certain area." + + "\n" + + "NOTE" + + "\n" + + "If any entries on the SupportedAreas attribute’s list have the AreaInfo field missing the semantic " + + "data, the client may remind the user to assign the respective data.", + + xref: { document: "cluster", section: "1.17.5.4.3" } + }) + ), + + Datatype( + { + name: "ProgressStruct", type: "struct", + details: "This is a struct indicating the progress.", + xref: { document: "cluster", section: "1.17.5.5" } + }, + + Field({ + name: "AreaId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall indicate the identifier of the area, and the identifier shall be an entry in the " + + "SupportedAreas attribute’s list.", + xref: { document: "cluster", section: "1.17.5.5.1" } + }), + + Field({ + name: "Status", id: 0x1, type: "OperationalStatusEnum", conformance: "M", + details: "This field shall indicate the operational status of the device regarding the area indicated by the " + + "AreaID field.", + xref: { document: "cluster", section: "1.17.5.5.2" } + }), + + Field({ + name: "TotalOperationalTime", id: 0x2, type: "elapsed-s", conformance: "O", quality: "X", + + details: "This field shall indicate the total operational time, in seconds, from when the device started to " + + "operate at the area indicated by the AreaID field, until the operation finished, due to completion " + + "or due to skipping, including any time spent while paused." + + "\n" + + "A value of null indicates that the total operational time is unknown." + + "\n" + + "There may be cases where the total operational time exceeds the maximum value that can be conveyed " + + "by this attribute, and in such instances this attribute shall be populated with null." + + "\n" + + "Null if the Status field is not set to Completed or Skipped.", + + xref: { document: "cluster", section: "1.17.5.5.3" } + }), + + Field({ + name: "InitialTimeEstimate", id: 0x3, type: "elapsed-s", conformance: "O", quality: "X", + + details: "This field shall indicate the estimated time for the operation, in seconds, from when the device " + + "will start operating at the area indicated by the AreaID field, until the operation completes, " + + "excluding any time spent while not operating in the area." + + "\n" + + "A value of null indicates that the estimated time is unknown. If the estimated time is unknown, or " + + "if it exceeds the maximum value that can be conveyed by this attribute, this attribute shall be " + + "null." + + "\n" + + "After initializing the ProgressStruct instance, the server SHOULD NOT change the value of this " + + "field, except when repopulating the entire instance, to avoid excessive reporting of the Progress " + + "attribute changes.", + + xref: { document: "cluster", section: "1.17.5.5.4" } + }) + ), + + Datatype( + { + name: "OperationalStatusEnum", type: "enum8", + details: "The following table defines the status values.", + xref: { document: "cluster", section: "1.17.5.6" } + }, + Field({ + name: "Pending", id: 0x0, conformance: "M", + description: "The device has not yet started operating at the given area, or has not finished operating at that area but it is not currently operating at the area" + }), + Field({ + name: "Operating", id: 0x1, conformance: "M", + description: "The device is currently operating at the given area" + }), + Field({ + name: "Skipped", id: 0x2, conformance: "M", + description: "The device has skipped the given area, before or during operating at it, due to a SkipArea command, due an out of band command (e.g. from the vendor’s application), due to a vendor specific reason, such as a time limit used by the device, or due the device ending operating unsuccessfully" + }), + Field({ + name: "Completed", id: 0x3, conformance: "M", + description: "The device has completed operating at the given area" + }) + ), + + Datatype( + { name: "SelectAreasStatus", type: "enum8", xref: { document: "cluster", section: "1.17.5.6.1" } }, + Field({ + name: "Success", id: 0x0, conformance: "M", + description: "Attempting to operate in the areas identified by the entries of the NewAreas field is allowed and possible. The SelectedAreas attribute is set to the value of the NewAreas field." + }), + Field({ + name: "UnsupportedArea", id: 0x1, conformance: "M", + description: "The value of at least one of the entries of the NewAreas field doesn’t match any entries in the SupportedAreas attribute." + }), + Field({ + name: "InvalidInMode", id: 0x2, conformance: "M", + description: "The received request cannot be handled due to the current mode of the device." + }), + Field({ + name: "InvalidSet", id: 0x3, conformance: "M", + description: "The set of values is invalid. For example, areas on different floors, that a robot knows it can’t reach on its own." + }) + ), + + Datatype( + { name: "SkipAreaStatus", type: "enum8", xref: { document: "cluster", section: "1.17.5.6.2" } }, + Field({ + name: "Success", id: 0x0, conformance: "M", + description: "Skipping the area is allowed and possible, or the device was operating at the last available area and has stopped." + }), + Field({ + name: "InvalidAreaList", id: 0x1, conformance: "M", + description: "The SelectedAreas attribute is empty." + }), + Field({ + name: "InvalidInMode", id: 0x2, conformance: "M", + description: "The received request cannot be handled due to the current mode of the device. For example, the CurrentArea attribute is null or the device is not operating." + }), + Field({ + name: "InvalidSkippedArea", id: 0x3, conformance: "M", + description: "The SkippedArea field doesn’t match an entry in the SupportedAreas list." + }) + ) + ), + + Datatype( + { name: "MeasurementTypeEnum", type: "enum16", xref: { document: "cluster", section: "2.1.4.2" } }, + Field({ name: "Unspecified", id: 0x0, conformance: "M" }), + Field({ name: "Voltage", id: 0x1, conformance: "M", description: "Voltage in millivolts (mV)" }), + Field({ name: "ActiveCurrent", id: 0x2, conformance: "M", description: "Active current in milliamps (mA)" }), + Field({ name: "ReactiveCurrent", id: 0x3, conformance: "M", description: "Reactive current in milliamps (mA)" }), + Field({ name: "ApparentCurrent", id: 0x4, conformance: "M", description: "Apparent current in milliamps (mA)" }), + Field({ name: "ActivePower", id: 0x5, conformance: "M", description: "Active power in milliwatts (mW)" }), + Field({ + name: "ReactivePower", id: 0x6, conformance: "M", + description: "Reactive power in millivolt-amps reactive (mVAR)" + }), + Field({ name: "ApparentPower", id: 0x7, conformance: "M", description: "Apparent power in millivolt-amps (mVA)" }), + Field({ name: "RmsVoltage", id: 0x8, conformance: "M", description: "Root mean squared voltage in millivolts (mV)" }), + Field({ name: "RmsCurrent", id: 0x9, conformance: "M", description: "Root mean squared current in milliamps (mA)" }), + Field({ name: "RmsPower", id: 0xa, conformance: "M", description: "Root mean squared power in milliwatts (mW)" }), + Field({ name: "Frequency", id: 0xb, conformance: "M", description: "AC frequency in millihertz (mHz)" }), + Field({ + name: "PowerFactor", id: 0xc, conformance: "M", + description: "Power Factor ratio in+/- 1/100ths of a percent." + }), + Field({ name: "NeutralCurrent", id: 0xd, conformance: "M", description: "AC neutral current in milliamps (mA)" }), + Field({ + name: "ElectricalEnergy", id: 0xe, conformance: "M", + description: "Electrical energy in milliwatt-hours (mWh)" + }) + ), + + Datatype( + { + name: "MeasurementAccuracyRangeStruct", type: "struct", + + details: "This struct represents the accuracy of a measurement for a range of measurement values. Accuracy " + + "shall be expressed as a maximum +/- percentage of the true value, a maximum +/- fixed value of the " + + "true value, or both." + + "\n" + + " • If both PercentMax and FixedMax are indicated, then for a given true value in the range between " + + " RangeMin and RangeMax," + + "\n" + + " ◦ the reported value shall be less than or equal to the sum of the true value, FixedMax and " + + " PercentMax percent of the true value." + + "\n" + + " ◦ the reported value shall be greater than or equal to the true value minus the sum of FixedMax " + + " and PercentMax percent of the true value." + + "\n" + + " • If only PercentMax is indicated, then for a given true value in the range between RangeMin and " + + " RangeMax," + + "\n" + + " ◦ the reported value shall be less than or equal to the sum of the true value and PercentMax " + + " percent of the true value." + + "\n" + + " ◦ the reported value shall be greater than or equal to the true value minus PercentMax per" + + "\n" + + "cent of the true value." + + "\n" + + " • If only FixedMax is indicated, then for a given true value in the range between RangeMin and " + + " RangeMax," + + "\n" + + " ◦ the reported value shall be less than or equal to the sum of the true value and FixedMax." + + "\n" + + " ◦ the reported value shall be greater than or equal to the true value minus FixedMax.", + + xref: { document: "cluster", section: "2.1.4.3" } + }, + + Field({ + name: "RangeMin", id: 0x0, type: "int64", conformance: "M", quality: "F", + + details: "This field shall indicate the minimum measurement value for the specified level of accuracy." + + "\n" + + "The value of this field shall be greater than or equal to the value of the MinMeasuredValue field " + + "on the encompassing MeasurementAccuracyStruct." + + "\n" + + "The value of this field shall be less than or equal to the value of the MaxMeasuredValue field on " + + "the encompassing MeasurementAccuracyStruct.", + + xref: { document: "cluster", section: "2.1.4.3.1" } + }), + + Field({ + name: "RangeMax", id: 0x1, type: "int64", conformance: "M", quality: "F", + + details: "This field shall indicate the maximum measurement value for the specified level of accuracy. The " + + "value of this field shall be greater than the value of the RangeMin field." + + "\n" + + "The value of this field shall be greater than or equal to the value of the MinMeasuredValue field " + + "on the encompassing MeasurementAccuracyStruct." + + "\n" + + "The value of this field shall be less than or equal to the value of the MaxMeasuredValue field on " + + "the encompassing MeasurementAccuracyStruct.", + + xref: { document: "cluster", section: "2.1.4.3.2" } + }), + + Field({ + name: "PercentMax", id: 0x2, type: "percent100ths", conformance: "O.a+", quality: "F", + details: "This field shall indicate the maximum +/- percentage accuracy for the associated measurement.", + xref: { document: "cluster", section: "2.1.4.3.3" } + }), + + Field({ + name: "PercentMin", id: 0x3, type: "percent100ths", conformance: "[PercentMax]", + constraint: "max percentTypical", quality: "F", + details: "This field shall indicate the minimum +/- percentage accuracy for the associated measurement.", + xref: { document: "cluster", section: "2.1.4.3.4" } + }), + + Field({ + name: "PercentTypical", id: 0x4, type: "percent100ths", conformance: "[PercentMin]", + constraint: "percentMin to percentMax", quality: "F", + details: "This field shall indicate the typical +/- percentage accuracy for the associated measurement.", + xref: { document: "cluster", section: "2.1.4.3.5" } + }), + + Field({ + name: "FixedMax", id: 0x5, type: "uint64", conformance: "O.a+", quality: "F", + details: "This field shall indicate the maximum +/- fixed accuracy for the associated measurement, in the " + + "unit indicated by MeasurementType.", + xref: { document: "cluster", section: "2.1.4.3.6" } + }), + + Field({ + name: "FixedMin", id: 0x6, type: "uint64", conformance: "[FixedMax]", constraint: "max fixedMax", + quality: "F", + details: "This field shall indicate the minimum +/- fixed accuracy for the associated measurement, in the " + + "unit indicated by MeasurementType.", + xref: { document: "cluster", section: "2.1.4.3.7" } + }), + + Field({ + name: "FixedTypical", id: 0x7, type: "uint64", conformance: "[FixedMin]", + constraint: "fixedMin to fixedMax", quality: "F", + details: "This field shall indicate the typical +/- fixed accuracy for the associated measurement, in the " + + "unit indicated by MeasurementType.", + xref: { document: "cluster", section: "2.1.4.3.8" } + }) + ), + + Datatype( + { + name: "MeasurementAccuracyStruct", type: "struct", + details: "This struct represents the set of accuracy ranges for a given measurement, the maximum and minimum " + + "values for the measurement, and whether the measurement is directly measured or just estimated from " + + "other information.", + xref: { document: "cluster", section: "2.1.4.4" } + }, + + Field({ + name: "MeasurementType", id: 0x0, type: "MeasurementTypeEnum", conformance: "M", quality: "F", + details: "This field shall indicate the type of measurement for the accuracy provided.", + xref: { document: "cluster", section: "2.1.4.4.1" } + }), + + Field({ + name: "Measured", id: 0x1, type: "bool", conformance: "M", default: false, quality: "F", + details: "This field shall indicate whether the associated measurement was directly measured. If this field " + + "is not set to true, then the associated measurement was estimated.", + xref: { document: "cluster", section: "2.1.4.4.2" } + }), + + Field({ name: "MinMeasuredValue", id: 0x2, type: "int64", conformance: "M", quality: "F" }), + Field({ name: "MaxMeasuredValue", id: 0x3, type: "int64", conformance: "M", quality: "F" }), + + Field( + { + name: "AccuracyRanges", id: 0x4, type: "list", conformance: "M", constraint: "min 1", quality: "F", + + details: "This field shall indicate a list of measurement ranges and their associated accuracies." + + "\n" + + "The value of the RangeMin field on the first MeasurementAccuracyRangeStruct in this list shall be " + + "equal to the value of the MinMeasuredValue field." + + "\n" + + "The value of the RangeMax field on the last MeasurementAccuracyRangeStruct in this list shall be " + + "less than or equal to the value of the MaxMeasuredValue field." + + "\n" + + "The value of the RangeMin field on each MeasurementAccuracyRangeStruct in this list other than the " + + "first shall be one more the value of the RangeMax field on the previous " + + "MeasurementAccuracyRangeStruct in this list (i.e. there shall be no gaps in the accuracy ranges, " + + "and the ranges shall be in increasing order).", + + xref: { document: "cluster", section: "2.1.4.4.5" } + }, + + Field({ name: "entry", type: "MeasurementAccuracyRangeStruct" }) + ) + ), + + Cluster( + { + name: "IlluminanceMeasurement", id: 0x400, classification: "application", pics: "ILL", + details: "The Illuminance Measurement cluster provides an interface to illuminance measurement functionality, " + + "including configuration and provision of notifications of illuminance measurements.", + xref: { document: "cluster", section: "2.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { + name: "MeasuredValue", id: 0x0, type: "uint16", access: "R V", conformance: "M", + constraint: "0, minMeasuredValue to maxMeasuredValue", default: 0, quality: "X P", + + details: "Indicates the illuminance in Lux (symbol lx) as follows:" + + "\n" + + " • MeasuredValue = 10,000 x log10(illuminance) + 1," + + "\n" + + "where 1 lx <= illuminance <= 3.576 Mlx, corresponding to a MeasuredValue in the range 1 to 0xFFFE. " + + "The MeasuredValue attribute can take the following values:" + + "\n" + + " • 0 indicates a value of illuminance that is too low to be measured," + + "\n" + + " • MinMeasuredValue <= MeasuredValue <= MaxMeasuredValue under normal circumstances," + + "\n" + + " • null indicates that the illuminance measurement is invalid." + + "\n" + + "The MeasuredValue attribute is updated continuously as new measurements are made.", + + xref: { document: "cluster", section: "2.2.5.1" } + } + ), + + Attribute({ + name: "MinMeasuredValue", id: 0x1, type: "uint16", access: "R V", conformance: "M", + constraint: "1 to 65533", quality: "X", + details: "Indicates the minimum value of MeasuredValue that can be measured. A value of null indicates that " + + "this attribute is not defined. See Measured Value for more details.", + xref: { document: "cluster", section: "2.2.5.2" } + }), + + Attribute({ + name: "MaxMeasuredValue", id: 0x2, type: "uint16", access: "R V", conformance: "M", + constraint: "min minMeasuredValue + 1", quality: "X", + details: "Indicates the maximum value of MeasuredValue that can be measured. A value of null indicates that " + + "this attribute is not defined. See Measured Value for more details.", + xref: { document: "cluster", section: "2.2.5.3" } + }), + + Attribute({ + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", + details: "See Measured Value.", + xref: { document: "cluster", section: "2.2.5.4" } + }), + + Attribute({ + name: "LightSensorType", id: 0x4, type: "LightSensorTypeEnum", access: "R V", conformance: "O", + default: null, quality: "X", + details: "Indicates the electronic type of the light sensor. This attribute shall be set to one of the " + + "non-reserved values listed in LightSensorTypeEnum or null in case the sensor type is unknown.", + xref: { document: "cluster", section: "2.2.5.5" } + }), + + Datatype( + { name: "LightSensorTypeEnum", type: "enum8", xref: { document: "cluster", section: "2.2.4.1" } }, + Field({ name: "Photodiode", id: 0x0, conformance: "M", description: "Indicates photodiode sensor type" }), + Field({ name: "Cmos", id: 0x1, conformance: "M", description: "Indicates CMOS sensor type" }) + ) + ), + + Cluster( + { + name: "TemperatureMeasurement", id: 0x402, classification: "application", pics: "TMP", + details: "This cluster provides an interface to temperature measurement functionality, including " + + "configuration and provision of notifications of temperature measurements.", + xref: { document: "cluster", section: "2.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute({ + name: "MeasuredValue", id: 0x0, type: "temperature", access: "R V", conformance: "M", + constraint: "minMeasuredValue to maxMeasuredValue", quality: "X P", + details: "Indicates the measured temperature. The null value indicates that the temperature is unknown.", + xref: { document: "cluster", section: "2.3.4.1" } + }), + + Attribute({ + name: "MinMeasuredValue", id: 0x1, type: "temperature", access: "R V", conformance: "M", + constraint: "-27315 to 32766", quality: "X", + details: "Indicates the minimum value of MeasuredValue that is capable of being measured. See Measured Value " + + "for more details." + + "\n" + + "The null value indicates that the value is not available.", + xref: { document: "cluster", section: "2.3.4.2" } + }), + + Attribute({ + name: "MaxMeasuredValue", id: 0x2, type: "temperature", access: "R V", conformance: "M", + constraint: "min minMeasuredValue + 1", quality: "X", + details: "This attribute indicates the maximum value of MeasuredValue that is capable of being measured. See " + + "Measured Value for more details." + + "\n" + + "The null value indicates that the value is not available.", + xref: { document: "cluster", section: "2.3.4.3" } + }), + + Attribute({ + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", + default: 0, + details: "See Measured Value.", + xref: { document: "cluster", section: "2.3.4.4" } + }) + ), + + Cluster( + { + name: "PressureMeasurement", id: 0x403, classification: "application", pics: "PRS", + details: "This cluster provides an interface to pressure measurement functionality, including configuration " + + "and provision of notifications of pressure measurements.", + xref: { document: "cluster", section: "2.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.4.4" } }, + Field({ + name: "EXT", conformance: "O", constraint: "0", description: "Extended", + details: "Extended range and resolution" + }) + ), + + Attribute( + { + name: "MeasuredValue", id: 0x0, type: "int16", access: "R V", conformance: "M", + constraint: "minMeasuredValue to maxMeasuredValue", quality: "X P", + details: "Indicates the pressure in kPa as follows:" + + "\n" + + "MeasuredValue = 10 x Pressure [kPa]" + + "\n" + + "The null value indicates that the value is not available.", + xref: { document: "cluster", section: "2.4.5.1" } + } + ), + + Attribute({ + name: "MinMeasuredValue", id: 0x1, type: "int16", access: "R V", conformance: "M", + constraint: "max 32766", quality: "X", + details: "Indicates the minimum value of MeasuredValue that can be measured. See Measured Value for more " + + "details." + + "\n" + + "The null value indicates that the value is not available.", + xref: { document: "cluster", section: "2.4.5.2" } + }), + + Attribute({ + name: "MaxMeasuredValue", id: 0x2, type: "int16", access: "R V", conformance: "M", + constraint: "minMeasuredValue + 1 to 32767", quality: "X", + details: "Indicates the maximum value of MeasuredValue that can be measured. See Measured Value for more " + + "details." + + "\n" + + "The null value indicates that the value is not available.", + xref: { document: "cluster", section: "2.4.5.3" } + }), + + Attribute({ + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", + default: 0, + details: "See Measured Value.", + xref: { document: "cluster", section: "2.4.5.4" } + }), + + Attribute( + { + name: "ScaledValue", id: 0x10, type: "int16", access: "R V", conformance: "EXT", + constraint: "minScaledValue to maxScaledValue", default: 0, quality: "X", + details: "Indicates the pressure in Pascals as follows:" + + "\n" + + "ScaledValue = 10Scale x Pressure [Pa]" + + "\n" + + "The null value indicates that the value is not available.", + xref: { document: "cluster", section: "2.4.5.5" } + } + ), + + Attribute({ + name: "MinScaledValue", id: 0x11, type: "int16", access: "R V", conformance: "EXT", + constraint: "max 32766", default: 0, quality: "X", + details: "Indicates the minimum value of ScaledValue that can be measured. The null value indicates that the " + + "value is not available.", + xref: { document: "cluster", section: "2.4.5.6" } + }), + + Attribute({ + name: "MaxScaledValue", id: 0x12, type: "int16", access: "R V", conformance: "EXT", + constraint: "minScaledValue + 1 to 32767", default: 0, quality: "X", + details: "Indicates the maximum value of ScaledValue that can be measured. The null value indicates that the " + + "value is not available.", + xref: { document: "cluster", section: "2.4.5.7" } + }), + + Attribute({ + name: "ScaledTolerance", id: 0x13, type: "uint16", access: "R V", conformance: "[EXT]", + constraint: "max 2048", default: 0, + details: "Indicates the magnitude of the possible error that is associated with Scaled" + + "\n" + + "Value. The true value is located in the range" + + "\n" + + "(ScaledValue – ScaledTolerance) to (ScaledValue + ScaledTolerance).", + xref: { document: "cluster", section: "2.4.5.8" } + }), + + Attribute({ + name: "Scale", id: 0x14, type: "int8", access: "R V", conformance: "EXT", constraint: "min -127", + default: 0, + details: "Indicates the base 10 exponent used to obtain ScaledValue (see ScaledValue).", + xref: { document: "cluster", section: "2.4.5.9" } + }) + ), + + Cluster( + { + name: "FlowMeasurement", id: 0x404, classification: "application", pics: "FLW", + details: "This cluster provides an interface to flow measurement functionality, including configuration and " + + "provision of notifications of flow measurements.", + xref: { document: "cluster", section: "2.5" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { + name: "MeasuredValue", id: 0x0, type: "uint16", access: "R V", conformance: "M", + constraint: "minMeasuredValue to maxMeasuredValue", default: null, quality: "X P", + + details: "Indicates the flow in m/h as follows:" + + "\n" + + "MeasuredValue = 10 x Flow" + + "\n" + + "The null value indicates that the flow measurement is unknown, otherwise the range shall be as " + + "described in Measured Value.", + + xref: { document: "cluster", section: "2.5.4.1" } + } + ), + + Attribute({ + name: "MinMeasuredValue", id: 0x1, type: "uint16", access: "R V", conformance: "M", + constraint: "max 65533", quality: "X", + details: "Indicates the minimum value of MeasuredValue that can be measured. See Measured Value for more " + + "details." + + "\n" + + "The null value indicates that the value is not available.", + xref: { document: "cluster", section: "2.5.4.2" } + }), + + Attribute({ + name: "MaxMeasuredValue", id: 0x2, type: "uint16", access: "R V", conformance: "M", + constraint: "min minMeasuredValue + 1", quality: "X", + details: "Indicates the maximum value of MeasuredValue that can be measured. See" + + "\n" + + "Measured Value for more details." + + "\n" + + "The null value indicates that the value is not available.", + xref: { document: "cluster", section: "2.5.4.3" } + }), + + Attribute({ + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", + default: 0, + details: "See Measured Value.", + xref: { document: "cluster", section: "2.5.4.4" } + }) + ), + + Cluster( + { + name: "RelativeHumidityMeasurement", id: 0x405, classification: "application", pics: "RH", + details: "This is a base cluster. The server cluster provides an interface to water content measurement " + + "functionality. The measurement is reportable and may be configured for reporting. Water content " + + "measurements currently is, but are not limited to relative humidity.", + xref: { document: "cluster", section: "2.6" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { + name: "MeasuredValue", id: 0x0, type: "uint16", access: "R V", conformance: "M", + constraint: "minMeasuredValue to maxMeasuredValue", quality: "X P", + + details: "MeasuredValue represents the water content in % as follows:" + + "\n" + + "MeasuredValue = 100 x water content" + + "\n" + + "Where 0% < = water content < = 100%, corresponding to a MeasuredValue in the range 0 to 10000. The " + + "maximum resolution this format allows is 0.01%." + + "\n" + + "MinMeasuredValue and MaxMeasuredValue define the range of the sensor." + + "\n" + + "The null value indicates that the measurement is unknown, otherwise the range shall be as described " + + "in Measured Value." + + "\n" + + "MeasuredValue is updated continuously as new measurements are made.", + + xref: { document: "cluster", section: "2.6.4.1" } + } + ), + + Attribute({ + name: "MinMeasuredValue", id: 0x1, type: "uint16", access: "R V", conformance: "M", + constraint: "max 9999", quality: "X", + details: "The MinMeasuredValue attribute indicates the minimum value of MeasuredValue that can be measured. " + + "The null value means this attribute is not defined. See Measured Value for more details.", + xref: { document: "cluster", section: "2.6.4.2" } + }), + + Attribute({ + name: "MaxMeasuredValue", id: 0x2, type: "uint16", access: "R V", conformance: "M", + constraint: "minMeasuredValue + 1 to 10000", quality: "X", + details: "The MaxMeasuredValue attribute indicates the maximum value of MeasuredValue that can be measured. " + + "The null value means this attribute is not defined. See Measured Value for more details.", + xref: { document: "cluster", section: "2.6.4.3" } + }), + + Attribute({ + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", + details: "See Measured Value.", + xref: { document: "cluster", section: "2.6.4.4" } + }) + ), + + Cluster( + { + name: "OccupancySensing", id: 0x406, classification: "application", pics: "OCC", + details: "The server cluster provides an interface to occupancy sensing functionality based on one or more " + + "sensing modalities, including configuration and provision of notifications of occupancy status.", + xref: { document: "cluster", section: "2.7" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 5 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.7.4" } }, + Field({ + name: "OTHER", conformance: "O.a+", constraint: "0", description: "Other", + details: "Supports sensing using a modality not listed in the other bits" + }), + Field({ + name: "PIR", conformance: "O.a+", constraint: "1", description: "PassiveInfrared", + details: "Supports sensing using PIR (Passive InfraRed)" + }), + Field({ + name: "US", conformance: "O.a+", constraint: "2", description: "Ultrasonic", + details: "Supports sensing using UltraSound" + }), + Field({ + name: "PHY", conformance: "O.a+", constraint: "3", description: "PhysicalContact", + details: "Supports sensing using a physical contact" + }), + Field({ + name: "AIR", conformance: "O.a+", constraint: "4", description: "ActiveInfrared", + details: "Supports sensing using Active InfraRed measurement (e.g. time-of- flight or " + + "transflective/reflective IR sensing)" + }), + Field({ + name: "RAD", conformance: "O.a+", constraint: "5", description: "Radar", + details: "Supports sensing using radar waves (microwave)" + }), + Field({ + name: "RFS", conformance: "O.a+", constraint: "6", description: "RfSensing", + details: "Supports sensing based on RF signal analysis" + }), + Field({ + name: "VIS", conformance: "O.a+", constraint: "7", description: "Vision", + details: "Supports sensing based on analyzing images" + }) + ), + + Attribute({ + name: "Occupancy", id: 0x0, type: "OccupancyBitmap", access: "R V", conformance: "M", + constraint: "0 to 1", quality: "P", + details: "Indicates the sensed (processed) status of occupancy. For compatibility reasons this is expressed " + + "as a bitmap where the status is indicated in bit 0: a value of 1 means occupied, and 0 means " + + "unoccupied, with the other bits set to 0; this can be considered equivalent to a boolean.", + xref: { document: "cluster", section: "2.7.6.1" } + }), + + Attribute({ + name: "OccupancySensorType", id: 0x1, type: "OccupancySensorTypeEnum", access: "R V", + conformance: "M, D", constraint: "desc", quality: "F", + xref: { document: "cluster", section: "2.7.6" } + }), + Attribute({ + name: "OccupancySensorTypeBitmap", id: 0x2, type: "OccupancySensorTypeBitmap", access: "R V", + conformance: "M, D", constraint: "0 to 7", quality: "F", + xref: { document: "cluster", section: "2.7.6" } + }), + + Attribute({ + name: "HoldTime", id: 0x3, type: "uint16", access: "RW VM", conformance: "O", constraint: "desc", + quality: "N", + + details: "This attribute shall specify the time delay, in seconds, before the sensor changes to its " + + "unoccupied state after the last detection of occupancy in the sensed area. This is equivalent to " + + "the legacy *OccupiedToUnoccupiedDelay attributes." + + "\n" + + "The value of HoldTime shall be within the limits provided in the HoldTimeLimits attribute, i.e. " + + "HoldTimeMin <= HoldTime <= HoldTimeMax" + + "\n" + + "Low values of HoldTime SHOULD be avoided since they could lead to many reporting messages. A value " + + "0 for HoldTime shall NOT be used." + + "\n" + + "The figure below illustrates this with an example of how this attribute is used for a PIR sensor. " + + "It uses threshold detection to generate an \"internal detection\" signal, which needs post-processing " + + "to become usable for transmission (traffic shaping). The bit in the Occupancy attribute will be set " + + "to 1 when the internal detection signal goes high, and will stay at 1 for HoldTime after the (last) " + + "instance where the internal detection signal goes low." + + "\n" + + "The top half of the figure shows the case of a single trigger: the bit in the Occupancy attribute " + + "will be 1 for the duration of the PIR signal exceeding the threshold plus HoldTime. The bottom half " + + "of the figure shows the case of multiple triggers: the second trigger starts before the HoldTime of " + + "the first trigger has expired; this results in a single period of the bit in the Occupancy " + + "attribute being 1. The bit in the Occupancy attribute will be set to 1 from the start of the first " + + "period where the PIR signal exceeds the threshold until HoldTime after the last moment where the " + + "PIR exceeded the threshold." + + "\n" + + "Figure 13. Processing of PIR signal towards Occupancy attribute using HoldTime", + + xref: { document: "cluster", section: "2.7.6.3" } + }), + + Attribute({ + name: "HoldTimeLimits", id: 0x4, type: "HoldTimeLimitsStruct", access: "R V", + conformance: "HoldTime", quality: "F", + details: "Indicates the server’s limits, and default value, for the HoldTime attribute.", + xref: { document: "cluster", section: "2.7.6.4" } + }), + + Attribute({ + name: "PirOccupiedToUnoccupiedDelay", id: 0x10, type: "uint16", access: "RW VM", + conformance: "[HoldTime & (PIR | !PIR & !US & !PHY)], D", default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the PIR sensor changes to its " + + "unoccupied state after the last detection of occupancy in the sensed area.", + xref: { document: "cluster", section: "2.7.6.6" } + }), + + Attribute({ + name: "PirUnoccupiedToOccupiedDelay", id: 0x11, type: "uint16", access: "RW VM", + conformance: "HoldTime & (PIR | !PIR & !US & !PHY) & PirUnoccupiedToOccupiedThreshold, [HoldTime & (PIR | !PIR & !US & !PHY)], D", + default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the PIR sensor changes to its " + + "occupied state after the first detection of occupancy in the sensed area.", + xref: { document: "cluster", section: "2.7.6.7" } + }), + + Attribute({ + name: "PirUnoccupiedToOccupiedThreshold", id: 0x12, type: "uint8", access: "RW VM", + conformance: "HoldTime & (PIR | !PIR & !US & !PHY) & PirUnoccupiedToOccupiedDelay, [HoldTime & (PIR | !PIR & !US & !PHY)], D", + constraint: "1 to 254", default: 1, quality: "N", + details: "This attribute shall specify the number of occupancy detection events that must occur in the period " + + "PIRUnoccupiedToOccupiedDelay, before the PIR sensor changes to its occupied state.", + xref: { document: "cluster", section: "2.7.6.8" } + }), + + Attribute({ + name: "UltrasonicOccupiedToUnoccupiedDelay", id: 0x20, type: "uint16", access: "RW VM", + conformance: "[HoldTime & US], D", default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the Ultrasonic sensor changes to " + + "its unoccupied state after the last detection of occupancy in the sensed area.", + xref: { document: "cluster", section: "2.7.6.9" } + }), + + Attribute({ + name: "UltrasonicUnoccupiedToOccupiedDelay", id: 0x21, type: "uint16", access: "RW VM", + conformance: "HoldTime & US & UltrasonicUnoccupiedToOccupiedThreshold, [HoldTime & US], D", + default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the Ultrasonic sensor changes to " + + "its occupied state after the first detection of occupancy in the sensed area.", + xref: { document: "cluster", section: "2.7.6.10" } + }), + + Attribute({ + name: "UltrasonicUnoccupiedToOccupiedThreshold", id: 0x22, type: "uint8", access: "RW VM", + conformance: "HoldTime & US & UltrasonicUnoccupiedToOccupiedDelay, [HoldTime & US], D", + constraint: "1 to 254", default: 1, quality: "N", + details: "This attribute shall specify the number of occupancy detection events that must occur in the period " + + "UltrasonicUnoccupiedToOccupiedDelay, before the Ultrasonic sensor changes to its occupied state.", + xref: { document: "cluster", section: "2.7.6.11" } + }), + + Attribute({ + name: "PhysicalContactOccupiedToUnoccupiedDelay", id: 0x30, type: "uint16", access: "RW VM", + conformance: "[HoldTime & PHY], D", default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the physical contact occupancy " + + "sensor changes to its unoccupied state after detecting the unoccupied event.", + xref: { document: "cluster", section: "2.7.6.12" } + }), + + Attribute({ + name: "PhysicalContactUnoccupiedToOccupiedDelay", id: 0x31, type: "uint16", access: "RW VM", + conformance: "HoldTime & PHY & PhysicalContactUnoccupiedToOccupiedThreshold, [HoldTime & PHY], D", + default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the physical contact sensor changes " + + "to its occupied state after the first detection of the occupied event.", + xref: { document: "cluster", section: "2.7.6.13" } + }), + + Attribute({ + name: "PhysicalContactUnoccupiedToOccupiedThreshold", id: 0x32, type: "uint8", access: "RW VM", + conformance: "HoldTime & PHY & PhysicalContactUnoccupiedToOccupiedDelay, [HoldTime & PHY], D", + constraint: "1 to 254", default: 1, quality: "N", + details: "This attribute shall specify the number of occupancy detection events that must occur in the period " + + "PhysicalContactUnoccupiedToOccupiedDelay, before the PhysicalContact sensor changes to its occupied " + + "state.", + xref: { document: "cluster", section: "2.7.6.14" } + }), + + Event( + { + name: "OccupancyChanged", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "If this event is supported, it shall be generated when the Occupancy attribute changes.", + xref: { document: "cluster", section: "2.7.7.1" } + }, + Field({ + name: "Occupancy", id: 0x0, type: "OccupancyBitmap", conformance: "M", + details: "This field shall indicate the new value of the Occupancy attribute.", + xref: { document: "cluster", section: "2.7.7.1.1" } + }) + ), + + Datatype( + { name: "OccupancyBitmap", type: "map8", xref: { document: "cluster", section: "2.7.5.1" } }, + + Field({ + name: "Occupied", constraint: "0", description: "Indicates the sensed occupancy state", + details: "If this bit is set, it shall indicate the occupied state else if the bit if not set, it shall " + + "indicate the unoccupied state.", + xref: { document: "cluster", section: "2.7.5.1.1" } + }) + ), + + Datatype( + { + name: "OccupancySensorTypeBitmap", type: "map8", + details: "NOTE" + + "\n" + + "This enum is as defined in ClusterRevision 4 and its definition shall NOT be extended; the feature " + + "flags provide the sensor modality (or modalities) for later cluster revisions. See Backward " + + "Compatibility section.", + xref: { document: "cluster", section: "2.7.5.2" } + }, + + Field({ name: "Pir", constraint: "0", description: "Indicates a passive infrared sensor." }), + Field({ name: "Ultrasonic", constraint: "1", description: "Indicates a ultrasonic sensor." }), + Field({ name: "PhysicalContact", constraint: "2", description: "Indicates a physical contact sensor." }) + ), + + Datatype( + { + name: "OccupancySensorTypeEnum", type: "enum8", + + details: "NOTE" + + "\n" + + "This enum is as defined in ClusterRevision 4 and its definition shall NOT be" + + "\n" + + "extended; the feature flags provide the sensor modality (or modalities) for later cluster " + + "revisions. See Backward Compatibility section.", + + xref: { document: "cluster", section: "2.7.5.3" } + }, + + Field({ name: "Pir", id: 0x0, conformance: "M", description: "Indicates a passive infrared sensor." }), + Field({ name: "Ultrasonic", id: 0x1, conformance: "M", description: "Indicates a ultrasonic sensor." }), + Field({ + name: "PirAndUltrasonic", id: 0x2, conformance: "M", + description: "Indicates a passive infrared and ultrasonic sensor." + }), + Field({ name: "PhysicalContact", id: 0x3, conformance: "M", description: "Indicates a physical contact sensor." }) + ), + + Datatype( + { + name: "HoldTimeLimitsStruct", type: "struct", + details: "This structure provides information on the server’s supported values for the HoldTime attribute.", + xref: { document: "cluster", section: "2.7.5.4" } + }, + + Field({ + name: "HoldTimeMin", id: 0x0, type: "uint16", conformance: "M", constraint: "min 1", + details: "This field shall specify the minimum value of the server’s supported value for the HoldTime " + + "attribute, in seconds.", + xref: { document: "cluster", section: "2.7.5.4.1" } + }), + + Field({ + name: "HoldTimeMax", id: 0x1, type: "uint16", conformance: "M", + constraint: "min holdTimeMin, min 10", + details: "This field shall specify the maximum value of the server’s supported value for the HoldTime " + + "attribute, in seconds.", + xref: { document: "cluster", section: "2.7.5.4.2" } + }), + + Field({ + name: "HoldTimeDefault", id: 0x2, type: "uint16", conformance: "M", + constraint: "holdTimeMin to holdTimeMax", + details: "This field shall specify the (manufacturer-determined) default value of the server’s HoldTime " + + "attribute, in seconds. This is the value that a client who wants to reset the settings to a valid " + + "default SHOULD use.", + xref: { document: "cluster", section: "2.7.5.4.3" } + }) + ) + ), + + Cluster( + { + name: "ResourceMonitoring", classification: "application", pics: "REPM", + + details: "This generic cluster provides an interface to the current condition of a resource. A resource is a" + + "\n" + + "component of a device that is designed to be replaced, refilled, or emptied when exhausted or full. " + + "Examples of resources include filters, cartridges, and water tanks. While batteries fit this " + + "definition they are not intended to be used with this cluster. Use the power source cluster for " + + "batteries instead." + + "\n" + + "NOTE" + + "\n" + + "This cluster is not meant to be used for monitoring of the system resources, such as processing, " + + "memory utilization, networking properties, etc." + + "\n" + + "This cluster shall be used via an alias to a specific resource type (see Cluster IDs).", + + xref: { document: "cluster", section: "2.8" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.8.4" } }, + Field({ + name: "CON", conformance: "O", constraint: "0", description: "Condition", + details: "Supports monitoring the condition of the resource in percentage" + }), + Field({ + name: "WRN", conformance: "O", constraint: "1", description: "Warning", + details: "Supports warning indication" + }), + Field({ + name: "REP", conformance: "O", constraint: "2", description: "ReplacementProductList", + details: "Supports specifying the list of replacement products" + }) + ), + + Attribute({ + name: "Condition", id: 0x0, type: "percent", access: "R V", conformance: "CON", + details: "Indicates the current condition of the resource in percent.", + xref: { document: "cluster", section: "2.8.6.1" } + }), + + Attribute({ + name: "DegradationDirection", id: 0x1, type: "DegradationDirectionEnum", access: "R V", + conformance: "CON", constraint: "desc", quality: "F", + details: "Indicates the direction of change for the condition of the resource over time, which helps to " + + "determine whether a higher or lower condition value is considered optimal.", + xref: { document: "cluster", section: "2.8.6.2" } + }), + + Attribute({ + name: "ChangeIndication", id: 0x2, type: "ChangeIndicationEnum", access: "R V", conformance: "M", + default: 0, + details: "This attribute shall be populated with a value from ChangeIndicationEnum that is indicative of the " + + "current requirement to change the resource.", + xref: { document: "cluster", section: "2.8.6.3" } + }), + + Attribute({ + name: "InPlaceIndicator", id: 0x3, type: "bool", access: "R V", conformance: "O", + details: "Indicates whether a resource is currently installed. A value of true shall indicate that a resource " + + "is installed. A value of false shall indicate that a resource is not installed.", + xref: { document: "cluster", section: "2.8.6.4" } + }), + + Attribute({ + name: "LastChangedTime", id: 0x4, type: "epoch-s", access: "RW VO", conformance: "O", default: null, + quality: "X N", + details: "This attribute may indicates the time at which the resource has been changed, if supported by the " + + "server. The attribute shall be null if it was never set or is unknown.", + xref: { document: "cluster", section: "2.8.6.5" } + }), + + Attribute( + { + name: "ReplacementProductList", id: 0x5, type: "list", access: "R V", conformance: "REP", + constraint: "max 5", quality: "F", + details: "Indicates the list of supported products that may be used as replacements for the current resource. " + + "Each item in this list represents a unique ReplacementProductStruct.", + xref: { document: "cluster", section: "2.8.6.6" } + }, + + Field({ name: "entry", type: "ReplacementProductStruct" }) + ), + + Command({ + name: "ResetCondition", id: 0x0, access: "O", conformance: "O", direction: "request", + response: "status", + details: "Upon receipt, the device shall reset the Condition and ChangeIndicator attributes, indicating full " + + "resource availability and readiness for use, as initially configured. Invocation of this command " + + "may cause the LastChangedTime to be updated automatically based on the clock of the server, if the " + + "server supports setting the attribute.", + xref: { document: "cluster", section: "2.8.7.1" } + }), + + Datatype( + { + name: "DegradationDirectionEnum", type: "enum8", + details: "Indicates the direction in which the condition of the resource changes over time.", + xref: { document: "cluster", section: "2.8.5.1" } + }, + Field({ + name: "Up", id: 0x0, conformance: "M", + description: "The degradation of the resource is indicated by an upwards moving/increasing value" + }), + Field({ + name: "Down", id: 0x1, conformance: "M", + description: "The degradation of the resource is indicated by a downwards moving/decreasing value" + }) + ), + + Datatype( + { name: "ChangeIndicationEnum", type: "enum8", xref: { document: "cluster", section: "2.8.5.2" } }, + Field({ + name: "Ok", id: 0x0, conformance: "M", + description: "Resource is in good condition, no intervention required" + }), + Field({ + name: "Warning", id: 0x1, conformance: "WRN", + description: "Resource will be exhausted soon, intervention will shortly be required" + }), + Field({ + name: "Critical", id: 0x2, conformance: "M", + description: "Resource is exhausted, immediate intervention is required" + }) + ), + + Datatype( + { + name: "ProductIdentifierTypeEnum", type: "enum8", + details: "Indicate the type of identifier used to describe the product. Devices SHOULD use " + + "globally-recognized IDs over OEM specific ones.", + xref: { document: "cluster", section: "2.8.5.3" } + }, + + Field({ name: "Upc", id: 0x0, conformance: "M", description: "12-digit Universal Product Code" }), + Field({ name: "Gtin8", id: 0x1, conformance: "M", description: "8-digit Global Trade Item Number" }), + Field({ name: "Ean", id: 0x2, conformance: "M", description: "13-digit European Article Number" }), + Field({ name: "Gtin14", id: 0x3, conformance: "M", description: "14-digit Global Trade Item Number" }), + Field({ name: "Oem", id: 0x4, conformance: "M", description: "Original Equipment Manufacturer part number" }) + ), + + Datatype( + { + name: "ReplacementProductStruct", type: "struct", + details: "Indicates the product identifier that can be used as a replacement for the resource.", + xref: { document: "cluster", section: "2.8.5.4" } + }, + Field({ + name: "ProductIdentifierType", id: 0x0, type: "ProductIdentifierTypeEnum", conformance: "M", + constraint: "desc" + }), + Field({ name: "ProductIdentifierValue", id: 0x1, type: "string", conformance: "M", constraint: "max 20" }) + ) + ), + + Cluster({ name: "HepaFilterMonitoring", id: 0x71, type: "ResourceMonitoring", pics: "HEPAFREMON" }), + Cluster({ name: "ActivatedCarbonFilterMonitoring", id: 0x72, type: "ResourceMonitoring", pics: "ACFREMON" }), + Cluster({ name: "WaterTankLevelMonitoring", id: 0x79, type: "ResourceMonitoring", pics: "WTLREPMON" }), + + Cluster( + { + name: "AirQuality", id: 0x5b, classification: "application", pics: "AIRQUAL", + details: "This cluster provides an interface to air quality classification using distinct levels with " + + "human-readable labels.", + xref: { document: "cluster", section: "2.9" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.9.4" } }, + Field({ + name: "FAIR", conformance: "O", constraint: "0", description: "Fair", + details: "Cluster supports the Fair air quality level" + }), + Field({ + name: "MOD", conformance: "O", constraint: "1", description: "Moderate", + details: "Cluster supports the Moderate air quality level" + }), + Field({ + name: "VPOOR", conformance: "O", constraint: "2", description: "VeryPoor", + details: "Cluster supports the Very poor air quality level" + }), + Field({ + name: "XPOOR", conformance: "O", constraint: "3", description: "ExtremelyPoor", + details: "Cluster supports the Extremely poor air quality level" + }) + ), + + Attribute({ + name: "AirQuality", id: 0x0, type: "AirQualityEnum", access: "R V", conformance: "M", + constraint: "desc", default: 0, + details: "Indicates a value from AirQualityEnum that is indicative of the currently measured air quality.", + xref: { document: "cluster", section: "2.9.6.1" } + }), + + Datatype( + { + name: "AirQualityEnum", type: "enum8", + details: "The AirQualityEnum provides a representation of the quality of the analyzed air. It is up to the " + + "device manufacturer to determine the mapping between the measured values and their corresponding " + + "enumeration values.", + xref: { document: "cluster", section: "2.9.5.1" } + }, + + Field({ name: "Unknown", id: 0x0, conformance: "M", description: "The air quality is unknown." }), + Field({ name: "Good", id: 0x1, conformance: "M", description: "The air quality is good." }), + Field({ name: "Fair", id: 0x2, conformance: "FAIR", description: "The air quality is fair." }), + Field({ name: "Moderate", id: 0x3, conformance: "MOD", description: "The air quality is moderate." }), + Field({ name: "Poor", id: 0x4, conformance: "M", description: "The air quality is poor." }), + Field({ name: "VeryPoor", id: 0x5, conformance: "VPOOR", description: "The air quality is very poor." }), + Field({ name: "ExtremelyPoor", id: 0x6, conformance: "XPOOR", description: "The air quality is extremely poor." }) + ) + ), + + Cluster( + { + name: "ConcentrationMeasurement", classification: "application", pics: "CONC", + details: "The server cluster provides an interface to concentration measurement functionality. This cluster " + + "shall to be used via an alias to a specific substance (see Cluster IDs).", + xref: { document: "cluster", section: "2.10" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.10.4" } }, + Field({ + name: "MEA", conformance: "O.a+", constraint: "0", description: "NumericMeasurement", + details: "Cluster supports numeric measurement of substance" + }), + Field({ + name: "LEV", conformance: "O.a+", constraint: "1", description: "LevelIndication", + details: "Cluster supports basic level indication for substance using the ConcentrationLevel enum" + }), + Field({ + name: "MED", conformance: "[LEV]", constraint: "2", description: "MediumLevel", + details: "Cluster supports the Medium Concentration Level" + }), + Field({ + name: "CRI", conformance: "[LEV]", constraint: "3", description: "CriticalLevel", + details: "Cluster supports the Critical Concentration Level" + }), + Field({ + name: "PEA", conformance: "[MEA]", constraint: "4", description: "PeakMeasurement", + details: "Cluster supports peak numeric measurement of substance" + }), + Field({ + name: "AVG", conformance: "[MEA]", constraint: "5", description: "AverageMeasurement", + details: "Cluster supports average numeric measurement of substance" + }) + ), + + Attribute({ + name: "MeasuredValue", id: 0x0, type: "single", access: "R V", conformance: "MEA", + constraint: "minMeasuredValue to maxMeasuredValue", default: null, quality: "X P", + details: "Indicates the most recent measurement as a single-precision floating-point number. MeasuredValue’s " + + "unit is represented by MeasurementUnit." + + "\n" + + "A value of null indicates that the measurement is unknown or outside the valid range. " + + "MinMeasuredValue and MaxMeasuredValue define the valid range for MeasuredValue.", + xref: { document: "cluster", section: "2.10.6.1" } + }), + + Attribute({ + name: "MinMeasuredValue", id: 0x1, type: "single", access: "R V", conformance: "MEA", default: null, + quality: "X", + details: "Indicates the minimum value of MeasuredValue that is capable of being measured. A MinMeasuredValue " + + "of null indicates that the MinMeasuredValue is not defined.", + xref: { document: "cluster", section: "2.10.6.2" } + }), + + Attribute({ + name: "MaxMeasuredValue", id: 0x2, type: "single", access: "R V", conformance: "MEA", + constraint: "min minMeasuredValue", default: null, quality: "X", + details: "Indicates the maximum value of MeasuredValue that is capable of being measured. A MaxMeasuredValue " + + "of null indicates that the MaxMeasuredValue is not defined.", + xref: { document: "cluster", section: "2.10.6.3" } + }), + + Attribute({ + name: "PeakMeasuredValue", id: 0x3, type: "single", access: "R V", conformance: "PEA", + constraint: "minMeasuredValue to maxMeasuredValue", default: null, quality: "X P", + details: "Indicates the maximum value of MeasuredValue that has been measured during the " + + "PeakMeasuredValueWindow. If this attribute is provided, the PeakMeasuredValueWindow attribute shall " + + "also be provided.", + xref: { document: "cluster", section: "2.10.6.4" } + }), + + Attribute({ + name: "PeakMeasuredValueWindow", id: 0x4, type: "elapsed-s", access: "R V", conformance: "PEA", + constraint: "max 604800", default: 1, quality: "P", + details: "Indicates the window of time used for determining the PeakMeasuredValue. The value is in seconds.", + xref: { document: "cluster", section: "2.10.6.5" } + }), + + Attribute({ + name: "AverageMeasuredValue", id: 0x5, type: "single", access: "R V", conformance: "AVG", + constraint: "minMeasuredValue to maxMeasuredValue", default: null, quality: "X P", + details: "Indicates the average value of MeasuredValue that has been measured during the " + + "AverageMeasuredValueWindow. If this attribute is provided, the AverageMeasuredValueWindow attribute " + + "shall also be provided.", + xref: { document: "cluster", section: "2.10.6.6" } + }), + + Attribute({ + name: "AverageMeasuredValueWindow", id: 0x6, type: "elapsed-s", access: "R V", conformance: "AVG", + constraint: "max 604800", default: 1, quality: "P", + details: "Indicates the window of time used for determining the AverageMeasuredValue. The value is in seconds.", + xref: { document: "cluster", section: "2.10.6.7" } + }), + + Attribute({ + name: "Uncertainty", id: 0x7, type: "single", access: "R V", conformance: "[MEA]", constraint: "ms", + details: "Indicates the range of error or deviation that can be found in MeasuredValue and PeakMeasuredValue. " + + "This is considered a +/- value and should be considered to be in MeasurementUnit.", + xref: { document: "cluster", section: "2.10.6.8" } + }), + + Attribute({ + name: "MeasurementUnit", id: 0x8, type: "MeasurementUnitEnum", access: "R V", conformance: "MEA", + quality: "F", + details: "Indicates the unit of MeasuredValue. See MeasurementUnitEnum.", + xref: { document: "cluster", section: "2.10.6.9" } + }), + + Attribute({ + name: "MeasurementMedium", id: 0x9, type: "MeasurementMediumEnum", access: "R V", conformance: "M", + quality: "F", + details: "Indicates the medium in which MeasuredValue is being measured. See MeasurementMediumEnum.", + xref: { document: "cluster", section: "2.10.6.10" } + }), + + Attribute({ + name: "LevelValue", id: 0xa, type: "LevelValueEnum", access: "R V", conformance: "LEV", default: 0, + details: "Indicates the level of the substance detected. See LevelValueEnum.", + xref: { document: "cluster", section: "2.10.6.11" } + }), + + Datatype( + { + name: "MeasurementUnitEnum", type: "enum8", + details: "Where mentioned, Billion refers to 10, Trillion refers to 1012 (short scale).", + xref: { document: "cluster", section: "2.10.5.1" } + }, + Field({ name: "Ppm", id: 0x0, conformance: "MEA", description: "Parts per Million (10)" }), + Field({ name: "Ppb", id: 0x1, conformance: "MEA", description: "Parts per Billion (10)" }), + Field({ name: "Ppt", id: 0x2, conformance: "MEA", description: "Parts per Trillion (1012)" }), + Field({ name: "Mgm3", id: 0x3, conformance: "MEA", description: "Milligram per m" }), + Field({ name: "Ugm3", id: 0x4, conformance: "MEA", description: "Microgram per m" }), + Field({ name: "Ngm3", id: 0x5, conformance: "MEA", description: "Nanogram per m" }), + Field({ name: "Pm3", id: 0x6, conformance: "MEA", description: "Particles per m" }), + Field({ name: "Bqm3", id: 0x7, conformance: "MEA", description: "Becquerel per m" }) + ), + + Datatype( + { name: "MeasurementMediumEnum", type: "enum8", xref: { document: "cluster", section: "2.10.5.2" } }, + Field({ name: "Air", id: 0x0, conformance: "M", description: "The measurement is being made in Air" }), + Field({ name: "Water", id: 0x1, conformance: "M", description: "The measurement is being made in Water" }), + Field({ name: "Soil", id: 0x2, conformance: "M", description: "The measurement is being made in Soil" }) + ), + + Datatype( + { name: "LevelValueEnum", type: "enum8", xref: { document: "cluster", section: "2.10.5.3" } }, + Field({ name: "Unknown", id: 0x0, conformance: "M", description: "The level is Unknown" }), + Field({ name: "Low", id: 0x1, conformance: "M", description: "The level is considered Low" }), + Field({ name: "Medium", id: 0x2, conformance: "MED", description: "The level is considered Medium" }), + Field({ name: "High", id: 0x3, conformance: "M", description: "The level is considered High" }), + Field({ name: "Critical", id: 0x4, conformance: "CRI", description: "The level is considered Critical" }) + ) + ), + + Cluster({ name: "CarbonMonoxideConcentrationMeasurement", id: 0x40c, type: "ConcentrationMeasurement", pics: "CMOCONC" }), + Cluster( + { name: "CarbonDioxideConcentrationMeasurement", id: 0x40d, type: "ConcentrationMeasurement", pics: "CDOCONC" } + ), + Cluster({ name: "NitrogenDioxideConcentrationMeasurement", id: 0x413, type: "ConcentrationMeasurement", pics: "NDOCONC" }), + Cluster({ name: "OzoneConcentrationMeasurement", id: 0x415, type: "ConcentrationMeasurement", pics: "OZCONC" }), + Cluster({ name: "Pm25ConcentrationMeasurement", id: 0x42a, type: "ConcentrationMeasurement", pics: "PMICONC" }), + Cluster({ name: "FormaldehydeConcentrationMeasurement", id: 0x42b, type: "ConcentrationMeasurement", pics: "FLDCONC" }), + Cluster({ name: "Pm1ConcentrationMeasurement", id: 0x42c, type: "ConcentrationMeasurement", pics: "PMHCONC" }), + Cluster({ name: "Pm10ConcentrationMeasurement", id: 0x42d, type: "ConcentrationMeasurement", pics: "PMKCONC" }), + Cluster({ + name: "TotalVolatileOrganicCompoundsConcentrationMeasurement", id: 0x42e, + type: "ConcentrationMeasurement", pics: "TVOCCONC" + }), + Cluster({ name: "RadonConcentrationMeasurement", id: 0x42f, type: "ConcentrationMeasurement", pics: "RNCONC" }), + + Cluster( + { + name: "SmokeCoAlarm", id: 0x5c, classification: "application", pics: "SMOKECO", + details: "This cluster provides an interface for observing and managing the state of smoke and CO alarms.", + xref: { document: "cluster", section: "2.11" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.11.4" } }, + Field({ + name: "SMOKE", conformance: "O.a+", constraint: "0", description: "SmokeAlarm", + details: "Supports Smoke alarm" + }), + Field({ name: "CO", conformance: "O.a+", constraint: "1", description: "CoAlarm", details: "Supports CO alarm" }) + ), + + Attribute({ + name: "ExpressedState", id: 0x0, type: "ExpressedStateEnum", access: "R V", conformance: "M", + quality: "N", + + details: "Indicates the visibly- and audibly-expressed state of the alarm. When multiple alarm conditions are " + + "being reflected in the server, this attribute shall indicate the condition with the highest " + + "priority. Priority order of conditions is determined by the manufacturer and shall be supplied as a " + + "part of certification procedure. If the value of ExpressedState is not Normal, the attribute " + + "corresponding to the value shall NOT be Normal. For example, if the ExpressedState is set to " + + "SmokeAlarm, the value of the SmokeState will indicate the severity of the alarm (Warning or " + + "Critical). Clients SHOULD also read the other attributes to be aware of further alarm conditions " + + "beyond the one indicated in ExpressedState." + + "\n" + + "Visible expression is typically a LED light pattern. Audible expression is a horn or speaker " + + "pattern. Audible expression shall BE suppressed if the DeviceMuted attribute is supported and set " + + "to Muted.", + + xref: { document: "cluster", section: "2.11.6.1" } + }), + + Attribute({ + name: "SmokeState", id: 0x1, type: "AlarmStateEnum", access: "R V", conformance: "SMOKE", + quality: "N", + details: "Indicates whether the device’s smoke sensor is currently triggering a smoke alarm.", + xref: { document: "cluster", section: "2.11.6.2" } + }), + + Attribute({ + name: "CoState", id: 0x2, type: "AlarmStateEnum", access: "R V", conformance: "CO", quality: "N", + details: "Indicates whether the device’s CO sensor is currently triggering a CO alarm.", + xref: { document: "cluster", section: "2.11.6.3" } + }), + + Attribute({ + name: "BatteryAlert", id: 0x3, type: "AlarmStateEnum", access: "R V", conformance: "M", + quality: "N", + details: "Indicates whether the power resource fault detection mechanism is currently triggered at the " + + "device. If the detection mechanism is triggered, this attribute shall be set to Warning or " + + "Critical, otherwise it shall be set to Normal. The battery state shall also be reflected in the " + + "Power Source cluster representing the device’s battery using the appropriate supported attributes " + + "and events.", + xref: { document: "cluster", section: "2.11.6.4" } + }), + + Attribute({ + name: "DeviceMuted", id: 0x4, type: "MuteStateEnum", access: "R V", conformance: "O", quality: "N", + details: "Indicates the whether the audible expression of the device is currently muted. Audible expression " + + "is typically a horn or speaker pattern.", + xref: { document: "cluster", section: "2.11.6.5" } + }), + + Attribute({ + name: "TestInProgress", id: 0x5, type: "bool", access: "R V", conformance: "M", + details: "Indicates whether the device self-test is currently activated. If the device self- test is " + + "activated, this attribute shall be set to True, otherwise it shall be set to False.", + xref: { document: "cluster", section: "2.11.6.6" } + }), + + Attribute({ + name: "HardwareFaultAlert", id: 0x6, type: "bool", access: "R V", conformance: "M", quality: "N", + details: "Indicates whether the hardware fault detection mechanism is currently triggered. If the detection " + + "mechanism is triggered, this attribute shall be set to True, otherwise it shall be set to False.", + xref: { document: "cluster", section: "2.11.6.7" } + }), + + Attribute({ + name: "EndOfServiceAlert", id: 0x7, type: "EndOfServiceEnum", access: "R V", conformance: "M", + quality: "N", + details: "Indicates whether the end-of-service has been triggered at the device. This attribute shall be set " + + "to Expired when the device reaches the end-of-service.", + xref: { document: "cluster", section: "2.11.6.8" } + }), + + Attribute({ + name: "InterconnectSmokeAlarm", id: 0x8, type: "AlarmStateEnum", access: "R V", conformance: "O", + details: "Indicates whether the interconnected smoke alarm is currently triggering by branching devices. When " + + "the interconnected smoke alarm is being triggered, this attribute shall be set to Warning or " + + "Critical, otherwise it shall be set to Normal.", + xref: { document: "cluster", section: "2.11.6.9" } + }), + + Attribute({ + name: "InterconnectCoAlarm", id: 0x9, type: "AlarmStateEnum", access: "R V", conformance: "O", + details: "Indicates whether the interconnected CO alarm is currently triggering by branching devices. When " + + "the interconnected CO alarm is being triggered, this attribute shall be set to Warning or Critical, " + + "otherwise it shall be set to Normal.", + xref: { document: "cluster", section: "2.11.6.10" } + }), + + Attribute({ + name: "ContaminationState", id: 0xa, type: "ContaminationStateEnum", access: "R V", + conformance: "[SMOKE]", + details: "Indicates the contamination level of the smoke sensor.", + xref: { document: "cluster", section: "2.11.6.11" } + }), + + Attribute({ + name: "SmokeSensitivityLevel", id: 0xb, type: "SensitivityEnum", access: "RW VM", + conformance: "[SMOKE]", + details: "Indicates the sensitivity level of the smoke sensor configured on the device.", + xref: { document: "cluster", section: "2.11.6.12" } + }), + + Attribute({ + name: "ExpiryDate", id: 0xc, type: "epoch-s", access: "R V", conformance: "O", quality: "F", + details: "Indicates the date when the device reaches its stated expiry date. After the ExpiryDate has been " + + "reached, the EndOfServiceAlert shall start to be triggered. To account for better customer " + + "experience across time zones, the EndOfServiceAlert may be delayed by up to 24 hours after the " + + "ExpiryDate. Similarly, clients may delay any actions based on the ExpiryDate by up to 24 hours to " + + "best align with the local time zone.", + xref: { document: "cluster", section: "2.11.6.13" } + }), + + Event( + { + name: "SmokeAlarm", id: 0x0, access: "V", conformance: "SMOKE", priority: "critical", + details: "This event shall be generated when SmokeState attribute changes to either Warning or Critical state.", + xref: { document: "cluster", section: "2.11.8.1" } + }, + Field({ + name: "AlarmSeverityLevel", id: 0x0, type: "AlarmStateEnum", conformance: "M", + details: "This field shall indicate the current value of the SmokeState attribute.", + xref: { document: "cluster", section: "2.11.8.1.1" } + }) + ), + + Event( + { + name: "CoAlarm", id: 0x1, access: "V", conformance: "CO", priority: "critical", + details: "This event shall be generated when COState attribute changes to either Warning or Critical state.", + xref: { document: "cluster", section: "2.11.8.2" } + }, + Field({ + name: "AlarmSeverityLevel", id: 0x0, type: "AlarmStateEnum", conformance: "M", + details: "This field shall indicate the current value of the COState attribute.", + xref: { document: "cluster", section: "2.11.8.2.1" } + }) + ), + + Event( + { + name: "LowBattery", id: 0x2, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when BatteryAlert attribute changes to either Warning or Critical " + + "state.", + xref: { document: "cluster", section: "2.11.8.3" } + }, + + Field({ + name: "AlarmSeverityLevel", id: 0x0, type: "AlarmStateEnum", conformance: "M", + details: "This field shall indicate the current value of the BatteryAlert attribute.", + xref: { document: "cluster", section: "2.11.8.3.1" } + }) + ), + + Event({ + name: "HardwareFault", id: 0x3, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when the device detects a hardware fault that leads to setting " + + "HardwareFaultAlert to True.", + xref: { document: "cluster", section: "2.11.8.4" } + }), + + Event({ + name: "EndOfService", id: 0x4, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when the EndOfServiceAlert is set to Expired.", + xref: { document: "cluster", section: "2.11.8.5" } + }), + + Event({ + name: "SelfTestComplete", id: 0x5, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when the SelfTest completes, and the attribute TestInProgress changes " + + "to False.", + xref: { document: "cluster", section: "2.11.8.6" } + }), + + Event({ + name: "AlarmMuted", id: 0x6, access: "V", conformance: "O", priority: "info", + details: "This event shall be generated when the DeviceMuted attribute changes to Muted.", + xref: { document: "cluster", section: "2.11.8.7" } + }), + Event({ + name: "MuteEnded", id: 0x7, access: "V", conformance: "O", priority: "info", + details: "This event shall be generated when DeviceMuted attribute changes to NotMuted.", + xref: { document: "cluster", section: "2.11.8.8" } + }), + + Event( + { + name: "InterconnectSmokeAlarm", id: 0x8, access: "V", conformance: "[SMOKE]", priority: "critical", + details: "This event shall be generated when the device hosting the server receives a smoke alarm from an " + + "interconnected sensor.", + xref: { document: "cluster", section: "2.11.8.9" } + }, + + Field({ + name: "AlarmSeverityLevel", id: 0x0, type: "AlarmStateEnum", conformance: "M", + details: "This field shall indicate the current value of the InterconnectSmokeAlarm attribute.", + xref: { document: "cluster", section: "2.11.8.9.1" } + }) + ), + + Event( + { + name: "InterconnectCoAlarm", id: 0x9, access: "V", conformance: "[CO]", priority: "critical", + details: "This event shall be generated when the device hosting the server receives a CO alarm from an " + + "interconnected sensor.", + xref: { document: "cluster", section: "2.11.8.10" } + }, + + Field({ + name: "AlarmSeverityLevel", id: 0x0, type: "AlarmStateEnum", conformance: "M", + details: "This field shall indicate the current value of the InterconnectCOAlarm attribute.", + xref: { document: "cluster", section: "2.11.8.10.1" } + }) + ), + + Event({ + name: "AllClear", id: 0xa, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when ExpressedState attribute returns to Normal state.", + xref: { document: "cluster", section: "2.11.8.11" } + }), + + Command({ + name: "SelfTestRequest", id: 0x0, access: "O", conformance: "O", direction: "request", + response: "status", + + details: "This command shall initiate a device self-test. The return status shall indicate whether the test " + + "was successfully initiated. Only one SelfTestRequest may be processed at a time. When the value of " + + "the ExpressedState attribute is any of SmokeAlarm, COAlarm, Testing, InterconnectSmoke, " + + "InterconnectCO, the device shall NOT execute the self-test, and shall return status code BUSY." + + "\n" + + "Upon successful acceptance of SelfTestRequest, the TestInProgress attribute shall be set to True " + + "and ExpressedState attribute shall be set to Testing. Any faults identified during the test shall " + + "be reflected in the appropriate attributes and events. Upon completion of the self test procedure, " + + "the SelfTestComplete event shall be generated, the TestInProgress attribute shall be set to False " + + "and ExpressedState attribute shall be updated to reflect the current state of the server.", + + xref: { document: "cluster", section: "2.11.7.1" } + }), + + Datatype( + { name: "AlarmStateEnum", type: "enum8", xref: { document: "cluster", section: "2.11.5.1" } }, + Field({ + name: "Normal", id: 0x0, conformance: "M", description: "Nominal state, the device is not alarming", + details: "This value shall indicate that this alarm is not alarming.", + xref: { document: "cluster", section: "2.11.5.1.1" } + }), + + Field({ + name: "Warning", id: 0x1, conformance: "O", description: "Warning state", + details: "This value shall indicate that this alarm is in a warning state. Alarms in this state SHOULD be " + + "subject to being muted via physical interaction.", + xref: { document: "cluster", section: "2.11.5.1.2" } + }), + + Field({ + name: "Critical", id: 0x2, conformance: "M", description: "Critical state", + details: "This value shall indicate that this alarm is in a critical state. Alarms in this state shall NOT be " + + "subject to being muted via physical interaction.", + xref: { document: "cluster", section: "2.11.5.1.3" } + }) + ), + + Datatype( + { name: "SensitivityEnum", type: "enum8", xref: { document: "cluster", section: "2.11.5.2" } }, + Field({ name: "High", id: 0x0, conformance: "O", description: "High sensitivity" }), + Field({ name: "Standard", id: 0x1, conformance: "M", description: "Standard Sensitivity" }), + Field({ name: "Low", id: 0x2, conformance: "O", description: "Low sensitivity" }) + ), + + Datatype( + { + name: "ExpressedStateEnum", type: "enum8", + details: "This value shall indicate that this alarm is not alarming.", + xref: { document: "cluster", section: "2.11.5.3" } + }, + Field({ name: "Normal", id: 0x0, conformance: "M", description: "Nominal state, the device is not alarming" }), + + Field({ + name: "SmokeAlarm", id: 0x1, conformance: "SMOKE", description: "Smoke Alarm state", + details: "This value shall indicate that this alarm is currently expressing visual indication of Smoke Alarm. " + + "This value shall indicate that the alarm is currently expressing audible indication of Smoke Alarm " + + "unless the DeviceMuted attribute is supported and set to Muted.", + xref: { document: "cluster", section: "2.11.5.3.2" } + }), + + Field({ + name: "CoAlarm", id: 0x2, conformance: "CO", description: "CO Alarm state", + details: "This value shall indicate that this alarm is currently expressing visual indication of CO Alarm. " + + "This value shall indicate that the alarm is currently expressing audible indication of CO Alarm " + + "unless the DeviceMuted attribute is supported and set to Muted.", + xref: { document: "cluster", section: "2.11.5.3.3" } + }), + + Field({ + name: "BatteryAlert", id: 0x3, conformance: "M", description: "Battery Alert State", + details: "This value shall indicate that this alarm is currently expressing visual indication of Critical Low " + + "Battery. This value shall indicate that the alarm is currently expressing audible indication of " + + "Critical Low Battery unless the DeviceMuted attribute is supported and set to Muted.", + xref: { document: "cluster", section: "2.11.5.3.4" } + }), + + Field({ + name: "Testing", id: 0x4, conformance: "M", description: "Test in Progress", + details: "This value shall indicate that this alarm is currently expressing visual and audible indication of " + + "SelfTest.", + xref: { document: "cluster", section: "2.11.5.3.5" } + }), + + Field({ + name: "HardwareFault", id: 0x5, conformance: "M", description: "Hardware Fault Alert State", + details: "This value shall indicate that this alarm is currently expressing visual indication of Hardware " + + "Fault. This value shall indicate that the alarm is currently expressing audible indication of " + + "Hardware Fault unless the DeviceMuted attribute is supported and set to Muted.", + xref: { document: "cluster", section: "2.11.5.3.6" } + }), + + Field({ + name: "EndOfService", id: 0x6, conformance: "M", description: "End of Service Alert State", + details: "This value shall indicate that this alarm is currently expressing visual indication of End Of " + + "Service. This value shall indicate that the alarm is currently expressing audible indication of End " + + "of Service unless the DeviceMuted attribute is supported and set to Muted.", + xref: { document: "cluster", section: "2.11.5.3.7" } + }), + + Field({ + name: "InterconnectSmoke", id: 0x7, conformance: "O", + description: "Interconnected Smoke Alarm State", + details: "This value shall indicate that this alarm is currently expressing visual indication of Smoke Alarm " + + "caused by Interconnect. This value shall indicate that the alarm is currently expressing audible " + + "indication of Smoke Alarm caused by Interconnect unless the DeviceMuted attribute is supported and " + + "set to Muted.", + xref: { document: "cluster", section: "2.11.5.3.8" } + }), + + Field({ + name: "InterconnectCo", id: 0x8, conformance: "O", description: "Interconnected CO Alarm State", + details: "This value shall indicate that this alarm is currently expressing visual indication of CO Alarm " + + "caused by Interconnect. This value shall indicate that the alarm is currently expressing audible " + + "indication of CO Alarm caused by Interconnect unless the DeviceMuted attribute is supported and set " + + "to Muted.", + xref: { document: "cluster", section: "2.11.5.3.9" } + }) + ), + + Datatype( + { name: "MuteStateEnum", type: "enum8", xref: { document: "cluster", section: "2.11.5.4" } }, + Field({ + name: "NotMuted", id: 0x0, conformance: "M", description: "Not Muted", + details: "This value shall indicate that the device is not muted.", + xref: { document: "cluster", section: "2.11.5.4.1" } + }), + Field({ + name: "Muted", id: 0x1, conformance: "M", description: "Muted", + details: "This value shall indicate that the device is muted.", + xref: { document: "cluster", section: "2.11.5.4.2" } + }) + ), + + Datatype( + { name: "EndOfServiceEnum", type: "enum8", xref: { document: "cluster", section: "2.11.5.5" } }, + + Field({ + name: "Normal", id: 0x0, conformance: "M", description: "Device has not expired", + details: "This value shall indicate that the device has not yet reached its end of service, and does not need " + + "to be imminently replaced.", + xref: { document: "cluster", section: "2.11.5.5.2" } + }), + + Field({ + name: "Expired", id: 0x1, conformance: "M", description: "Device has reached its end of service", + details: "This value shall indicate that the device has reached its end of service, and needs to be replaced.", + xref: { document: "cluster", section: "2.11.5.5.1" } + }) + ), + + Datatype( + { + name: "ContaminationStateEnum", type: "enum8", + details: "This value shall indicate that the smoke sensor has nominal contamination levels, no customer " + + "action is required.", + xref: { document: "cluster", section: "2.11.5.6" } + }, + + Field({ name: "Normal", id: 0x0, conformance: "M", description: "Nominal state, the sensor is not contaminated" }), + + Field({ + name: "Low", id: 0x1, conformance: "O", description: "Low contamination", + details: "This value shall indicate that the smoke sensor has detectable contamination levels, but the " + + "contamination is too low to cause a visible or audible alarm.", + xref: { document: "cluster", section: "2.11.5.6.2" } + }), + + Field({ + name: "Warning", id: 0x2, conformance: "O", description: "Warning state", + details: "This value shall indicate that the smoke sensor has contamination levels in a warning state. At " + + "this level, the contamination may cause a visible or audible alarm. User intervention is suggested.", + xref: { document: "cluster", section: "2.11.5.6.3" } + }), + + Field({ + name: "Critical", id: 0x3, conformance: "M", + description: "Critical state, will cause nuisance alarms", + details: "This value shall indicate that the smoke sensor has contamination levels in a critical state. At " + + "this level, the contamination should cause a visible or audible alarm. User intervention is " + + "required. Critical contamination of the sensor shall also be reflected as a HardwareFault.", + xref: { document: "cluster", section: "2.11.5.6.4" } + }) + ) + ), + + Cluster( + { + name: "ElectricalEnergyMeasurement", id: 0x91, classification: "application", pics: "EEM", + details: "This cluster provides a mechanism for querying data about the electrical energy imported or " + + "provided by the server.", + xref: { document: "cluster", section: "2.12" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.12.4" } }, + Field({ + name: "IMPE", conformance: "O.a+", constraint: "0", description: "ImportedEnergy", + details: "The feature indicates the server is capable of measuring how much energy is imported by the server.", + xref: { document: "cluster", section: "2.12.4.1" } + }), + Field({ + name: "EXPE", conformance: "O.a+", constraint: "1", description: "ExportedEnergy", + details: "The feature indicates the server is capable of measuring how much energy is exported by the server.", + xref: { document: "cluster", section: "2.12.4.2" } + }), + + Field({ + name: "CUME", conformance: "O.b+", constraint: "2", description: "CumulativeEnergy", + details: "The feature indicates the server is capable of measuring how much energy has been imported or " + + "exported by the server over the device’s lifetime. This measurement may start from when a device’s " + + "firmware is updated to include this feature, when a device’s firmware is updated to correct " + + "measurement errors, or when a device is factory reset.", + xref: { document: "cluster", section: "2.12.4.3" } + }), + + Field({ + name: "PERE", conformance: "O.b+", constraint: "3", description: "PeriodicEnergy", + details: "The feature indicates the server is capable of measuring how much energy has been imported or " + + "exported by the server during a certain period of time. The start and end times for measurement " + + "periods shall be determined by the server, and may represent overlapping periods.", + xref: { document: "cluster", section: "2.12.4.4" } + }) + ), + + Attribute({ + name: "Accuracy", id: 0x0, type: "MeasurementAccuracyStruct", access: "R V", conformance: "M", + quality: "F", + details: "Indicates the accuracy of energy measurement by this server. The value of the MeasurementType field " + + "on this MeasurementAccuracyStruct shall be ElectricalEnergy.", + xref: { document: "cluster", section: "2.12.6.1" } + }), + + Attribute({ + name: "CumulativeEnergyImported", id: 0x1, type: "EnergyMeasurementStruct", access: "R V", + conformance: "IMPE & CUME", default: null, quality: "X Q", + + details: "Indicates the most recent measurement of cumulative energy imported by the server over the lifetime " + + "of the device, and the timestamp of when the measurement was recorded." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the cumulative energy imported cannot currently be determined, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.12.6.2" } + }), + + Attribute({ + name: "CumulativeEnergyExported", id: 0x2, type: "EnergyMeasurementStruct", access: "R V", + conformance: "EXPE & CUME", default: null, quality: "X Q", + + details: "Indicates the most recent measurement of cumulative energy exported by the server over the lifetime " + + "of the device, and the timestamp of when the measurement was recorded." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the cumulative energy exported cannot currently be determined, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.12.6.3" } + }), + + Attribute({ + name: "PeriodicEnergyImported", id: 0x3, type: "EnergyMeasurementStruct", access: "R V", + conformance: "IMPE & PERE", default: null, quality: "X Q", + + details: "Indicates the most recent measurement of energy imported by the server and the period during which " + + "it was measured." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the periodic energy imported cannot currently be determined, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.12.6.4" } + }), + + Attribute({ + name: "PeriodicEnergyExported", id: 0x4, type: "EnergyMeasurementStruct", access: "R V", + conformance: "EXPE & PERE", default: null, quality: "X Q", + + details: "Indicates the most recent measurement of energy exported by the server and the period during which " + + "it was measured." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the periodic energy exported cannot currently be determined, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.12.6.5" } + }), + + Attribute({ + name: "CumulativeEnergyReset", id: 0x5, type: "CumulativeEnergyResetStruct", access: "R V", + conformance: "[CUME]", default: null, quality: "X", + details: "Indicates when cumulative measurements were most recently zero.", + xref: { document: "cluster", section: "2.12.6.6" } + }), + + Event( + { + name: "CumulativeEnergyMeasured", id: 0x0, access: "V", conformance: "CUME", priority: "info", + details: "This event shall be generated when the server takes a snapshot of the cumulative energy imported by " + + "the server, exported from the server, or both, but not more frequently than the rate mentioned in " + + "the description above of the related attribute.", + xref: { document: "cluster", section: "2.12.7.1" } + }, + + Field({ + name: "EnergyImported", id: 0x0, type: "EnergyMeasurementStruct", conformance: "CUME & IMPE", + details: "This field shall be the value of CumulativeEnergyImported attribute at the timestamp indicated in " + + "its EndTimestamp field, EndSystime field, or both.", + xref: { document: "cluster", section: "2.12.7.1.1" } + }), + + Field({ + name: "EnergyExported", id: 0x1, type: "EnergyMeasurementStruct", conformance: "CUME & EXPE", + details: "This field shall be the value of CumulativeEnergyExported attribute at the timestamp indicated in " + + "its EndTimestamp field, EndSystime field, or both.", + xref: { document: "cluster", section: "2.12.7.1.2" } + }) + ), + + Event( + { + name: "PeriodicEnergyMeasured", id: 0x1, access: "V", conformance: "PERE", priority: "info", + details: "This event shall be generated when the server reaches the end of a reporting period for imported " + + "energy, exported energy, or both.", + xref: { document: "cluster", section: "2.12.7.2" } + }, + + Field({ + name: "EnergyImported", id: 0x0, type: "EnergyMeasurementStruct", conformance: "PERE & IMPE", + details: "This field shall be the value of PeriodicEnergyImported attribute at the timestamp indicated in its " + + "EndTimestamp field, EndSystime field, or both.", + xref: { document: "cluster", section: "2.12.7.2.1" } + }), + + Field({ + name: "EnergyExported", id: 0x1, type: "EnergyMeasurementStruct", conformance: "PERE & EXPE", + details: "This field shall be the value of PeriodicEnergyExported attribute at the timestamp indicated in its " + + "EndTimestamp field, EndSystime field, or both.", + xref: { document: "cluster", section: "2.12.7.2.2" } + }) + ), + + Datatype( + { + name: "EnergyMeasurementStruct", type: "struct", + + details: "This struct shall indicate the amount of energy measured during a given measurement period." + + "\n" + + "A server which does not have the ability to determine the time in UTC, or has not yet done so, " + + "shall use the system time fields to specify the measurement period and observation times." + + "\n" + + "A server which has determined the time in UTC shall use the timestamp fields to specify the " + + "measurement period. Such a server may also include the systime fields to indicate how many seconds " + + "had passed since boot for a given timestamp; this allows for client-side resolution of UTC time for " + + "previous reports that only included systime.", + + xref: { document: "cluster", section: "2.12.5.1" } + }, + + Field({ + name: "Energy", id: 0x0, type: "energy-mWh", conformance: "M", constraint: "min 0", + + details: "This field shall be the reported energy." + + "\n" + + "If the EnergyMeasurementStruct represents cumulative energy, then this shall represent the " + + "cumulative energy recorded at either the value of the EndTimestamp field or the value of the " + + "EndSystime field, or both." + + "\n" + + "If the EnergyMeasurementStruct represents periodic energy, then this shall represent the energy " + + "recorded during the period specified by either the StartTimestamp and EndTimestamp fields, the " + + "period specified by the StartSystime and EndSystime fields, or both.", + + xref: { document: "cluster", section: "2.12.5.1.1" } + }), + + Field({ + name: "StartTimestamp", id: 0x1, type: "epoch-s", conformance: "desc", + + details: "This field shall indicate the timestamp in UTC of the beginning of the period during which the " + + "value of the Energy field was measured." + + "\n" + + "If this EnergyMeasurementStruct represents cumulative energy, this field shall be omitted." + + "\n" + + "Otherwise, if the server had determined the time in UTC at or before the beginning of the " + + "measurement period, this field shall be indicated." + + "\n" + + "Otherwise, if the server had not yet determined the time in UTC at or before the beginning of the " + + "measurement period, or does not have the capability of determining the time in UTC, this field " + + "shall be omitted.", + + xref: { document: "cluster", section: "2.12.5.1.2" } + }), + + Field({ + name: "EndTimestamp", id: 0x2, type: "epoch-s", conformance: "desc", + constraint: "min startTimestamp + 1", + + details: "This field shall indicate the timestamp in UTC of the end of the period during which the value of " + + "the Energy field was measured." + + "\n" + + "If the server had determined the time in UTC by the end of the measurement period, this field shall " + + "be indicated." + + "\n" + + "Otherwise, if the server had not yet determined the time in UTC by the end of the measurement " + + "period, or does not have the capability of determining the time in UTC, this field shall be omitted.", + + xref: { document: "cluster", section: "2.12.5.1.3" } + }), + + Field({ + name: "StartSystime", id: 0x3, type: "systime-ms", conformance: "desc", + + details: "This field shall indicate the time elapsed since boot at the beginning of the period during which " + + "the value of the Energy field was measured." + + "\n" + + "If this EnergyMeasurementStruct represents cumulative energy, this field shall be omitted. " + + "Otherwise, if the server had not yet determined the time in UTC at the start of the measurement" + + "\n" + + "period, or does not have the capability of determining the time in UTC, this field shall be " + + "indicated." + + "\n" + + "Otherwise, if the server had determined the time in UTC at or before the beginning of the " + + "measurement period, this field may be omitted; if it is indicated, its value shall be the time " + + "elapsed since boot at the UTC time indicated in StartTimestamp.", + + xref: { document: "cluster", section: "2.12.5.1.4" } + }), + + Field({ + name: "EndSystime", id: 0x4, type: "systime-ms", conformance: "desc", + constraint: "min startSystime + 1", + + details: "This field shall indicate the time elapsed since boot at the end of the period during which the " + + "value of the Energy field was measured." + + "\n" + + "If the server had not yet determined the time in UTC by the end of the measurement period, or does " + + "not have the capability of determining the time in UTC, this field shall be indicated." + + "\n" + + "Otherwise, if the server had determined the time in UTC by the end of the measurement period, this " + + "field may be omitted; if it is indicated, its value shall be the time elapsed since boot at the UTC " + + "time indicated in EndTimestamp.", + + xref: { document: "cluster", section: "2.12.5.1.5" } + }) + ), + + Datatype( + { + name: "CumulativeEnergyResetStruct", type: "struct", + details: "This struct shall represent the times at which cumulative measurements were last zero, either due " + + "to initialization of the device, or an internal reset of the cumulative value.", + xref: { document: "cluster", section: "2.12.5.2" } + }, + + Field({ + name: "ImportedResetTimestamp", id: 0x0, type: "epoch-s", conformance: "[IMPE]", default: null, + quality: "X", + + details: "This field shall indicate the timestamp in UTC when the value of the Energy field on the " + + "CumulativeEnergyImported attribute was most recently zero." + + "\n" + + "If the server had determined the time in UTC when the value of the Energy field on the " + + "CumulativeEnergyImported attribute was most recently zero, this field shall be indicated." + + "\n" + + "Otherwise, if the server had not yet determined the time in UTC when the value of the Energy field " + + "on the CumulativeEnergyImported attribute was most recently zero, or does not have the capability " + + "of determining the time in UTC, this field shall be omitted." + + "\n" + + "If the timestamp in UTC when the value of the Energy field on the CumulativeEnergyImported " + + "attribute was most recently zero cannot currently be determined, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.12.5.2.1" } + }), + + Field({ + name: "ExportedResetTimestamp", id: 0x1, type: "epoch-s", conformance: "[EXPE]", default: null, + quality: "X", + + details: "This field shall indicate the timestamp in UTC when the value of the Energy field on the " + + "CumulativeEnergyExported attribute was most recently zero." + + "\n" + + "If the server had determined the time in UTC when the value of the Energy field on the " + + "CumulativeEnergyExported attribute was most recently zero, this field shall be indicated." + + "\n" + + "Otherwise, if the server had not yet determined the time in UTC when the value of the Energy field " + + "on the CumulativeEnergyExported attribute was most recently zero, or does not have the capability " + + "of determining the time in UTC, this field shall be omitted." + + "\n" + + "If the timestamp in UTC when the value of the Energy field on the CumulativeEnergyExported " + + "attribute was most recently zero cannot currently be determined, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.12.5.2.2" } + }), + + Field({ + name: "ImportedResetSystime", id: 0x2, type: "systime-ms", conformance: "[IMPE]", default: null, + quality: "X", + + details: "This field shall indicate the time elapsed since boot when the value of the Energy field on the " + + "CumulativeEnergyImported attribute was most recently zero." + + "\n" + + "If the server had not yet determined the time in UTC when the value of the Energy field on the " + + "CumulativeEnergyImported attribute was most recently zero, or does not have the capability of " + + "determining the time in UTC, this field shall be indicated." + + "\n" + + "Otherwise, if the server had determined the time in UTC when the value of the Energy field on the " + + "CumulativeEnergyImported attribute was most recently zero, this field may be omitted; if it is " + + "indicated, its value shall be the time elapsed since boot at the UTC time indicated in " + + "ImportedResetTimestamp.", + + xref: { document: "cluster", section: "2.12.5.2.3" } + }), + + Field({ + name: "ExportedResetSystime", id: 0x3, type: "systime-ms", conformance: "[EXPE]", default: null, + quality: "X", + + details: "This field shall indicate the time elapsed since boot when the value of the Energy field on the " + + "CumulativeEnergyExported attribute was most recently zero." + + "\n" + + "If the server had not yet determined the time in UTC when the value of the Energy field on the " + + "CumulativeEnergyExported attribute was most recently zero, or does not have the capability of " + + "determining the time in UTC, this field shall be indicated." + + "\n" + + "Otherwise, if the server had determined the time in UTC when the value of the Energy field on the " + + "CumulativeEnergyExported attribute was most recently zero, this field may be omitted; if it is " + + "indicated, its value shall be the time elapsed since boot at the UTC time indicated in " + + "ImportedResetTimestamp.", + + xref: { document: "cluster", section: "2.12.5.2.4" } + }) + ) + ), + + Cluster( + { + name: "ElectricalPowerMeasurement", id: 0x90, classification: "application", pics: "EPM", + details: "This cluster provides a mechanism for querying data about electrical power as measured by the " + + "server.", + xref: { document: "cluster", section: "2.13" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.13.4" } }, + Field({ + name: "DIRC", conformance: "O.a+", constraint: "0", description: "DirectCurrent", + details: "This feature indicates the cluster can measure a direct current.", + xref: { document: "cluster", section: "2.13.4.1" } + }), + Field({ + name: "ALTC", conformance: "O.a+", constraint: "1", description: "AlternatingCurrent", + details: "This feature indicates the cluster can measure an alternating current.", + xref: { document: "cluster", section: "2.13.4.2" } + }), + + Field({ + name: "POLY", conformance: "[ALTC]", constraint: "2", description: "PolyphasePower", + details: "This feature indicates the cluster represents the collective measurements for a Polyphase power " + + "supply.", + xref: { document: "cluster", section: "2.13.4.3" } + }), + + Field({ + name: "HARM", conformance: "[ALTC]", constraint: "3", description: "Harmonics", + details: "This feature indicates the cluster can measure the harmonics of an alternating current.", + xref: { document: "cluster", section: "2.13.4.4" } + }), + Field({ + name: "PWRQ", conformance: "[ALTC]", constraint: "4", description: "PowerQuality", + details: "This feature indicates the cluster can measure the harmonic phases of an alternating current.", + xref: { document: "cluster", section: "2.13.4.5" } + }) + ), + + Attribute({ + name: "PowerMode", id: 0x0, type: "PowerModeEnum", access: "R V", conformance: "M", + details: "This shall indicate the current mode of the server. For some servers, such as an EV, this may " + + "change depending on the mode of charging or discharging.", + xref: { document: "cluster", section: "2.13.6.1" } + }), + + Attribute({ + name: "NumberOfMeasurementTypes", id: 0x1, type: "uint8", access: "R V", conformance: "M", + constraint: "min 1", quality: "F", + details: "This shall indicate the maximum number of measurement types the server is capable of reporting.", + xref: { document: "cluster", section: "2.13.6.2" } + }), + + Attribute( + { + name: "Accuracy", id: 0x2, type: "list", access: "R V", conformance: "M", + constraint: "1 to numberOfMeasurementTypes", quality: "F", + details: "This shall indicate a list of accuracy specifications for the measurement types supported by the " + + "server. There shall be an entry for ActivePower, as well as any other measurement types implemented " + + "by this server.", + xref: { document: "cluster", section: "2.13.6.3" } + }, + + Field({ name: "entry", type: "MeasurementAccuracyStruct" }) + ), + + Attribute( + { + name: "Ranges", id: 0x3, type: "list", access: "R V", conformance: "O", + constraint: "0 to numberOfMeasurementTypes", default: [], quality: "Q", + + details: "This shall indicate a list of measured ranges for different measurement types. Each measurement " + + "type shall have at most one entry in this list, representing the range of measurements in the most " + + "recent measurement period." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.", + + xref: { document: "cluster", section: "2.13.6.4" } + }, + + Field({ name: "entry", type: "MeasurementRangeStruct" }) + ), + + Attribute({ + name: "Voltage", id: 0x4, type: "voltage-mV", access: "R V", conformance: "O", default: null, + quality: "X Q", + + details: "This shall indicate the most recent Voltage reading in millivolts (mV)." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the voltage cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.5" } + }), + + Attribute({ + name: "ActiveCurrent", id: 0x5, type: "amperage-mA", access: "R V", conformance: "O", default: null, + quality: "X Q", + + details: "This shall indicate the most recent ActiveCurrent reading in milliamps (mA)." + + "\n" + + "A positive value represents current flowing into the server, while a negative value represents " + + "current flowing out of the server." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the current cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.6" } + }), + + Attribute({ + name: "ReactiveCurrent", id: 0x6, type: "amperage-mA", access: "R V", conformance: "[ALTC]", + default: null, quality: "X Q", + + details: "This shall indicate the most recent ReactiveCurrent reading in milliamps (mA)." + + "\n" + + "A positive value represents current flowing into the server, while a negative value represents " + + "current flowing out of the server." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the current cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.7" } + }), + + Attribute({ + name: "ApparentCurrent", id: 0x7, type: "amperage-mA", access: "R V", conformance: "[ALTC]", + constraint: "min 0", default: null, quality: "X Q", + + details: "This shall indicate the most recent ApparentCurrent (square root sum of the squares of active and " + + "reactive currents) reading in milliamps (mA)." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the active or reactive currents cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.8" } + }), + + Attribute({ + name: "ActivePower", id: 0x8, type: "power-mW", access: "R V", conformance: "M", default: null, + quality: "X Q", + + details: "This shall indicate the most recent ActivePower reading in milliwatts (mW). If the power cannot be " + + "measured, a value of null shall be returned." + + "\n" + + "A positive value represents power imported, while a negative value represents power exported." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the Polyphase Power feature is set, this value represents the combined active power imported or " + + "exported.", + + xref: { document: "cluster", section: "2.13.6.9" } + }), + + Attribute({ + name: "ReactivePower", id: 0x9, type: "power-mW", access: "R V", conformance: "[ALTC]", + default: null, quality: "X Q", + + details: "This shall indicate the most recent ReactivePower reading in millivolt-amps reactive (mVAR). A " + + "positive value represents power imported, while a negative value represents power exported." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the reactive power cannot be measured, a value of null shall be returned." + + "\n" + + "If the Polyphase Power feature is supported, this value represents the combined reactive power " + + "imported or exported.", + + xref: { document: "cluster", section: "2.13.6.10" } + }), + + Attribute({ + name: "ApparentPower", id: 0xa, type: "power-mW", access: "R V", conformance: "[ALTC]", + default: null, quality: "X Q", + + details: "This shall indicate the most recent ApparentPower reading in millivolt-amps (mVA)." + + "\n" + + "A positive value represents power imported, while a negative value represents power exported." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the apparent power cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.11" } + }), + + Attribute({ + name: "RmsVoltage", id: 0xb, type: "voltage-mV", access: "R V", conformance: "[ALTC]", + default: null, quality: "X Q", + + details: "This shall indicate the most recent RMSVoltage reading in millivolts (mV)." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the RMS voltage cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.12" } + }), + + Attribute({ + name: "RmsCurrent", id: 0xc, type: "amperage-mA", access: "R V", conformance: "[ALTC]", + default: null, quality: "X Q", + + details: "This shall indicate the most recent RMSCurrent reading in milliamps (mA)." + + "\n" + + "A positive value represents current flowing into the server, while a negative value represents " + + "current flowing out of the server." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the RMS current cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.13" } + }), + + Attribute({ + name: "RmsPower", id: 0xd, type: "power-mW", access: "R V", conformance: "[ALTC]", default: null, + quality: "X Q", + + details: "This shall indicate the most recent RMSPower reading in milliwatts (mW)." + + "\n" + + "A positive value represents power imported, while a negative value represents power exported." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the RMS power cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.14" } + }), + + Attribute({ + name: "Frequency", id: 0xe, type: "int64", access: "R V", conformance: "[ALTC]", + constraint: "0 to 1000000", default: null, quality: "X Q", + + details: "This shall indicate the most recent Frequency reading in millihertz (mHz)." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds." + + "\n" + + "If the frequency cannot be measured, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.6.15" } + }), + + Attribute( + { + name: "HarmonicCurrents", id: 0xf, type: "list", access: "R V", conformance: "HARM", + constraint: "desc", default: null, quality: "X Q", + + details: "This shall indicate a list of HarmonicMeasurementStruct values, with each HarmonicMeasurementStruct " + + "representing the harmonic current reading for the harmonic order specified by Order." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.", + + xref: { document: "cluster", section: "2.13.6.16" } + }, + + Field({ name: "entry", type: "HarmonicMeasurementStruct" }) + ), + + Attribute( + { + name: "HarmonicPhases", id: 0x10, type: "list", access: "R V", conformance: "PWRQ", + constraint: "desc", default: null, quality: "X Q", + + details: "This shall indicate a list of HarmonicMeasurementStruct values, with each HarmonicMeasurementStruct " + + "representing the most recent phase of the harmonic current reading for the harmonic" + + "\n" + + "order specified by Order." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.", + + xref: { document: "cluster", section: "2.13.6.17" } + }, + + Field({ name: "entry", type: "HarmonicMeasurementStruct" }) + ), + + Attribute({ + name: "PowerFactor", id: 0x11, type: "int64", access: "R V", conformance: "[ALTC]", + constraint: "-10000 to 10000", default: null, quality: "X Q", + + details: "This shall indicate the Power Factor ratio in +/- 1/100ths of a percent." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.", + + xref: { document: "cluster", section: "2.13.6.18" } + }), + + Attribute({ + name: "NeutralCurrent", id: 0x12, type: "amperage-mA", access: "R V", conformance: "[POLY]", + default: null, quality: "X Q", + + details: "This shall indicate the most recent NeutralCurrent reading in milliamps (mA). Typically this is a " + + "derived value, taking the magnitude of the vector sum of phase currents." + + "\n" + + "If the neutral current cannot be measured or derived, a value of null shall be returned." + + "\n" + + "A positive value represents an imbalance between the phase currents when power is imported. A " + + "negative value represents an imbalance between the phase currents when power is exported." + + "\n" + + "The reporting interval of this attribute shall be manufacturer dependent. The server may choose to " + + "omit publication of deltas considered not meaningful." + + "\n" + + "The server shall NOT mark this attribute ready for report if the last time this was done was more " + + "recently than 1 second ago." + + "\n" + + "The server may delay marking this attribute ready for report for longer periods if needed, however " + + "the server shall NOT delay marking this attribute as ready for report for longer than 60 seconds.", + + xref: { document: "cluster", section: "2.13.6.19" } + }), + + Event( + { + name: "MeasurementPeriodRanges", id: 0x0, access: "V", conformance: "Ranges", priority: "info", + details: "If supported, this event shall be generated at the end of a measurement period. The start and end " + + "times for measurement periods shall be determined by the server, and may represent overlapping " + + "periods.", + xref: { document: "cluster", section: "2.13.7.1" } + }, + + Field( + { + name: "Ranges", id: 0x0, type: "list", conformance: "M", default: "RV", + details: "This shall indicate the value of the Ranges attribute at the time of event generation.", + xref: { document: "cluster", section: "2.13.7.1.1" } + }, + Field({ name: "entry", type: "MeasurementRangeStruct" }) + ) + ), + + Datatype( + { name: "PowerModeEnum", type: "enum8", xref: { document: "cluster", section: "2.13.5.1" } }, + Field({ name: "Unknown", id: 0x0, conformance: "M" }), + Field({ name: "Dc", id: 0x1, conformance: "M", description: "Direct current" }), + Field({ + name: "Ac", id: 0x2, conformance: "M", + description: "Alternating current, either single-phase or polyphase" + }) + ), + + Datatype( + { + name: "MeasurementRangeStruct", type: "struct", + + details: "This struct shall indicate the maximum and minimum values of a given measurement type during a " + + "measurement period, along with the observation times of these values." + + "\n" + + "A server which does not have the ability to determine the time in UTC, or has not yet done so, " + + "shall use the system time fields to specify the measurement period and observation times." + + "\n" + + "A server which has determined the time in UTC shall use the timestamp fields to specify the " + + "measurement period and observation times. Such a server may also include the systime fields to " + + "indicate how many seconds had passed since boot for a given timestamp; this allows for client-side " + + "resolution of UTC time for previous reports that only included systime.", + + xref: { document: "cluster", section: "2.13.5.2" } + }, + + Field({ + name: "MeasurementType", id: 0x0, type: "MeasurementTypeEnum", conformance: "M", + details: "This field shall be the type of measurement for the range provided.", + xref: { document: "cluster", section: "2.13.5.2.1" } + }), + + Field({ + name: "Min", id: 0x1, type: "int64", conformance: "M", + details: "This field shall be the smallest measured value for the associated measurement over either the " + + "period between StartTimestamp and EndTimestamp, or the period between StartSystime and EndSystime, " + + "or both.", + xref: { document: "cluster", section: "2.13.5.2.2" } + }), + + Field({ + name: "Max", id: 0x2, type: "int64", conformance: "M", + details: "This field shall be the largest measured value for the associated measurement over the period " + + "between either StartTimestamp and EndTimestamp or the period between StartSystime and EndSystime, " + + "or both.", + xref: { document: "cluster", section: "2.13.5.2.3" } + }), + + Field({ + name: "StartTimestamp", id: 0x3, type: "epoch-s", conformance: "EndTimestamp", + details: "This field shall be the timestamp in UTC of the beginning of the measurement period." + + "\n" + + "If the server had not yet determined the time in UTC at or before the beginning of the measurement " + + "period, or does not have the capability of determining the time in UTC, this field shall be omitted.", + xref: { document: "cluster", section: "2.13.5.2.4" } + }), + + Field({ + name: "EndTimestamp", id: 0x4, type: "epoch-s", conformance: "desc", + constraint: "min startTimestamp + 1", + details: "This field shall be the timestamp in UTC of the end of the measurement period." + + "\n" + + "If the server had not yet determined the time in UTC at or before the beginning of the measurement " + + "period, or does not have the capability of determining the time in UTC, this field shall be omitted.", + xref: { document: "cluster", section: "2.13.5.2.5" } + }), + + Field({ + name: "MinTimestamp", id: 0x5, type: "epoch-s", conformance: "EndTimestamp", + details: "This field shall be the most recent timestamp in UTC that the value in the Min field was measured." + + "\n" + + "This field shall be greater than or equal to the value of the StartTimestamp field. This field " + + "shall be less than or equal to the value of the EndTimestamp field.", + xref: { document: "cluster", section: "2.13.5.2.6" } + }), + + Field({ + name: "MaxTimestamp", id: 0x6, type: "epoch-s", conformance: "EndTimestamp", + constraint: "min minTimestamp + 1", + details: "This field shall be the most recent timestamp in UTC of the value in the Max field. This field " + + "shall be greater than or equal to the value of the StartTimestamp field. This field shall be less " + + "than or equal to the value of the EndTimestamp field.", + xref: { document: "cluster", section: "2.13.5.2.7" } + }), + + Field({ + name: "StartSystime", id: 0x7, type: "systime-ms", conformance: "EndSystime", + details: "This field shall be the time since boot of the beginning of the measurement period." + + "\n" + + "If the server had determined the time in UTC at or before the start of the measurement period, this " + + "field may be omitted along with the EndSystime, MinSystime, and MaxSystime fields.", + xref: { document: "cluster", section: "2.13.5.2.8" } + }), + + Field({ + name: "EndSystime", id: 0x8, type: "systime-ms", conformance: "desc", + constraint: "min startSystime + 1", + details: "This field shall be the time since boot of the end of the measurement period." + + "\n" + + "If the server had determined the time in UTC at the end of the measurement period, this field may " + + "be omitted along with the StartSystime field, MinSystime, and MaxSystime fields.", + xref: { document: "cluster", section: "2.13.5.2.9" } + }), + + Field({ + name: "MinSystime", id: 0x9, type: "systime-ms", conformance: "EndSystime", + details: "This field shall be the measurement time since boot of the value in the Min field was measured. " + + "This field shall be greater than or equal to the value of the StartSystime field." + + "\n" + + "This field shall be less than or equal to the value of the EndSystime field.", + xref: { document: "cluster", section: "2.13.5.2.10" } + }), + + Field({ + name: "MaxSystime", id: 0xa, type: "systime-ms", conformance: "EndSystime", + constraint: "min minSystime + 1", + details: "This field shall be the measurement time since boot of the value in the Max field. This field shall " + + "be greater than or equal to the value of the StartSystime field." + + "\n" + + "This field shall be less than or equal to the value of the EndSystime field.", + xref: { document: "cluster", section: "2.13.5.2.11" } + }) + ), + + Datatype( + { name: "HarmonicMeasurementStruct", type: "struct", xref: { document: "cluster", section: "2.13.5.3" } }, + + Field({ + name: "Order", id: 0x0, type: "uint8", conformance: "M", constraint: "min 1", default: 1, + details: "This field shall be the order of the harmonic being measured. Typically this is an odd number, but " + + "servers may choose to report even harmonics.", + xref: { document: "cluster", section: "2.13.5.3.1" } + }), + + Field({ + name: "Measurement", id: 0x1, type: "int64", conformance: "M", default: null, quality: "X", + + details: "This field shall be the measured value for the given harmonic order." + + "\n" + + "For the Harmonic Currents attribute, this value is the most recently measured harmonic current " + + "reading in milliamps (mA). A positive value indicates that the measured harmonic current is " + + "positive, and a negative value indicates that the measured harmonic current is negative." + + "\n" + + "For the Harmonic Phases attribute, this value is the most recent phase of the given harmonic order" + + "\n" + + "in millidegrees (mDeg). A positive value indicates that the measured phase is leading, and a " + + "negative value indicates that the measured phase is lagging." + + "\n" + + "If this measurement is not currently available, a value of null shall be returned.", + + xref: { document: "cluster", section: "2.13.5.3.2" } + }) + ) + ), + + Cluster( + { + name: "ColorControl", id: 0x300, classification: "application", pics: "CC", + + details: "This cluster provides an interface for changing the color of a light. Color is specified according " + + "to the CIE 1931 Color space. Color control is carried out in terms of x,y values, as defined by " + + "this specification." + + "\n" + + "Additionally, color may optionally be controlled in terms of color temperature, or as hue and " + + "saturation values based on optionally variable RGB and W color points. It is recommended that the " + + "hue and saturation are interpreted according to the HSV (a.k.a. HSB) color model." + + "\n" + + "Control over luminance is not included, as this is provided by means of the Level Control for " + + "Lighting cluster. It is recommended that the level provided by this cluster be interpreted as " + + "representing a proportion of the maximum intensity achievable at the current color.", + + xref: { document: "cluster", section: "3.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 7 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "3.2.4" } }, + Field({ + name: "HS", conformance: "EHUE, O", constraint: "0", description: "HueSaturation", + details: "Supports color specification via hue/saturation." + }), + Field({ + name: "EHUE", conformance: "CL, O", constraint: "1", description: "EnhancedHue", + details: "Enhanced hue is supported." + }), + Field({ + name: "CL", conformance: "O", constraint: "2", description: "ColorLoop", + details: "Color loop is supported." + }), + Field({ + name: "XY", conformance: "O", constraint: "3", description: "Xy", + details: "Supports color specification via XY." + }), + Field({ + name: "CT", conformance: "O", constraint: "4", description: "ColorTemperature", + details: "Supports specification of color temperature." + }) + ), + + Attribute( + { + name: "CurrentHue", id: 0x0, type: "uint8", access: "R V", conformance: "HS", constraint: "max 254", + default: 0, quality: "N P Q", + + details: "The CurrentHue attribute contains the current hue value of the light. It is updated as fast as " + + "practical during commands that change the hue." + + "\n" + + "The hue in degrees shall be related to the CurrentHue attribute by the relationship:" + + "\n" + + "Hue = \"CurrentHue\" * 360 / 254" + + "\n" + + "where CurrentHue is in the range from 0 to 254 inclusive." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", + + xref: { document: "cluster", section: "3.2.7.2" } + } + ), + + Attribute( + { + name: "CurrentSaturation", id: 0x1, type: "uint8", access: "R V", conformance: "HS", + constraint: "max 254", default: 0, quality: "N S P Q", + + details: "Indicates the current saturation value of the light. It is updated as fast as practical during " + + "commands that change the saturation." + + "\n" + + "The saturation (on a scale from 0.0 to 1.0) shall be related to the CurrentSaturation attribute by " + + "the relationship:" + + "\n" + + "Saturation = \"CurrentSaturation\" / 254" + + "\n" + + "where CurrentSaturation is in the range from 0 to 254 inclusive." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", + + xref: { document: "cluster", section: "3.2.7.3" } + } + ), + + Attribute({ + name: "RemainingTime", id: 0x2, type: "uint16", access: "R V", conformance: "O", + constraint: "max 65534", default: 0, quality: "Q", + + details: "Indicates the time remaining, in 1/10ths of a second, until transitions due to the currently active " + + "command will be complete." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • When it changes from 0 to any value higher than 10, or" + + "\n" + + " • When it changes, with a delta larger than 10, caused by the invoke of a command, or" + + "\n" + + " • When it changes to 0." + + "\n" + + "For commands with a transition time or changes to the transition time less than 1 second, changes " + + "to this attribute shall NOT be reported." + + "\n" + + "As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the " + + "reporting of this attribute in order to keep track of the remaining duration.", + + xref: { document: "cluster", section: "3.2.7.4" } + }), + + Attribute( + { + name: "CurrentX", id: 0x3, type: "uint16", access: "R V", conformance: "XY", + constraint: "max 65279", default: 24939, quality: "N S P Q", + + details: "Indicates the current value of the normalized chromaticity value x, as defined in the CIE xyY Color " + + "Space. It is updated as fast as practical during commands that change the color." + + "\n" + + "The value of x shall be related to the CurrentX attribute by the relationship" + + "\n" + + "x = \"CurrentX\" / 65536" + + "\n" + + "where CurrentX is in the range from 0 to 65279 inclusive." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", + + xref: { document: "cluster", section: "3.2.7.5" } + } + ), + + Attribute( + { + name: "CurrentY", id: 0x4, type: "uint16", access: "R V", conformance: "XY", + constraint: "max 65279", default: 24701, quality: "N S P Q", + + details: "Indicates the current value of the normalized chromaticity value y, as defined in the CIE xyY Color " + + "Space. It is updated as fast as practical during commands that change the color." + + "\n" + + "The value of y shall be related to the CurrentY attribute by the relationship" + + "\n" + + "y = \"CurrentY\" / 65536" + + "\n" + + "where CurrentY is in the range from 0 to 65279 inclusive." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", + + xref: { document: "cluster", section: "3.2.7.6" } + } + ), + + Attribute({ + name: "DriftCompensation", id: 0x5, type: "DriftCompensationEnum", access: "R V", conformance: "O", + details: "Indicates what mechanism, if any, is in use for compensation for color/intensity drift over time.", + xref: { document: "cluster", section: "3.2.7.7" } + }), + + Attribute({ + name: "CompensationText", id: 0x6, type: "string", access: "R V", conformance: "O", + constraint: "max 254", + details: "This attribute shall contain a textual indication of what mechanism, if any, is in use to " + + "compensate for color/intensity drift over time.", + xref: { document: "cluster", section: "3.2.7.8" } + }), + + Attribute( + { + name: "ColorTemperatureMireds", id: 0x7, type: "uint16", access: "R V", conformance: "CT", + constraint: "max 65279", default: 250, quality: "N S P Q", + + details: "Indicates a scaled inverse of the current value of the color temperature. The unit of " + + "ColorTemperatureMireds is the mired (micro reciprocal degree), a.k.a. mirek (micro reciprocal " + + "kelvin). It is updated as fast as practical during commands that change the color." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition." + + "\n" + + "The color temperature value in kelvins shall be related to the ColorTemperatureMireds attribute in " + + "mired by the relationship" + + "\n" + + "\"Color temperature [K]\" = \"1,000,000\" / \"ColorTemperatureMireds\"" + + "\n" + + "where ColorTemperatureMireds is in the range from 1 to 65279 inclusive, giving a color temperature " + + "range from 1,000,000 K to 15.32 K." + + "\n" + + "If this attribute is implemented then the ColorMode attribute shall also be implemented.", + + xref: { document: "cluster", section: "3.2.7.9" } + } + ), + + Attribute({ + name: "ColorMode", id: 0x8, type: "ColorModeEnum", access: "R V", conformance: "M", default: 1, + quality: "N", + details: "Indicates which attributes are currently determining the color of the device." + + "\n" + + "The value of the ColorMode attribute cannot be written directly - it is set upon reception of any " + + "command in section Commands to the appropriate mode for that command.", + xref: { document: "cluster", section: "3.2.7.10" } + }), + + Attribute({ + name: "Options", id: 0xf, type: "OptionsBitmap", access: "RW VO", conformance: "M", + constraint: "desc", default: 0, + + details: "Indicates a bitmap that determines the default behavior of some cluster commands. Each command that " + + "is dependent on the Options attribute shall first construct a temporary Options bitmap that is in " + + "effect during the command processing. The temporary Options bitmap has the same format and meaning " + + "as the Options attribute, but includes any bits that may be overridden by command fields." + + "\n" + + "This attribute is meant to be changed only during commissioning." + + "\n" + + "Below is the format and description of the Options attribute and temporary Options bitmap and the " + + "effect on dependent commands." + + "\n" + + "Command execution shall NOT continue beyond the Options processing if all of these criteria are " + + "true:" + + "\n" + + " • The On/Off cluster exists on the same endpoint as this cluster." + + "\n" + + " • The OnOff attribute of the On/Off cluster, on this endpoint, is FALSE." + + "\n" + + " • The value of the ExecuteIfOff bit is 0.", + + xref: { document: "cluster", section: "3.2.7.11" } + }), + + Attribute({ + name: "NumberOfPrimaries", id: 0x10, type: "uint8", access: "R V", conformance: "M", + constraint: "max 6", quality: "X F", + + details: "Indicates the number of color primaries implemented on this device. A value of null shall indicate " + + "that the number of primaries is unknown." + + "\n" + + "Where this attribute is implemented, the attributes below for indicating the “x” and “y” color " + + "values of the primaries shall also be implemented for each of the primaries from 1 to " + + "NumberOfPrimaries, without leaving gaps. Implementation of the Primary1Intensity attribute and " + + "subsequent intensity attributes is optional.", + + xref: { document: "cluster", section: "3.2.7.24" } + }), + + Attribute( + { + name: "Primary1X", id: 0x11, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 0, O", + constraint: "max 65279", quality: "F", + details: "Indicates the normalized chromaticity value x for this primary, as defined in the CIE xyY Color " + + "Space." + + "\n" + + "The value of x shall be related to the Primary1X attribute by the relationship x = Primary1X / " + + "65536 (Primary1X in the range 0 to 65279 inclusive)", + xref: { document: "cluster", section: "3.2.7.25" } + } + ), + + Attribute( + { + name: "Primary1Y", id: 0x12, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 0, O", + constraint: "max 65279", quality: "F", + details: "Indicates the normalized chromaticity value y for this primary, as defined in the CIE xyY Color " + + "Space." + + "\n" + + "The value of y shall be related to the Primary1Y attribute by the relationship y = Primary1Y / " + + "65536 (Primary1Y in the range 0 to 65279 inclusive)", + xref: { document: "cluster", section: "3.2.7.26" } + } + ), + + Attribute({ + name: "Primary1Intensity", id: 0x13, type: "uint8", access: "R V", + conformance: "NumberOfPrimaries > 0, O", quality: "X F", + + details: "Indicates a representation of the maximum intensity of this primary as defined in the Dimming Light " + + "Curve in the Ballast Configuration cluster (see Ballast Configuration Cluster), normalized such " + + "that the primary with the highest maximum intensity contains the value 254." + + "\n" + + "A value of null shall indicate that this primary is not available." + + "\n" + + "3.2.7.28. Primary2X, Primary2Y, Primary2Intensity, Primary3X, Primary3Y, Primary3Intensity, " + + "Primary4X, Primary4Y, Primary4Intensity, Primary5X, Primary5Y, Primary5Intensity, Primary6X, " + + "Primary6Y and Primary6Intensity Attributes" + + "\n" + + "These attributes shall represent the capabilities of the 2nd, 3rd, 4th, 5th and 6th primaries, " + + "where present, in the same way as for the Primary1X, Primary1Y and Primary1Intensity attributes.", + + xref: { document: "cluster", section: "3.2.7.27" } + }), + + Attribute({ + name: "Primary2X", id: 0x15, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 1, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary2Y", id: 0x16, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 1, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary2Intensity", id: 0x17, type: "uint8", access: "R V", + conformance: "NumberOfPrimaries > 1, O", quality: "X F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary3X", id: 0x19, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 2, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary3Y", id: 0x1a, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 2, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary3Intensity", id: 0x1b, type: "uint8", access: "R V", + conformance: "NumberOfPrimaries > 2, O", quality: "X F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary4X", id: 0x20, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 3, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary4Y", id: 0x21, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 3, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary4Intensity", id: 0x22, type: "uint8", access: "R V", + conformance: "NumberOfPrimaries > 3, O", quality: "X F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary5X", id: 0x24, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 4, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary5Y", id: 0x25, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 4, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary5Intensity", id: 0x26, type: "uint8", access: "R V", + conformance: "NumberOfPrimaries > 4, O", quality: "X F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary6X", id: 0x28, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 5, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary6Y", id: 0x29, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 5, O", + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "Primary6Intensity", id: 0x2a, type: "uint8", access: "R V", + conformance: "NumberOfPrimaries > 5, O", quality: "X F", + xref: { document: "cluster", section: "3.2.7" } + }), + + Attribute( + { + name: "WhitePointX", id: 0x30, type: "uint16", access: "RW VM", conformance: "O", + constraint: "max 65279", + details: "Indicates the normalized chromaticity value x, as defined in the CIE xyY Color Space, of the " + + "current white point of the device." + + "\n" + + "The value of x shall be related to the WhitePointX attribute by the relationship x = WhitePointX / " + + "65536 (WhitePointX in the range 0 to 65279 inclusive)", + xref: { document: "cluster", section: "3.2.7.29" } + } + ), + + Attribute( + { + name: "WhitePointY", id: 0x31, type: "uint16", access: "RW VM", conformance: "O", + constraint: "max 65279", + details: "Indicates the normalized chromaticity value y, as defined in the CIE xyY Color Space, of the " + + "current white point of the device." + + "\n" + + "The value of y shall be related to the WhitePointY attribute by the relationship y = WhitePointY / " + + "65536 (WhitePointY in the range 0 to 65279 inclusive)", + xref: { document: "cluster", section: "3.2.7.30" } + } + ), + + Attribute( + { + name: "ColorPointRx", id: 0x32, type: "uint16", access: "RW VM", conformance: "O", + constraint: "max 65279", + details: "Indicates the normalized chromaticity value x, as defined in the CIE xyY Color Space, of the red " + + "color point of the device." + + "\n" + + "The value of x shall be related to the ColorPointRX attribute by the relationship x = ColorPointRX " + + "/ 65536 (ColorPointRX in the range 0 to 65279 inclusive)", + xref: { document: "cluster", section: "3.2.7.31" } + } + ), + + Attribute( + { + name: "ColorPointRy", id: 0x33, type: "uint16", access: "RW VM", conformance: "O", + constraint: "max 65279", + details: "Indicates the normalized chromaticity value y, as defined in the CIE xyY Color Space, of the red " + + "color point of the device." + + "\n" + + "The value of y shall be related to the ColorPointRY attribute by the relationship y = ColorPointRY " + + "/ 65536 (ColorPointRY in the range 0 to 65279 inclusive)", + xref: { document: "cluster", section: "3.2.7.32" } + } + ), + + Attribute({ + name: "ColorPointRIntensity", id: 0x34, type: "uint8", access: "RW VM", conformance: "O", + quality: "X", + + details: "Indicates a representation of the relative intensity of the red color point as defined in the " + + "Dimming Light Curve in the Ballast Configuration cluster (see Ballast Configuration Cluster), " + + "normalized such that the color point with the highest relative intensity contains the value 254." + + "\n" + + "A value of null shall indicate an invalid value." + + "\n" + + "3.2.7.34. ColorPointGX, ColorPointGY, ColorPointGIntensity, ColorPointBX, ColorPointBY and " + + "ColorPointBIntensity Attributes" + + "\n" + + "These attributes shall represent the chromaticity values and intensities of the green and blue " + + "color points, in the same way as for the ColorPointRX, ColorPointRY and ColorPointRIntensity " + + "attributes." + + "\n" + + "If any one of these red, green or blue color point attributes is implemented then they shall all be " + + "implemented.", + + xref: { document: "cluster", section: "3.2.7.33" } + }), + + Attribute({ + name: "ColorPointGx", id: 0x36, type: "uint16", access: "RW VM", conformance: "O", + constraint: "max 65279", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "ColorPointGy", id: 0x37, type: "uint16", access: "RW VM", conformance: "O", + constraint: "max 65279", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "ColorPointGIntensity", id: 0x38, type: "uint8", access: "RW VM", conformance: "O", + quality: "X", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "ColorPointBx", id: 0x3a, type: "uint16", access: "RW VM", conformance: "O", + constraint: "max 65279", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "ColorPointBy", id: 0x3b, type: "uint16", access: "RW VM", conformance: "O", + constraint: "max 65279", + xref: { document: "cluster", section: "3.2.7" } + }), + Attribute({ + name: "ColorPointBIntensity", id: 0x3c, type: "uint8", access: "RW VM", conformance: "O", + quality: "X", + xref: { document: "cluster", section: "3.2.7" } + }), + + Attribute({ + name: "EnhancedCurrentHue", id: 0x4000, type: "uint16", access: "R V", conformance: "EHUE", + default: 0, quality: "N S Q", + + details: "Indicates the non-equidistant steps along the CIE 1931 color triangle, and it provides 16-bits " + + "precision." + + "\n" + + "The upper 8 bits of this attribute shall be used as an index in the implementation specific XY " + + "lookup table to provide the non-equidistant steps. The lower 8 bits shall be used to interpolate " + + "between these steps in a linear way in order to provide color zoom for the user." + + "\n" + + "To provide compatibility with clients not supporting EHUE, the CurrentHue attribute shall contain a " + + "hue value in the range 0 to 254, calculated from the EnhancedCurrentHue attribute." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", + + xref: { document: "cluster", section: "3.2.7.12" } + }), + + Attribute({ + name: "EnhancedColorMode", id: 0x4001, type: "EnhancedColorModeEnum", access: "R V", + conformance: "M", default: 1, quality: "N S", + + details: "Indicates which attributes are currently determining the color of the device." + + "\n" + + "To provide compatibility with clients not supporting EHUE, the original ColorMode attribute shall " + + "indicate CurrentHue and CurrentSaturation when the light uses the EnhancedCurrentHue attribute. If " + + "the ColorMode attribute is changed, its new value shall be copied to the EnhancedColorMode " + + "attribute.", + + xref: { document: "cluster", section: "3.2.7.13" } + }), + + Attribute({ + name: "ColorLoopActive", id: 0x4002, type: "uint8", access: "R V", conformance: "CL", + constraint: "max 1", default: 0, quality: "N S", + details: "Indicates the current active status of the color loop. If this attribute has the value 0, the color " + + "loop shall NOT be active. If this attribute has the value 1, the color loop shall be active.", + xref: { document: "cluster", section: "3.2.7.14" } + }), + + Attribute({ + name: "ColorLoopDirection", id: 0x4003, type: "uint8", access: "R V", conformance: "CL", + constraint: "max 1", default: 0, quality: "N S", + details: "Indicates the current direction of the color loop. If this attribute has the value 0, the " + + "EnhancedCurrentHue attribute shall be decremented. If this attribute has the value 1, the " + + "EnhancedCurrentHue attribute shall be incremented.", + xref: { document: "cluster", section: "3.2.7.15" } + }), + + Attribute({ + name: "ColorLoopTime", id: 0x4004, type: "uint16", access: "R V", conformance: "CL", default: 25, + quality: "N S", + details: "Indicates the number of seconds it shall take to perform a full color loop, i.e., to cycle all " + + "values of the EnhancedCurrentHue attribute (between 0 and 65534).", + xref: { document: "cluster", section: "3.2.7.16" } + }), + + Attribute({ + name: "ColorLoopStartEnhancedHue", id: 0x4005, type: "uint16", access: "R V", conformance: "CL", + default: 8960, + details: "Indicates the value of the EnhancedCurrentHue attribute from which the color loop shall be started.", + xref: { document: "cluster", section: "3.2.7.17" } + }), + + Attribute({ + name: "ColorLoopStoredEnhancedHue", id: 0x4006, type: "uint16", access: "R V", conformance: "CL", + default: 0, + details: "Indicates the value of the EnhancedCurrentHue attribute before the color loop was started. Once the " + + "color loop is complete, the EnhancedCurrentHue attribute shall be restored to this value.", + xref: { document: "cluster", section: "3.2.7.18" } + }), + + Attribute({ + name: "ColorCapabilities", id: 0x400a, type: "ColorCapabilitiesBitmap", access: "R V", + conformance: "M", constraint: "max 31", default: 0, + details: "Indicates the color control capabilities of the device." + + "\n" + + "Bits 0-4 of the ColorCapabilities attribute shall have the same values as the corresponding bits of " + + "the FeatureMap attribute. All other bits in ColorCapabilities shall be 0.", + xref: { document: "cluster", section: "3.2.7.19" } + }), + + Attribute({ + name: "ColorTempPhysicalMinMireds", id: 0x400b, type: "uint16", access: "R V", conformance: "CT", + constraint: "1 to 65279", + details: "Indicates the minimum mired value supported by the hardware. ColorTempPhysicalMinMireds corresponds " + + "to the maximum color temperature in kelvins supported by the hardware." + + "\n" + + "ColorTempPhysicalMinMireds <= ColorTemperatureMireds.", + xref: { document: "cluster", section: "3.2.7.20" } + }), + + Attribute({ + name: "ColorTempPhysicalMaxMireds", id: 0x400c, type: "uint16", access: "R V", conformance: "CT", + constraint: "max 65279", + details: "Indicates the maximum mired value supported by the hardware. ColorTempPhysicalMaxMireds corresponds " + + "to the minimum color temperature in kelvins supported by the hardware." + + "\n" + + "ColorTemperatureMireds <= ColorTempPhysicalMaxMireds.", + xref: { document: "cluster", section: "3.2.7.21" } + }), + + Attribute( + { + name: "CoupleColorTempToLevelMiNMireds", id: 0x400d, type: "uint16", access: "R V", + conformance: "CT | ColorTemperatureMireds", + constraint: "colorTempPhysicalMinMireds to colorTemperatureMireds", + + details: "Indicates a lower bound on the value of the ColorTemperatureMireds attribute for the purposes of " + + "coupling the ColorTemperatureMireds attribute to the CurrentLevel attribute when the " + + "CoupleColorTempToLevel bit of the Options attribute of the Level Control cluster is equal to 1. " + + "When coupling the ColorTemperatureMireds attribute to the CurrentLevel attribute, this value shall " + + "correspond to a CurrentLevel value of 254 (100%)." + + "\n" + + "This attribute shall be set such that the following relationship exists: ColorTempPhysicalMinMireds " + + "<= CoupleColorTempToLevelMinMireds <= ColorTemperatureMireds" + + "\n" + + "Note that since this attribute is stored as a micro reciprocal degree (mired) value (i.e. color " + + "temperature in kelvins = 1,000,000 / CoupleColorTempToLevelMinMireds), the " + + "CoupleColorTempToLevelMinMireds attribute corresponds to an upper bound on the value of the color " + + "temperature" + + "\n" + + "in kelvins supported by the device.", + + xref: { document: "cluster", section: "3.2.7.22" } + } + ), + + Attribute({ + name: "StartUpColorTemperatureMireds", id: 0x4010, type: "uint16", access: "RW VM", + conformance: "CT | ColorTemperatureMireds", constraint: "1 to 65279", quality: "X N", + details: "Indicates the desired startup color temperature value the light shall use when it is supplied with " + + "power and this value shall be reflected in the ColorTemperatureMireds attribute. In addition, the " + + "ColorMode and EnhancedColorMode attributes shall be set to 2 (ColorTemperatureMireds). The values " + + "of the StartUpColorTemperatureMireds attribute are listed in the table below,", + xref: { document: "cluster", section: "3.2.7.23" } + }), + + Command( + { + name: "MoveToHue", id: 0x0, access: "O", conformance: "HS", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.4" } + }, + Field({ + name: "Hue", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the hue to be moved to.", + xref: { document: "cluster", section: "3.2.8.4.1" } + }), + Field({ + name: "Direction", id: 0x1, type: "DirectionEnum", conformance: "M", + details: "This field shall indicate the movement direction.", + xref: { document: "cluster", section: "3.2.8.4.2" } + }), + + Field({ + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field shall indicate, in 1/10ths of a second, the time that shall be taken to move to the new " + + "hue.", + xref: { document: "cluster", section: "3.2.8.4.3" } + }), + + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "MoveHue", id: 0x1, access: "O", conformance: "HS", direction: "request", response: "status", + xref: { document: "cluster", section: "3.2.8.5" } + }, + Field({ + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", + details: "This field shall indicate the mode of movement.", + xref: { document: "cluster", section: "3.2.8.5.1" } + }), + + Field({ + name: "Rate", id: 0x1, type: "uint8", conformance: "M", + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + + "device’s hue of one unit.", + xref: { document: "cluster", section: "3.2.8.5.2" } + }), + + Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "StepHue", id: 0x2, access: "O", conformance: "HS", direction: "request", response: "status", + xref: { document: "cluster", section: "3.2.8.6" } + }, + Field({ + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", + details: "This field shall indicate the mode of the step to be performed.", + xref: { document: "cluster", section: "3.2.8.6.1" } + }), + + Field({ + name: "StepSize", id: 0x1, type: "uint8", conformance: "M", + details: "This field shall indicate the change to be added to (or subtracted from) the current value of the " + + "device’s hue.", + xref: { document: "cluster", section: "3.2.8.6.2" } + }), + + Field({ + name: "TransitionTime", id: 0x2, type: "uint8", conformance: "M", + + details: "This field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the step." + + "\n" + + "A step is a change in the device’s hue of Step size units." + + "\n" + + "NOTE" + + "\n" + + "Here the TransitionTime data field is of data type uint8, where uint16 is more common for " + + "TransitionTime data fields in other clusters / commands.", + + xref: { document: "cluster", section: "3.2.8.6.3" } + }), + + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "MoveToSaturation", id: 0x3, access: "O", conformance: "HS", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.7" } + }, + Field({ name: "Saturation", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254" }), + Field({ name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", constraint: "max 65534" }), + Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "MoveSaturation", id: 0x4, access: "O", conformance: "HS", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.8" } + }, + Field({ + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", + details: "This field shall indicate the mode of movement, as described in the MoveHue command.", + xref: { document: "cluster", section: "3.2.8.8.1" } + }), + + Field({ + name: "Rate", id: 0x1, type: "uint8", conformance: "M", + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + + "device’s saturation of one unit.", + xref: { document: "cluster", section: "3.2.8.8.2" } + }), + + Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "StepSaturation", id: 0x5, access: "O", conformance: "HS", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.9" } + }, + Field({ + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", + details: "This field shall indicate the mode of the step to be performed, as described in the StepHue command.", + xref: { document: "cluster", section: "3.2.8.9.1" } + }), + + Field({ + name: "StepSize", id: 0x1, type: "uint8", conformance: "M", + details: "This field shall indicate the change to be added to (or subtracted from) the current value of the " + + "device’s saturation.", + xref: { document: "cluster", section: "3.2.8.9.2" } + }), + + Field({ + name: "TransitionTime", id: 0x2, type: "uint8", conformance: "M", + + details: "This field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the " + + "step. A step is a change in the device’s saturation of Step size units." + + "\n" + + "NOTE" + + "\n" + + "Here the TransitionTime data field is of data type uint8, where uint16 is more common for " + + "TransitionTime data fields in other clusters / commands.", + + xref: { document: "cluster", section: "3.2.8.9.3" } + }), + + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "MoveToHueAndSaturation", id: 0x6, access: "O", conformance: "HS", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.10" } + }, + Field({ name: "Hue", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254" }), + Field({ name: "Saturation", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254" }), + Field({ name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534" }), + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "MoveToColor", id: 0x7, access: "O", conformance: "XY", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.11" } + }, + Field({ name: "ColorX", id: 0x0, type: "uint16", conformance: "M", constraint: "max 65279" }), + Field({ name: "ColorY", id: 0x1, type: "uint16", conformance: "M", constraint: "max 65279" }), + Field({ name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534" }), + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "MoveColor", id: 0x8, access: "O", conformance: "XY", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.12" } + }, + + Field({ + name: "RateX", id: 0x0, type: "int16", conformance: "M", + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + + "device’s CurrentX attribute of one unit.", + xref: { document: "cluster", section: "3.2.8.12.1" } + }), + + Field({ + name: "RateY", id: 0x1, type: "int16", conformance: "M", + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + + "device’s CurrentY attribute of one unit.", + xref: { document: "cluster", section: "3.2.8.12.2" } + }), + + Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "StepColor", id: 0x9, access: "O", conformance: "XY", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.13" } + }, + Field({ name: "StepX", id: 0x0, type: "int16", conformance: "M" }), + Field({ name: "StepY", id: 0x1, type: "int16", conformance: "M" }), + + Field({ + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "The field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the color " + + "change.", + xref: { document: "cluster", section: "3.2.8.13.2" } + }), + + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "MoveToColorTemperature", id: 0xa, access: "O", conformance: "CT", direction: "request", + response: "status", + xref: { document: "cluster", section: "3.2.8.14" } + }, + Field({ name: "ColorTemperatureMireds", id: 0x0, type: "uint16", conformance: "M", constraint: "max 65279" }), + Field({ name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", constraint: "max 65534" }), + Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "EnhancedMoveToHue", id: 0x40, access: "O", conformance: "EHUE", direction: "request", + response: "status", + details: "This command allows the light to be moved in a smooth continuous transition from their current hue " + + "to a target hue.", + xref: { document: "cluster", section: "3.2.8.15" } + }, + + Field({ + name: "EnhancedHue", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall indicate the target extended hue for the light.", + xref: { document: "cluster", section: "3.2.8.15.1" } + }), + Field({ + name: "Direction", id: 0x1, type: "DirectionEnum", conformance: "M", + details: "This field shall indicate the movement direction.", + xref: { document: "cluster", section: "3.2.8.15.2" } + }), + Field({ + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field shall indicate the transition time, as described in the MoveToHue command.", + xref: { document: "cluster", section: "3.2.8.15.3" } + }), + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "EnhancedMoveHue", id: 0x41, access: "O", conformance: "EHUE", direction: "request", + response: "status", + details: "This command allows the light to start a continuous transition starting from their current hue.", + xref: { document: "cluster", section: "3.2.8.16" } + }, + + Field({ + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the mode of movement, as described in the MoveHue command.", + xref: { document: "cluster", section: "3.2.8.16.1" } + }), + + Field({ + name: "Rate", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + + "extended hue of a device by one unit.", + xref: { document: "cluster", section: "3.2.8.16.2" } + }), + + Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "EnhancedStepHue", id: 0x42, access: "O", conformance: "EHUE", direction: "request", + response: "status", + details: "This command allows the light to be moved in a stepped transition from their current hue, resulting " + + "in a linear transition through XY space.", + xref: { document: "cluster", section: "3.2.8.17" } + }, + + Field({ + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the mode of the step to be performed, as described in the StepHue command.", + xref: { document: "cluster", section: "3.2.8.17.1" } + }), + + Field({ + name: "StepSize", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall indicate the change to be added to (or subtracted from) the current value of the " + + "device’s enhanced hue.", + xref: { document: "cluster", section: "3.2.8.17.2" } + }), + + Field({ + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + + details: "The field shall indicate, in units of 1/10ths of a second, the time that shall be taken to perform " + + "the step. A step is a change to the device’s enhanced hue of a magnitude corresponding to the " + + "StepSize field." + + "\n" + + "NOTE" + + "\n" + + "Here TransitionTime data field is of data type uint16, while the TransitionTime data field of the " + + "StepHue command is of data type uint8.", + + xref: { document: "cluster", section: "3.2.8.17.3" } + }), + + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "EnhancedMoveToHueAndSaturation", id: 0x43, access: "O", conformance: "EHUE", + direction: "request", response: "status", + details: "This command allows the light to be moved in a smooth continuous transition from their current hue " + + "to a target hue and from their current saturation to a target saturation.", + xref: { document: "cluster", section: "3.2.8.18" } + }, + + Field({ + name: "EnhancedHue", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall indicate the target extended hue for the light.", + xref: { document: "cluster", section: "3.2.8.18.1" } + }), + Field({ + name: "Saturation", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the saturation, as described in the MoveToHueAndSaturation command.", + xref: { document: "cluster", section: "3.2.8.18.2" } + }), + Field({ + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field shall indicate the transition time, as described in the MoveToHue command.", + xref: { document: "cluster", section: "3.2.8.18.3" } + }), + Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "ColorLoopSet", id: 0x44, access: "O", conformance: "CL", direction: "request", + response: "status", + details: "This command allows a color loop to be activated such that the color light cycles through its range " + + "of hues.", + xref: { document: "cluster", section: "3.2.8.19" } + }, + + Field({ + name: "UpdateFlags", id: 0x0, type: "UpdateFlagsBitmap", conformance: "M", + details: "This field shall indicate which color loop attributes to update (from the values supplied in the " + + "other fields, see field descriptions below) before the color loop is started.", + xref: { document: "cluster", section: "3.2.8.19.1" } + }), + + Field({ + name: "Action", id: 0x1, type: "ColorLoopActionEnum", conformance: "M", + details: "This field shall indicate the action to take for the color loop.", + xref: { document: "cluster", section: "3.2.8.19.2" } + }), + Field({ + name: "Direction", id: 0x2, type: "ColorLoopDirectionEnum", conformance: "M", + details: "This field shall indicate the direction for the color loop.", + xref: { document: "cluster", section: "3.2.8.19.3" } + }), + Field({ + name: "Time", id: 0x3, type: "uint16", conformance: "M", + details: "This field shall indicate the number of seconds over which to perform a full color loop.", + xref: { document: "cluster", section: "3.2.8.19.4" } + }), + Field({ name: "StartHue", id: 0x4, type: "uint16", conformance: "M" }), + Field({ name: "OptionsMask", id: 0x5, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x6, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "StopMoveStep", id: 0x47, access: "O", conformance: "HS | XY | CT", direction: "request", + response: "status", + details: "This command is provided to allow MoveTo and Step commands to be stopped." + + "\n" + + "NOTE This automatically provides symmetry to the Level Control cluster." + + "\n" + + "NOTE The StopMoveStep command has no effect on an active color loop.", + xref: { document: "cluster", section: "3.2.8.20" } + }, + + Field({ name: "OptionsMask", id: 0x0, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x1, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "MoveColorTemperature", id: 0x4b, access: "O", conformance: "CT", direction: "request", + response: "status", + details: "This command allows the color temperature of the light to be moved at a specified rate.", + xref: { document: "cluster", section: "3.2.8.21" } + }, + + Field({ + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", + details: "This field shall indicate the mode of movement, as described in the MoveHue command.", + xref: { document: "cluster", section: "3.2.8.21.1" } + }), + + Field({ + name: "Rate", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the color " + + "temperature of a device by one unit.", + xref: { document: "cluster", section: "3.2.8.21.2" } + }), + + Field({ + name: "ColorTemperatureMinimumMireds", id: 0x2, type: "uint16", conformance: "M", + constraint: "max 65279", + + details: "This field shall indicate a lower bound on the ColorTemperatureMireds attribute (≡ an upper bound " + + "on the color temperature in kelvins) for the current move operation" + + "\n" + + "ColorTempPhysicalMinMireds <= ColorTemperatureMinimumMireds field <= ColorTemperatureMireds" + + "\n" + + "As such if the move operation takes the ColorTemperatureMireds attribute towards the value of the " + + "ColorTemperatureMinimumMireds field it shall be clipped so that the above invariant is satisfied. " + + "If the ColorTemperatureMinimumMireds field is set to 0, ColorTempPhysicalMinMireds shall be used as " + + "the lower bound for the ColorTemperatureMireds attribute.", + + xref: { document: "cluster", section: "3.2.8.21.3" } + }), + + Field({ + name: "ColorTemperatureMaximumMireds", id: 0x3, type: "uint16", conformance: "M", + constraint: "max 65279", + + details: "This field shall indicate an upper bound on the ColorTemperatureMireds attribute (≡ a lower bound " + + "on the color temperature in kelvins) for the current move operation" + + "\n" + + "ColorTemperatureMireds <= ColorTemperatureMaximumMireds field <= ColorTempPhysicalMaxMireds" + + "\n" + + "As such if the move operation takes the ColorTemperatureMireds attribute towards the value of the " + + "ColorTemperatureMaximumMireds field it shall be clipped so that the above invariant is satisfied. " + + "If the ColorTemperatureMaximumMireds field is set to 0, ColorTempPhysicalMaxMireds shall be used as " + + "the upper bound for the ColorTemperatureMireds attribute.", + + xref: { document: "cluster", section: "3.2.8.21.4" } + }), + + Field({ name: "OptionsMask", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x5, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Command( + { + name: "StepColorTemperature", id: 0x4c, access: "O", conformance: "CT", direction: "request", + response: "status", + details: "This command allows the color temperature of the light to be stepped with a specified step size.", + xref: { document: "cluster", section: "3.2.8.22" } + }, + + Field({ + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", + details: "This field shall indicate the mode of the step to be performed, as described in the StepHue command.", + xref: { document: "cluster", section: "3.2.8.22.1" } + }), + + Field({ + name: "StepSize", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall indicate the change to be added to (or subtracted from) the current value of the " + + "device’s color temperature.", + xref: { document: "cluster", section: "3.2.8.22.2" } + }), + + Field({ + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field shall indicate, in units of 1/10ths of a second, the time that shall be taken to perform " + + "the step. A step is a change to the device’s color temperature of a magnitude corresponding to the " + + "StepSize field.", + xref: { document: "cluster", section: "3.2.8.22.3" } + }), + + Field({ + name: "ColorTemperatureMinimumMireds", id: 0x3, type: "uint16", conformance: "M", + constraint: "max 65279", + + details: "This field shall indicate a lower bound on the ColorTemperatureMireds attribute (≡ an upper bound " + + "on the color temperature in kelvins) for the current step operation" + + "\n" + + "ColorTempPhysicalMinMireds <= ColorTemperatureMinimumMireds field <= ColorTemperatureMireds" + + "\n" + + "As such if the step operation takes the ColorTemperatureMireds attribute towards the value of the " + + "ColorTemperatureMinimumMireds field it shall be clipped so that the above invariant is satisfied. " + + "If the ColorTemperatureMinimumMireds field is set to 0, ColorTempPhysicalMinMireds shall be used as " + + "the lower bound for the ColorTemperatureMireds attribute.", + + xref: { document: "cluster", section: "3.2.8.22.4" } + }), + + Field({ + name: "ColorTemperatureMaximumMireds", id: 0x4, type: "uint16", conformance: "M", + constraint: "max 65279", + + details: "This field shall indicate an upper bound on the ColorTemperatureMireds attribute (≡ a lower bound " + + "on the color temperature in kelvins) for the current step operation" + + "\n" + + "ColorTemperatureMireds ≤ ColorTemperatureMaximumMireds field ≤ ColorTempPhysicalMaxMireds" + + "\n" + + "As such if the step operation takes the ColorTemperatureMireds attribute towards the value of the " + + "ColorTemperatureMaximumMireds field it shall be clipped so that the above invariant is satisfied. " + + "If the ColorTemperatureMaximumMireds field is set to 0, ColorTempPhysicalMaxMireds shall be used as " + + "the upper bound for the ColorTemperatureMireds attribute.", + + xref: { document: "cluster", section: "3.2.8.22.5" } + }), + + Field({ name: "OptionsMask", id: 0x5, type: "Options", conformance: "M", constraint: "desc", default: 0 }), + Field({ name: "OptionsOverride", id: 0x6, type: "Options", conformance: "M", constraint: "desc", default: 0 }) + ), + + Datatype( + { name: "ColorCapabilitiesBitmap", type: "map16", xref: { document: "cluster", section: "3.2.6.1" } }, + Field({ name: "HueSaturation", constraint: "0", description: "Supports color specification via hue/saturation." }), + Field({ name: "EnhancedHue", constraint: "1", description: "Enhanced hue is supported." }), + Field({ name: "ColorLoop", constraint: "2", description: "Color loop is supported." }), + Field({ name: "Xy", constraint: "3", description: "Supports color specification via XY." }), + Field({ + name: "ColorTemperature", constraint: "4", + description: "Supports color specification via color temperature." + }) + ), + + Datatype( + { name: "OptionsBitmap", type: "map8", xref: { document: "cluster", section: "3.2.6.2" } }, + Field({ + name: "ExecuteIfOff", constraint: "0", description: "Dependency on On/Off cluster", + details: "This bit shall indicate if this cluster server instance has a dependency with the On/Off cluster.", + xref: { document: "cluster", section: "3.2.6.2.1" } + }) + ), + + Datatype( + { + name: "UpdateFlagsBitmap", type: "map8", + details: "This data type is derived from map8 and is used in the ColorLoopSet command.", + xref: { document: "cluster", section: "3.2.6.3" } + }, + + Field( + { + name: "UpdateAction", constraint: "0", + description: "Device adheres to the associated action field.", + + details: "This bit shall indicate whether the server adheres to the Action field in order to process the " + + "command." + + "\n" + + " • 0 = Device shall ignore the Action field." + + "\n" + + " • 1 = Device shall adhere to the Action field.", + + xref: { document: "cluster", section: "3.2.6.3.1" } + } + ), + + Field( + { + name: "UpdateDirection", constraint: "1", + description: "Device updates the associated direction attribute.", + + details: "This bit shall indicate whether the device updates the ColorLoopDirection attribute with the " + + "Direction field." + + "\n" + + " • 0 = Device shall ignore the Direction field." + + "\n" + + " • 1 = Device shall update the ColorLoopDirection attribute with the value of the Direction field.", + + xref: { document: "cluster", section: "3.2.6.3.2" } + } + ), + + Field( + { + name: "UpdateTime", constraint: "2", description: "Device updates the associated time attribute.", + + details: "This bit shall indicate whether the device updates the ColorLoopTime attribute with the Time field." + + "\n" + + " • 0 = Device shall ignore the Time field." + + "\n" + + " • 1 = Device shall update the value of the ColorLoopTime attribute with the value of the Time " + + " field.", + + xref: { document: "cluster", section: "3.2.6.3.3" } + } + ), + + Field( + { + name: "UpdateStartHue", constraint: "3", + description: "Device updates the associated start hue attribute.", + + details: "This bit shall indicate whether the device updates the ColorLoopStartEnhancedHue attribute with the " + + "value of the StartHue field." + + "\n" + + " • 0 = Device shall ignore the StartHue field." + + "\n" + + " • 1 = Device shall update the value of the ColorLoopStartEnhancedHue attribute with the value of " + + " the StartHue field.", + + xref: { document: "cluster", section: "3.2.6.3.4" } + } + ) + ), + + Datatype( + { name: "DriftCompensationEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.4" } }, + Field({ name: "None", id: 0x0, conformance: "M", description: "There is no compensation." }), + Field({ + name: "OtherOrUnknown", id: 0x1, conformance: "M", + description: "The compensation is based on other or unknown mechanism." + }), + Field({ + name: "TemperatureMonitoring", id: 0x2, conformance: "M", + description: "The compensation is based on temperature monitoring." + }), + Field({ + name: "OpticalLuminanceMonitoringAndFeedback", id: 0x3, conformance: "M", + description: "The compensation is based on optical luminance monitoring and feedback." + }), + Field({ + name: "OpticalColorMonitoringAndFeedback", id: 0x4, conformance: "M", + description: "The compensation is based on optical color monitoring and feedback." + }) + ), + + Datatype( + { name: "ColorModeEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.5" } }, + Field({ + name: "CurrentHueAndCurrentSaturation", id: 0x0, conformance: "M", + description: "The current hue and saturation attributes determine the color." + }), + Field({ + name: "CurrentXAndCurrentY", id: 0x1, conformance: "M", + description: "The current X and Y attributes determine the color." + }), + Field({ + name: "ColorTemperatureMireds", id: 0x2, conformance: "M", + description: "The color temperature attribute determines the color." + }) + ), + + Datatype( + { name: "EnhancedColorModeEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.6" } }, + Field({ + name: "CurrentHueAndCurrentSaturation", id: 0x0, conformance: "M", + description: "The current hue and saturation attributes determine the color." + }), + Field({ + name: "CurrentXAndCurrentY", id: 0x1, conformance: "M", + description: "The current X and Y attributes determine the color." + }), + Field({ + name: "ColorTemperatureMireds", id: 0x2, conformance: "M", + description: "The color temperature attribute determines the color." + }), + Field({ + name: "EnhancedCurrentHueAndCurrentSaturation", id: 0x3, conformance: "M", + description: "The enhanced current hue and saturation attributes determine the color." + }) + ), + + Datatype( + { name: "DirectionEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.7" } }, + Field({ name: "Shortest", id: 0x0, conformance: "M", description: "Shortest distance" }), + Field({ name: "Longest", id: 0x1, conformance: "M", description: "Longest distance" }), + Field({ name: "Up", id: 0x2, conformance: "M", description: "Up" }), + Field({ name: "Down", id: 0x3, conformance: "M", description: "Down" }) + ), + + Datatype( + { name: "MoveModeEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.8" } }, + Field({ name: "Stop", id: 0x0, conformance: "M", description: "Stop the movement" }), + Field({ name: "Up", id: 0x1, conformance: "M", description: "Move in an upwards direction" }), + Field({ name: "Down", id: 0x3, conformance: "M", description: "Move in a downwards direction" }) + ), + + Datatype( + { name: "StepModeEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.9" } }, + Field({ name: "Up", id: 0x1, conformance: "M", description: "Step in an upwards direction" }), + Field({ name: "Down", id: 0x3, conformance: "M", description: "Step in a downwards direction" }) + ), + + Datatype( + { name: "ColorLoopActionEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.10" } }, + Field({ name: "Deactivate", id: 0x0, conformance: "M", description: "De-activate the color loop." }), + Field({ + name: "ActivateFromColorLoopStartEnhancedHue", id: 0x1, conformance: "M", + description: "Activate the color loop from the value in the ColorLoopStartEnhancedHue field." + }), + Field({ + name: "ActivateFromEnhancedCurrentHue", id: 0x2, conformance: "M", + description: "Activate the color loop from the value of the EnhancedCurrentHue attribute." + }) + ), + + Datatype( + { name: "ColorLoopDirectionEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.11" } }, + Field({ name: "Decrement", id: 0x0, conformance: "M", description: "Decrement the hue in the color loop." }), + Field({ name: "Increment", id: 0x1, conformance: "M", description: "Increment the hue in the color loop." }) + ) + ), + + Cluster( + { + name: "BallastConfiguration", id: 0x301, classification: "application", pics: "BC", + details: "This cluster is used for configuring a lighting ballast." + + "\n" + + "NOTE Support for Ballast Configuration cluster is provisional.", + xref: { document: "cluster", section: "3.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute({ + name: "PhysicalMinLevel", id: 0x0, type: "uint8", access: "R V", conformance: "M", + constraint: "1 to 254", default: 1, + details: "This attribute shall specify the minimum light output the ballast can achieve according to the " + + "dimming light curve (see Dimming Curve).", + xref: { document: "cluster", section: "3.3.6.1" } + }), + + Attribute({ + name: "PhysicalMaxLevel", id: 0x1, type: "uint8", access: "R V", conformance: "M", + constraint: "1 to 254", default: 254, + details: "This attribute shall specify the maximum light output the ballast can achieve according to the " + + "dimming light curve (see Dimming Curve).", + xref: { document: "cluster", section: "3.3.6.2" } + }), + + Attribute({ + name: "BallastStatus", id: 0x2, type: "BallastStatusBitmap", access: "R V", conformance: "O", + default: 0, + details: "This attribute shall specify the status of various aspects of the ballast or the connected lights, " + + "see BallastStatusBitmap.", + xref: { document: "cluster", section: "3.3.6.3" } + }), + + Attribute({ + name: "MinLevel", id: 0x10, type: "uint8", access: "RW VM", conformance: "M", + constraint: "physicalMinLevel to maxLevel", + default: { type: "reference", name: "PhysicalMinLevel" }, + + details: "This attribute shall specify the light output of the ballast according to the dimming light curve " + + "(see Dimming Curve) when the Level Control Cluster’s CurrentLevel attribute equals to 1 (and the " + + "On/Off Cluster’s OnOff attribute equals to TRUE)." + + "\n" + + "The value of this attribute shall be both greater than or equal to PhysicalMinLevel and less than " + + "or equal to MaxLevel. If an attempt is made to set this attribute to a level where these conditions " + + "are not met, a response shall be returned with status code set to CONSTRAINT_ERROR, and the level " + + "shall NOT be set.", + + xref: { document: "cluster", section: "3.3.6.4" } + }), + + Attribute({ + name: "MaxLevel", id: 0x11, type: "uint8", access: "RW VM", conformance: "M", + constraint: "minLevel to physicalMaxLevel", + default: { type: "reference", name: "PhysicalMaxLevel" }, + + details: "This attribute shall specify the light output of the ballast according to the dimming light curve " + + "(see Dimming Curve) when the Level Control Cluster’s CurrentLevel attribute equals to 254 (and the " + + "On/Off Cluster’s OnOff attribute equals to TRUE)." + + "\n" + + "The value of this attribute shall be both less than or equal to PhysicalMaxLevel and greater than" + + "\n" + + "or equal to MinLevel. If an attempt is made to set this attribute to a level where these conditions " + + "are not met, a response shall be returned with status code set to CONSTRAINT_ERROR, and the level " + + "shall NOT be set.", + + xref: { document: "cluster", section: "3.3.6.5" } + }), + + Attribute({ name: "PowerOnLevel", id: 0x12, conformance: "D", xref: { document: "cluster", section: "3.3.6" } }), + Attribute({ name: "PowerOnFadeTime", id: 0x13, conformance: "D", xref: { document: "cluster", section: "3.3.6" } }), + + Attribute({ + name: "IntrinsicBallastFactor", id: 0x14, type: "uint8", access: "RW VM", conformance: "O", + quality: "X", + details: "This attribute shall specify the ballast factor, as a percentage, of the ballast/lamp combination, " + + "prior to any adjustment." + + "\n" + + "A value of null indicates in invalid value.", + xref: { document: "cluster", section: "3.3.6.6" } + }), + + Attribute( + { + name: "BallastFactorAdjustment", id: 0x15, type: "uint8", access: "RW VM", conformance: "O", + constraint: "100 to ms", default: null, quality: "X", + + details: "This attribute shall specify the multiplication factor, as a percentage, to be applied to the " + + "configured light output of the lamps. A typical use for this attribute is to compensate for " + + "reduction in efficiency over the lifetime of a lamp." + + "\n" + + "The light output is given by" + + "\n" + + "actual light output = configured light output x BallastFactorAdjustment / 100%" + + "\n" + + "The range for this attribute is manufacturer dependent. If an attempt is made to set this attribute " + + "to a level that cannot be supported, a response shall be returned with status code set to " + + "CONSTRAINT_ERROR, and the level shall NOT be changed. The value of null indicates that ballast " + + "factor scaling is not in use.", + + xref: { document: "cluster", section: "3.3.6.7" } + } + ), + + Attribute({ + name: "LampQuantity", id: 0x20, type: "uint8", access: "R V", conformance: "M", + details: "This attribute shall specify the number of lamps connected to this ballast. (Note 1: this number " + + "does not take into account whether lamps are actually in their sockets or not).", + xref: { document: "cluster", section: "3.3.6.8" } + }), + + Attribute({ + name: "LampType", id: 0x30, type: "string", access: "RW VM", conformance: "O", constraint: "max 16", + default: "", + details: "This attribute shall specify the type of lamps (including their wattage) connected to the ballast.", + xref: { document: "cluster", section: "3.3.6.9" } + }), + + Attribute({ + name: "LampManufacturer", id: 0x31, type: "string", access: "RW VM", conformance: "O", + constraint: "max 16", default: "", + details: "This attribute shall specify the name of the manufacturer of the currently connected lamps.", + xref: { document: "cluster", section: "3.3.6.10" } + }), + + Attribute({ + name: "LampRatedHours", id: 0x32, type: "uint24", access: "RW VM", conformance: "O", default: null, + quality: "X", + details: "This attribute shall specify the number of hours of use the lamps are rated for by the manufacturer." + + "\n" + + "A value of null indicates an invalid or unknown time.", + xref: { document: "cluster", section: "3.3.6.11" } + }), + + Attribute({ + name: "LampBurnHours", id: 0x33, type: "uint24", access: "RW VM", conformance: "O", default: 0, + quality: "X", + + details: "This attribute shall specify the length of time, in hours, the currently connected lamps have been " + + "operated, cumulative since the last re-lamping. Burn hours shall NOT be accumulated if the lamps " + + "are off." + + "\n" + + "This attribute SHOULD be reset to zero (e.g., remotely) when the lamps are changed. If partially " + + "used lamps are connected, LampBurnHours SHOULD be updated to reflect the burn hours of the lamps." + + "\n" + + "A value of null indicates an invalid or unknown time.", + + xref: { document: "cluster", section: "3.3.6.12" } + }), + + Attribute({ + name: "LampAlarmMode", id: 0x34, type: "LampAlarmModeBitmap", access: "RW VM", conformance: "O", + default: 0, + details: "This attribute shall specify which attributes may cause an alarm notification to be generated. Ain " + + "each bit position means that its associated attribute is able to generate an alarm." + + "\n" + + "NOTE All alarms are also logged in the alarm table – see Alarms cluster.", + xref: { document: "cluster", section: "3.3.6.13" } + }), + + Attribute({ + name: "LampBurnHoursTripPoint", id: 0x35, type: "uint24", access: "RW VM", conformance: "O", + default: null, quality: "X", + + details: "This attribute shall specify the number of hours the LampBurnHours attribute may reach before an " + + "alarm is generated." + + "\n" + + "If the Alarms cluster is not present on the same device this attribute is not used and thus may be " + + "omitted (see Dependencies)." + + "\n" + + "The Alarm Code field included in the generated alarm shall be 0x01." + + "\n" + + "If this attribute has the value of null, then this alarm shall NOT be generated.", + + xref: { document: "cluster", section: "3.3.6.14" } + }), + + Datatype( + { name: "BallastStatusBitmap", type: "map8", xref: { document: "cluster", section: "3.3.5.1" } }, + + Field( + { + name: "BallastNonOperational", constraint: "0", description: "Operational state of the ballast.", + details: "This bit shall indicate whether the ballast is operational." + + "\n" + + " • 0 = The ballast is fully operational" + + "\n" + + " • 1 = The ballast is not fully operational", + xref: { document: "cluster", section: "3.3.5.1.1" } + } + ), + + Field( + { + name: "LampFailure", constraint: "1", description: "Operational state of the lamps.", + details: "This bit shall indicate whether all lamps is operational." + + "\n" + + " • 0 = All lamps are operational" + + "\n" + + " • 1 = One or more lamp is not in its socket or is faulty", + xref: { document: "cluster", section: "3.3.5.1.2" } + } + ) + ), + + Datatype( + { name: "LampAlarmModeBitmap", type: "map8", xref: { document: "cluster", section: "3.3.5.2" } }, + Field({ + name: "LampBurnHours", constraint: "0", description: "State of LampBurnHours alarm generation", + details: "This bit shall indicate that the LampBurnHours attribute may generate an alarm.", + xref: { document: "cluster", section: "3.3.5.2.1" } + }) + ) + ), + + Cluster( + { + name: "PumpConfigurationAndControl", id: 0x200, classification: "application", pics: "PCC", + + details: "The Pump Configuration and Control cluster provides an interface for the setup and control of pump " + + "devices, and the automatic reporting of pump status information. Note that control of pump speed is " + + "not included – speed is controlled by the On/Off and Level Control clusters." + + "\n" + + "### Pump controller Pump" + + "\n" + + "C Pump configuration and control S C Level control S" + + "\n" + + "C On/Off S" + + "\n" + + "C = Client S = Server" + + "\n" + + "Note: Device names are examples for illustration purposes only" + + "\n" + + "Figure 14. Typical Usage of Pump Configuration and Control Cluster", + + xref: { document: "cluster", section: "4.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "4.2.4" } }, + Field({ + name: "PRSCONST", conformance: "O.a+", constraint: "0", description: "ConstantPressure", + details: "Supports operating in constant pressure mode" + }), + Field({ + name: "PRSCOMP", conformance: "O.a+", constraint: "1", description: "CompensatedPressure", + details: "Supports operating in compensated pressure mode" + }), + Field({ + name: "FLW", conformance: "O.a+", constraint: "2", description: "ConstantFlow", + details: "Supports operating in constant flow mode" + }), + Field({ + name: "SPD", conformance: "O.a+", constraint: "3", description: "ConstantSpeed", + details: "Supports operating in constant speed mode" + }), + Field({ + name: "TEMP", conformance: "O.a+", constraint: "4", description: "ConstantTemperature", + details: "Supports operating in constant temperature mode" + }), + Field({ + name: "AUTO", conformance: "O", constraint: "5", description: "Automatic", + details: "Supports operating in automatic mode" + }), + Field({ + name: "LOCAL", conformance: "O", constraint: "6", description: "LocalOperation", + details: "Supports operating using local settings" + }) + ), + + Attribute({ + name: "MaxPressure", id: 0x0, type: "int16", access: "R V", conformance: "M", default: null, + quality: "X F", + details: "This attribute specifies the maximum pressure the pump can achieve. It is a physical limit, and " + + "does not apply to any specific control mode or operation mode." + + "\n" + + "Valid range is -3,276.7 kPa to 3,276.7 kPa (steps of 0.1 kPa). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.1" } + }), + + Attribute({ + name: "MaxSpeed", id: 0x1, type: "uint16", access: "R V", conformance: "M", default: null, + quality: "X F", + details: "This attribute specifies the maximum speed the pump can achieve. It is a physical limit, and does " + + "not apply to any specific control mode or operation mode." + + "\n" + + "Valid range is 0 to 65,534 RPM (steps of 1 RPM). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.2" } + }), + + Attribute({ + name: "MaxFlow", id: 0x2, type: "uint16", access: "R V", conformance: "M", default: null, + quality: "X F", + details: "This attribute specifies the maximum flow the pump can achieve. It is a physical limit, and does " + + "not apply to any specific control mode or operation mode." + + "\n" + + "Valid range is 0 m/h to 6,553.4 m/h (steps of 0.1 m/h). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.3" } + }), + + Attribute({ + name: "MinConstPressure", id: 0x3, type: "int16", access: "R V", conformance: "PRSCONST, [AUTO]", + default: null, quality: "X F", + details: "This attribute specifies the minimum pressure the pump can achieve when it is working with the " + + "ControlMode attribute set to ConstantPressure." + + "\n" + + "Valid range is –3,276.7 kPa to 3,276.7 kPa (steps of 0.1 kPa). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.4" } + }), + + Attribute({ + name: "MaxConstPressure", id: 0x4, type: "int16", access: "R V", conformance: "PRSCONST, [AUTO]", + default: null, quality: "X F", + details: "This attribute specifies the maximum pressure the pump can achieve when it is working with the " + + "ControlMode attribute set to ConstantPressure." + + "\n" + + "Valid range is –3,276.7 kPa to 3,276.7 kPa (steps of 0.1 kPa). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.5" } + }), + + Attribute({ + name: "MinCompPressure", id: 0x5, type: "int16", access: "R V", conformance: "PRSCOMP, [AUTO]", + default: null, quality: "X F", + details: "This attribute specifies the minimum compensated pressure the pump can achieve when it is working " + + "with the ControlMode attribute set to ProportionalPressure." + + "\n" + + "Valid range is –3,276.7 kPa to 3,276.7 kPa (steps of 0.1 kPa). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.6" } + }), + + Attribute({ + name: "MaxCompPressure", id: 0x6, type: "int16", access: "R V", conformance: "PRSCOMP, [AUTO]", + default: null, quality: "X F", + details: "This attribute specifies the maximum compensated pressure the pump can achieve when it is working " + + "with the ControlMode attribute set to ProportionalPressure." + + "\n" + + "Valid range is –3,276.7 kPa to 3,276.7 kPa (steps of 0.1 kPa). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.7" } + }), + + Attribute({ + name: "MinConstSpeed", id: 0x7, type: "uint16", access: "R V", conformance: "SPD, [AUTO]", + default: null, quality: "X F", + details: "This attribute specifies the minimum speed the pump can achieve when it is working with the Con" + + "\n" + + "trolMode attribute set to ConstantSpeed." + + "\n" + + "Valid range is 0 to 65,534 RPM (steps of 1 RPM). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.8" } + }), + + Attribute({ + name: "MaxConstSpeed", id: 0x8, type: "uint16", access: "R V", conformance: "SPD, [AUTO]", + default: null, quality: "X F", + details: "This attribute specifies the maximum speed the pump can achieve when it is working with the " + + "ControlMode attribute set to ConstantSpeed." + + "\n" + + "Valid range is 0 to 65,534 RPM (steps of 1 RPM). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.9" } + }), + + Attribute({ + name: "MinConstFlow", id: 0x9, type: "uint16", access: "R V", conformance: "FLW, [AUTO]", + default: null, quality: "X F", + details: "This attribute specifies the minimum flow the pump can achieve when it is working with the " + + "ControlMode attribute set to ConstantFlow." + + "\n" + + "Valid range is 0 m/h to 6,553.4 m/h (steps of 0.1 m/h). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.10" } + }), + + Attribute({ + name: "MaxConstFlow", id: 0xa, type: "uint16", access: "R V", conformance: "FLW, [AUTO]", + default: null, quality: "X F", + details: "This attribute specifies the maximum flow the pump can achieve when it is working with the " + + "ControlMode attribute set to ConstantFlow." + + "\n" + + "Valid range is 0 m/h to 6,553.4 m/h (steps of 0.1 m/h). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.11" } + }), + + Attribute({ + name: "MinConstTemp", id: 0xb, type: "int16", access: "R V", conformance: "TEMP, [AUTO]", + constraint: "min -27315", default: null, quality: "X F", + details: "This attribute specifies the minimum temperature the pump can maintain in the system when it is " + + "working with the ControlMode attribute set to ConstantTemperature." + + "\n" + + "Valid range is –273.15 °C to 327.67 °C (steps of 0.01 °C). Null if the value is invalid.", + xref: { document: "cluster", section: "4.2.7.12" } + }), + + Attribute({ + name: "MaxConstTemp", id: 0xc, type: "int16", access: "R V", conformance: "TEMP, [AUTO]", + constraint: "min -27315", default: null, quality: "X F", + + details: "This attribute specifies the maximum temperature the pump can maintain in the system when it is " + + "working with the ControlMode attribute set to ConstantTemperature." + + "\n" + + "MaxConstTemp shall be greater than or equal to MinConstTemp" + + "\n" + + "Valid range is –273.15 °C to 327.67 °C (steps of 0.01 °C). Null if the value is invalid.", + + xref: { document: "cluster", section: "4.2.7.13" } + }), + + Attribute({ + name: "PumpStatus", id: 0x10, type: "PumpStatusBitmap", access: "R V", conformance: "O", + constraint: "desc", default: 0, quality: "P", + details: "This attribute specifies the activity status of the pump functions as listed in PumpStatusBitmap. " + + "Where a pump controller function is active, the corresponding bit shall be set to 1. Where a pump" + + "\n" + + "controller function is not active, the corresponding bit shall be set to 0.", + xref: { document: "cluster", section: "4.2.7.14" } + }), + + Attribute({ + name: "EffectiveOperationMode", id: 0x11, type: "OperationModeEnum", access: "R V", + conformance: "M", constraint: "desc", quality: "N", + + details: "This attribute specifies current effective operation mode of the pump as defined in " + + "OperationModeEnum." + + "\n" + + "The value of the EffectiveOperationMode attribute is the same as the OperationMode attribute, " + + "unless one of the following points are true:" + + "\n" + + " • The pump is physically set to run with the local settings" + + "\n" + + " • The LocalOverride bit in the PumpStatus attribute is set," + + "\n" + + "See OperationMode and ControlMode attributes for a detailed description of the operation and " + + "control of the pump.", + + xref: { document: "cluster", section: "4.2.7.15" } + }), + + Attribute({ + name: "EffectiveControlMode", id: 0x12, type: "ControlModeEnum", access: "R V", conformance: "M", + constraint: "desc", quality: "N", + + details: "This attribute specifies the current effective control mode of the pump as defined in " + + "ControlModeEnum." + + "\n" + + "This attribute contains the control mode that currently applies to the pump. It will have the value " + + "of the ControlMode attribute, unless one of the following points are true:" + + "\n" + + " • The ControlMode attribute is set to Automatic. In this case, the value of the " + + " EffectiveControlMode shall match the behavior of the pump." + + "\n" + + " • A remote sensor is used as the sensor for regulation of the pump. In this case, " + + " EffectiveControlMode will display ConstantPressure, ConstantFlow or ConstantTemperature if the " + + " remote sensor is a pressure sensor, a flow sensor or a temperature sensor respectively, " + + " regardless of the value of the ControlMode attribute." + + "\n" + + "In case the ControlMode attribute is not included on the device and no remote sensors are " + + "connected, the value of the EffectiveControlMode shall match the vendor-specific behavior of the " + + "pump." + + "\n" + + "See OperationMode and ControlMode attributes for detailed a description of the operation and " + + "control of the pump.", + + xref: { document: "cluster", section: "4.2.7.16" } + }), + + Attribute({ + name: "Capacity", id: 0x13, type: "int16", access: "R V", conformance: "M", default: null, + quality: "X P", + + details: "This attribute specifies the actual capacity of the pump as a percentage of the effective maximum " + + "setpoint value. It is updated dynamically as the speed of the pump changes." + + "\n" + + "If the value is not available (the measurement or estimation of the speed is done in the pump), " + + "this attribute will indicate the null value." + + "\n" + + "Valid range is 0 % to 163.835% (0.005 % granularity). Although this attribute is a signed value, " + + "values of capacity less than zero have no physical meaning.", + + xref: { document: "cluster", section: "4.2.7.17" } + }), + + Attribute({ + name: "Speed", id: 0x14, type: "uint16", access: "R V", conformance: "O", default: null, + quality: "X", + + details: "This attribute specifies the actual speed of the pump measured in RPM. It is updated dynamically as " + + "the speed of the pump changes." + + "\n" + + "If the value is not available (the measurement or estimation of the speed is done in the pump), " + + "this attribute will indicate the null value." + + "\n" + + "Valid range is 0 to 65,534 RPM.", + + xref: { document: "cluster", section: "4.2.7.18" } + }), + + Attribute({ + name: "LifetimeRunningHours", id: 0x15, type: "uint24", access: "RW VM", conformance: "O", + default: 0, quality: "X N", + + details: "This attribute specifies the accumulated number of hours that the pump has been powered and the " + + "motor has been running. It is updated dynamically as it increases. It is preserved over power " + + "cycles of the pump. If LifeTimeRunningHours rises above maximum value it “rolls over” and starts at " + + "0 (zero)." + + "\n" + + "This attribute is writeable, in order to allow setting to an appropriate value after maintenance. " + + "If the value is not available, this attribute will indicate the null value." + + "\n" + + "Valid range is 0 to 16,777,214 hrs.", + + xref: { document: "cluster", section: "4.2.7.19" } + }), + + Attribute({ + name: "Power", id: 0x16, type: "uint24", access: "R V", conformance: "O", default: null, + quality: "X", + + details: "This attribute specifies the actual power consumption of the pump in Watts. The value of this " + + "attribute is updated dynamically as the power consumption of the pump changes." + + "\n" + + "This attribute is read only. If the value is not available (the measurement of power consumption is " + + "not done in the pump), this attribute will indicate the null value." + + "\n" + + "Valid range is 0 to 16,777,214 Watts.", + + xref: { document: "cluster", section: "4.2.7.20" } + }), + + Attribute({ + name: "LifetimeEnergyConsumed", id: 0x17, type: "uint32", access: "RW VM", conformance: "O", + default: 0, quality: "X N", + + details: "This attribute specifies the accumulated energy consumption of the pump through the entire lifetime " + + "of the pump in kWh. The value of the LifetimeEnergyConsumed attribute is updated dynamically as the " + + "energy consumption of the pump increases. If LifetimeEnergyConsumed rises above maximum value it " + + "“rolls over” and starts at 0 (zero)." + + "\n" + + "This attribute is writeable, in order to allow setting to an appropriate value after maintenance." + + "\n" + + "Valid range is 0 kWh to 4,294,967,294 kWh." + + "\n" + + "Null if the value is unknown.", + + xref: { document: "cluster", section: "4.2.7.21" } + }), + + Attribute({ + name: "OperationMode", id: 0x20, type: "OperationModeEnum", access: "RW VM", conformance: "M", + constraint: "desc", default: 0, quality: "N", + + details: "This attribute specifies the operation mode of the pump as defined in OperationModeEnum." + + "\n" + + "The actual operating mode of the pump is a result of the setting of the attributes OperationMode, " + + "ControlMode and the optional connection of a remote sensor. The operation and control is " + + "prioritized as shown in the scheme below:" + + "\n" + + "Priority Scheme of Pump Operation and Control" + + "\n" + + "If this attribute is Maximum, Minimum or Local, the OperationMode attribute decides how the pump is " + + "operated." + + "\n" + + "If this attribute is Normal and a remote sensor is connected to the pump, the type of the remote " + + "sensor decides the control mode of the pump. A connected remote pressure sensor will make the pump " + + "run in control mode Constant pressure and vice versa for flow and temperature type sensors. This is " + + "regardless of the setting of the ControlMode attribute." + + "\n" + + "If this attribute is Normal and no remote sensor is connected, the control mode of the pump is " + + "decided by the ControlMode attribute." + + "\n" + + "OperationMode may be changed at any time, even when the pump is running. The behavior of the pump " + + "at the point of changing the value of this attribute is vendor-specific." + + "\n" + + "In the case a device does not support a specific operation mode, the write interaction to this " + + "attribute with an unsupported operation mode value shall be ignored and a response containing the " + + "status of CONSTRAINT_ERROR shall be returned.", + + xref: { document: "cluster", section: "4.2.7.22" } + }), + + Attribute({ + name: "ControlMode", id: 0x21, type: "ControlModeEnum", access: "RW VM", conformance: "O", + constraint: "desc", default: 0, quality: "N", + + details: "This attribute specifies the control mode of the pump as defined in ControlModeEnum." + + "\n" + + "See the OperationMode attribute for a detailed description of the operation and control of the pump." + + "\n" + + "ControlMode may be changed at any time, even when the pump is running. The behavior of the pump at " + + "the point of changing is vendor-specific." + + "\n" + + "In the case a device does not support a specific control mode, the write interaction to this " + + "attribute with an unsupported control mode value shall be ignored and a response containing the " + + "status of CONSTRAINT_ERROR shall be returned.", + + xref: { document: "cluster", section: "4.2.7.23" } + }), + + Attribute({ name: "AlarmMask", id: 0x22, conformance: "D", xref: { document: "cluster", section: "4.2.7" } }), + Event({ + name: "SupplyVoltageLow", id: 0x0, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "SupplyVoltageHigh", id: 0x1, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "PowerMissingPhase", id: 0x2, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "SystemPressureLow", id: 0x3, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "SystemPressureHigh", id: 0x4, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "DryRunning", id: 0x5, access: "V", conformance: "O", priority: "critical", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "MotorTemperatureHigh", id: 0x6, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "PumpMotorFatalFailure", id: 0x7, access: "V", conformance: "O", priority: "critical", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "ElectronicTemperatureHigh", id: 0x8, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "PumpBlocked", id: 0x9, access: "V", conformance: "O", priority: "critical", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "SensorFailure", id: 0xa, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "ElectronicNonFatalFailure", id: 0xb, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "ElectronicFatalFailure", id: 0xc, access: "V", conformance: "O", priority: "critical", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "GeneralFault", id: 0xd, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "Leakage", id: 0xe, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "AirDetection", id: 0xf, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + Event({ + name: "TurbineOperation", id: 0x10, access: "V", conformance: "O", priority: "info", + xref: { document: "cluster", section: "4.2.8" } + }), + + Datatype( + { name: "PumpStatusBitmap", type: "map16", xref: { document: "cluster", section: "4.2.6.1" } }, + + Field({ + name: "DeviceFault", constraint: "0", + description: "A fault related to the system or pump device is detected.", + details: "If this bit is set, it may correspond to an event in the range 2-16, see Events.", + xref: { document: "cluster", section: "4.2.6.1.1" } + }), + + Field({ + name: "SupplyFault", constraint: "1", + description: "A fault related to the supply to the pump is detected.", + details: "If this bit is set, it may correspond to an event in the range 0-1 or 13, see Events.", + xref: { document: "cluster", section: "4.2.6.1.2" } + }), + + Field({ name: "SpeedLow", constraint: "2", description: "Setpoint is too low to achieve." }), + Field({ name: "SpeedHigh", constraint: "3", description: "Setpoint is too high to achieve." }), + + Field({ + name: "LocalOverride", constraint: "4", + description: "Device control is overridden by hardware, such as an external STOP button or via a local HMI.", + details: "While this bit is set, the EffectiveOperationMode is adjusted to Local. Any request changing " + + "OperationMode shall generate a FAILURE error status until LocalOverride is cleared on the physical " + + "device. When LocalOverride is cleared, the device shall return to the operation mode set in " + + "OperationMode.", + xref: { document: "cluster", section: "4.2.6.1.3" } + }), + + Field({ name: "Running", constraint: "5", description: "Pump is currently running" }), + + Field({ + name: "RemotePressure", constraint: "6", + description: "A remote pressure sensor is used as the sensor for the regulation of the pump.", + details: "If this bit is set, EffectiveControlMode is ConstantPressure and the setpoint for the pump is " + + "interpreted as a percentage of the range of the remote sensor ([MinMeasuredValue – " + + "MaxMeasuredValue]).", + xref: { document: "cluster", section: "4.2.6.1.4" } + }), + + Field({ + name: "RemoteFlow", constraint: "7", + description: "A remote flow sensor is used as the sensor for the regulation of the pump.", + details: "If this bit is set, EffectiveControlMode is ConstantFlow, and the setpoint for the pump is " + + "interpreted as a percentage of the range of the remote sensor ([MinMeasuredValue – " + + "MaxMeasuredValue]).", + xref: { document: "cluster", section: "4.2.6.1.5" } + }), + + Field({ + name: "RemoteTemperature", constraint: "8", + description: "A remote temperature sensor is used as the sensor for the regulation of the pump.", + details: "If this bit is set, EffectiveControlMode is ConstantTemperature, and the setpoint for the pump is " + + "interpreted as a percentage of the range of the remote sensor ([MinMeasuredValue – " + + "MaxMeasuredValue])", + xref: { document: "cluster", section: "4.2.6.1.6" } + }) + ), + + Datatype( + { name: "OperationModeEnum", type: "enum8", xref: { document: "cluster", section: "4.2.6.2" } }, + + Field({ + name: "Normal", id: 0x0, conformance: "M", + description: "The pump is controlled by a setpoint, as defined by a connected remote sensor or by the ControlMode attribute.", + details: "If the pump is running in this operation mode the setpoint is an internal variable which may be " + + "controlled between 0% and 100%, e.g., by means of the Level Control cluster", + xref: { document: "cluster", section: "4.2.6.2.1" } + }), + + Field({ + name: "Minimum", id: 0x1, conformance: "SPD", + description: "This value sets the pump to run at the minimum possible speed it can without being stopped." + }), + Field({ + name: "Maximum", id: 0x2, conformance: "SPD", + description: "This value sets the pump to run at its maximum possible speed." + }), + Field({ + name: "Local", id: 0x3, conformance: "LOCAL", + description: "This value sets the pump to run with the local settings of the pump, regardless of what these are." + }) + ), + + Datatype( + { name: "ControlModeEnum", type: "enum8", xref: { document: "cluster", section: "4.2.6.3" } }, + + Field({ + name: "ConstantSpeed", id: 0x0, conformance: "SPD", + description: "The pump is running at a constant speed.", + details: "The setpoint is interpreted as a percentage of the range derived from the [MinConstSpeed – " + + "MaxConstSpeed] attributes.", + xref: { document: "cluster", section: "4.2.6.3.1" } + }), + + Field({ + name: "ConstantPressure", id: 0x1, conformance: "PRSCONST", + description: "The pump will regulate its speed to maintain a constant differential pressure over its flanges.", + details: "The setpoint is interpreted as a percentage of the range of the sensor used for this control mode. " + + "In case of the internal pressure sensor, this will be the range derived from the [MinConstPressure " + + "– MaxConstPressure] attributes. In case of a remote pressure sensor, this will be the range derived " + + "from the [MinMeasuredValue – MaxMeasuredValue] attributes of the remote pressure sensor.", + xref: { document: "cluster", section: "4.2.6.3.2" } + }), + + Field({ + name: "ProportionalPressure", id: 0x2, conformance: "PRSCOMP", + description: "The pump will regulate its speed to maintain a constant differential pressure over its flanges.", + details: "The setpoint is interpreted as a percentage of the range derived of the [MinCompPressure – Max" + + "\n" + + "CompPressure] attributes. The internal setpoint will be lowered (compensated) dependent on the flow " + + "in the pump (lower flow ⇒ lower internal setpoint).", + xref: { document: "cluster", section: "4.2.6.3.3" } + }), + + Field({ + name: "ConstantFlow", id: 0x3, conformance: "FLW", + description: "The pump will regulate its speed to maintain a constant flow through the pump.", + details: "The setpoint is interpreted as a percentage of the range of the sensor used for this control mode. " + + "In case of the internal flow sensor, this will be the range derived from the [MinConstFlow – " + + "MaxConstFlow] attributes. In case of a remote flow sensor, this will be the range derived from the " + + "[MinMeasuredValue – MaxMeasuredValue] attributes of the remote flow sensor.", + xref: { document: "cluster", section: "4.2.6.3.4" } + }), + + Field({ + name: "ConstantTemperature", id: 0x5, conformance: "TEMP", + description: "The pump will regulate its speed to maintain a constant temperature.", + details: "The setpoint is interpreted as a percentage of the range of the sensor used for this control mode. " + + "In case of the internal temperature sensor, this will be the range derived from the [MinConstTemp – " + + "MaxConstTemp] attributes. In case of a remote temperature sensor, this will be the range derived " + + "from the [MinMeasuredValue – MaxMeasuredValue] attributes of the remote temperature sensor.", + xref: { document: "cluster", section: "4.2.6.3.5" } + }), + + Field({ + name: "Automatic", id: 0x7, conformance: "AUTO", + description: "The operation of the pump is automatically optimized to provide the most suitable performance with respect to comfort and energy savings.", + details: "This behavior is manufacturer defined. The pump can be stopped by setting the setpoint of the level " + + "control cluster to 0, or by using the On/Off cluster. If the pump is started (at any setpoint), the " + + "speed of the pump is entirely determined by the pump.", + xref: { document: "cluster", section: "4.2.6.3.6" } + }) + ) + ), + + Cluster( + { + name: "Thermostat", id: 0x201, classification: "application", pics: "TSTAT", + + details: "This cluster provides an interface to the functionality of a thermostat." + + "\n" + + "Optional temperature, humidity and occupancy sensors" + + "\n" + + "Thermostat" + + "\n" + + "Heating / cooling control panel" + + "\n" + + "C" + + "\n" + + "Dehumidification configuration" + + "\n" + + "Dehumidification notification" + + "\n" + + "ThermostatS" + + "\n" + + "Heating / cooling device (e.g. indoor air handler)" + + "\n" + + "S" + + "\n" + + "user interface S" + + "\n" + + "configuration" + + "\n" + + "C" + + "\n" + + "Configuration tool" + + "\n" + + "Thermostat configuration" + + "\n" + + "C C Fan control S" + + "\n" + + "ThermostatS notification C" + + "\n" + + "C = Client S = Server" + + "\n" + + "Note: Device names are examples for illustration purposes only" + + "\n" + + "Figure 15. Example Usage of the Thermostat and Related Clusters\"", + + xref: { document: "cluster", section: "4.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 8 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "4.3.4" } }, + Field({ + name: "HEAT", conformance: "AUTO, O.a+", constraint: "0", description: "Heating", + details: "Thermostat is capable of managing a heating device" + }), + Field({ + name: "COOL", conformance: "AUTO, O.a+", constraint: "1", description: "Cooling", + details: "Thermostat is capable of managing a cooling device" + }), + Field({ + name: "OCC", conformance: "O", constraint: "2", description: "Occupancy", + details: "Supports Occupied and Unoccupied setpoints" + }), + Field({ + name: "SCH", conformance: "O", constraint: "3", description: "ScheduleConfiguration", + details: "Supports remote configuration of a weekly schedule of setpoint transitions" + }), + Field({ + name: "SB", conformance: "O", constraint: "4", description: "Setback", + details: "Supports configurable setback (or span)" + }), + Field({ + name: "AUTO", conformance: "O", constraint: "5", description: "AutoMode", + details: "Supports a System Mode of Auto" + }), + + Field({ + name: "LTNE", conformance: "O", constraint: "6", description: "LocalTemperatureNotExposed", + details: "This feature indicates that the Calculated Local Temperature used internally is unavailable to " + + "report externally, for example due to the temperature control being done by a separate subsystem " + + "which does not offer a view into the currently measured temperature, but allows setpoints to be " + + "provided.", + xref: { document: "cluster", section: "4.3.4.1" } + }), + + Field({ + name: "MSCH", conformance: "O", constraint: "7", description: "MatterScheduleConfiguration", + details: "Supports enhanced schedules" + }), + Field({ + name: "PRES", conformance: "O", constraint: "8", description: "Presets", + details: "Thermostat supports setpoint presets" + }) + ), + + Attribute({ + name: "LocalTemperature", id: 0x0, type: "temperature", access: "R V", conformance: "M", + default: null, quality: "X P", + + details: "Indicates the current Calculated Local Temperature, when available." + + "\n" + + " • If the LTNE feature is not supported:" + + "\n" + + " ◦ If the LocalTemperatureCalibration is invalid or currently unavailable, the attribute shall " + + " report null." + + "\n" + + " ◦ If the LocalTemperatureCalibration is valid, the attribute shall report that value." + + "\n" + + " • Otherwise, if the LTNE feature is supported, there is no feedback externally available for the " + + " LocalTemperatureCalibration. In that case, the LocalTemperature attribute shall always report " + + " null.", + + xref: { document: "cluster", section: "4.3.9.2" } + }), + + Attribute({ + name: "OutdoorTemperature", id: 0x1, type: "temperature", access: "R V", conformance: "O", + default: null, quality: "X", + details: "Indicates the outdoor temperature, as measured locally or remotely (over the network).", + xref: { document: "cluster", section: "4.3.9.3" } + }), + + Attribute({ + name: "Occupancy", id: 0x2, type: "OccupancyBitmap", access: "R V", conformance: "OCC", default: 1, + details: "Indicates whether the heated/cooled space is occupied or not, as measured locally or remotely (over " + + "the network).", + xref: { document: "cluster", section: "4.3.9.4" } + }), + + Attribute({ + name: "AbsMinHeatSetpointLimit", id: 0x3, type: "temperature", access: "R V", conformance: "[HEAT]", + constraint: "desc", default: { type: "celsius", value: 7 }, quality: "F", + details: "Indicates the absolute minimum level that the heating setpoint may be set to. This is a limitation " + + "imposed by the manufacturer." + + "\n" + + "Refer to Setpoint Limits for constraints", + xref: { document: "cluster", section: "4.3.9.5" } + }), + + Attribute({ + name: "AbsMaxHeatSetpointLimit", id: 0x4, type: "temperature", access: "R V", conformance: "[HEAT]", + constraint: "desc", default: { type: "celsius", value: 30 }, quality: "F", + xref: { document: "cluster", section: "4.3.9" } + }), + Attribute({ + name: "AbsMinCoolSetpointLimit", id: 0x5, type: "temperature", access: "R V", conformance: "[COOL]", + constraint: "desc", default: { type: "celsius", value: 16 }, quality: "F", + xref: { document: "cluster", section: "4.3.9" } + }), + + Attribute({ + name: "AbsMaxCoolSetpointLimit", id: 0x6, type: "temperature", access: "R V", conformance: "[COOL]", + constraint: "desc", default: { type: "celsius", value: 32 }, quality: "F", + details: "Indicates the absolute maximum level that the cooling setpoint may be set to. This is a limitation " + + "imposed by the manufacturer." + + "\n" + + "Refer to Setpoint Limits for constraints", + xref: { document: "cluster", section: "4.3.9.8" } + }), + + Attribute({ + name: "PiCoolingDemand", id: 0x7, type: "uint8", access: "R V", conformance: "[COOL]", + constraint: "0% to 100%", quality: "P", + details: "Indicates the level of cooling demanded by the PI (proportional integral) control loop in use by " + + "the thermostat (if any), in percent. This value is 0 when the thermostat is in “off” or “heating” " + + "mode." + + "\n" + + "This attribute is reported regularly and may be used to control a cooling device.", + xref: { document: "cluster", section: "4.3.9.9" } + }), + + Attribute({ + name: "PiHeatingDemand", id: 0x8, type: "uint8", access: "R V", conformance: "[HEAT]", + constraint: "0% to 100%", quality: "P", + details: "Indicates the level of heating demanded by the PI loop in percent. This value is 0 when the " + + "thermostat is in “off” or “cooling” mode." + + "\n" + + "This attribute is reported regularly and may be used to control a heating device.", + xref: { document: "cluster", section: "4.3.9.10" } + }), + + Attribute({ + name: "HvacSystemTypeConfiguration", id: 0x9, type: "HVACSystemTypeBitmap", access: "R[W] VM", + conformance: "D", constraint: "desc", default: 0, quality: "N", + details: "Indicates the HVAC system type controlled by the thermostat. If the thermostat uses physical DIP " + + "switches to set these parameters, this information shall be available read-only" + + "\n" + + "from the DIP switches. If these parameters are set via software, there shall be read/write access " + + "in order to provide remote programming capability.", + xref: { document: "cluster", section: "4.3.9.11" } + }), + + Attribute({ + name: "LocalTemperatureCalibration", id: 0x10, type: "SignedTemperature", access: "RW VM", + conformance: "[!LTNE]", default: { type: "celsius", value: 0 }, quality: "N", + + details: "Indicates the offset the Thermostat server shall make to the measured temperature (locally or " + + "remotely) to adjust the Calculated Local Temperature prior to using, displaying or reporting it." + + "\n" + + "The purpose of this attribute is to adjust the calibration of the Thermostat server per the user’s " + + "preferences (e.g., to match if there are multiple servers displaying different values for the same " + + "HVAC area) or compensate for variability amongst temperature sensors." + + "\n" + + "If a Thermostat client attempts to write LocalTemperatureCalibration attribute to an unsupported " + + "value (e.g., out of the range supported by the Thermostat server), the Thermostat server shall " + + "respond with a status of SUCCESS and set the value of LocalTemperatureCalibration to the upper or " + + "lower limit reached." + + "\n" + + "NOTE" + + "\n" + + "Prior to revision 8 of this cluster specification the value of this attribute was constrained to a " + + "range of -2.5°C to 2.5°C.", + + xref: { document: "cluster", section: "4.3.9.12" } + }), + + Attribute({ + name: "OccupiedCoolingSetpoint", id: 0x11, type: "temperature", access: "RW VO", + conformance: "COOL", constraint: "desc", default: { type: "celsius", value: 26 }, quality: "N", + + details: "Indicates the cooling mode setpoint when the room is occupied. Refer to Setpoint Limits for " + + "constraints." + + "\n" + + "If an attempt is made to set this attribute to a value greater than MaxCoolSetpointLimit or less " + + "than MinCoolSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If this attribute is set to a value that is less than (OccupiedHeatingSetpoint + " + + "MinSetpointDeadBand), the value of OccupiedHeatingSetpoint shall be adjusted to " + + "(OccupiedCoolingSetpoint - MinSetpointDeadBand)." + + "\n" + + "If the occupancy status of the room is unknown, this attribute shall be used as the cooling mode " + + "setpoint." + + "\n" + + "If a client changes the value of this attribute, the server supports the PRES feature, and the " + + "server either does not support the OCC feature or the Occupied bit is set on the Occupancy " + + "attribute, the value of the ActivePresetHandle attribute shall be set to null.", + + xref: { document: "cluster", section: "4.3.9.13" } + }), + + Attribute({ + name: "OccupiedHeatingSetpoint", id: 0x12, type: "temperature", access: "RW VO", + conformance: "HEAT", constraint: "desc", default: { type: "celsius", value: 20 }, quality: "N", + + details: "Indicates the heating mode setpoint when the room is occupied. Refer to Setpoint Limits for " + + "constraints." + + "\n" + + "If an attempt is made to set this attribute to a value greater than MaxHeatSetpointLimit or less " + + "than MinHeatSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If this attribute is set to a value that is greater than" + + "\n" + + "Band), the value of OccupiedCoolingSetpoint shall be adjusted to (OccupiedHeatingSetpoint + " + + "MinSetpointDeadBand)." + + "\n" + + "If the occupancy status of the room is unknown, this attribute shall be used as the heating mode " + + "setpoint." + + "\n" + + "If a client changes the value of this attribute, the server supports the PRES feature, and the " + + "server either does not support the OCC feature or the Occupied bit is set on the Occupancy " + + "attribute, the value of the ActivePresetHandle attribute shall be set to null.", + + xref: { document: "cluster", section: "4.3.9.14" } + }), + + Attribute({ + name: "UnoccupiedCoolingSetpoint", id: 0x13, type: "temperature", access: "RW VO", + conformance: "COOL & OCC", constraint: "desc", default: { type: "celsius", value: 26 }, + quality: "N", + + details: "Indicates the cooling mode setpoint when the room is unoccupied. Refer to Setpoint Limits for " + + "constraints." + + "\n" + + "If an attempt is made to set this attribute to a value greater than MaxCoolSetpointLimit or less " + + "than MinCoolSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If this attribute is set to a value that is less than (UnoccupiedHeatingSetpoint + " + + "MinSetpointDeadBand), the value of UnoccupiedHeatingSetpoint shall be adjusted to " + + "(UnoccupiedCoolingSetpoint - MinSetpointDeadBand)." + + "\n" + + "If the occupancy status of the room is unknown, this attribute shall NOT be used." + + "\n" + + "If a client changes the value of this attribute, the server supports the PRES and OCC features, and " + + "the Occupied bit is not set on the Occupancy attribute, the value of the ActivePresetHandle " + + "attribute shall be set to null.", + + xref: { document: "cluster", section: "4.3.9.15" } + }), + + Attribute({ + name: "UnoccupiedHeatingSetpoint", id: 0x14, type: "temperature", access: "RW VO", + conformance: "HEAT & OCC", constraint: "desc", default: { type: "celsius", value: 20 }, + quality: "N", + + details: "Indicates the heating mode setpoint when the room is unoccupied. Refer to Setpoint Limits for " + + "constraints." + + "\n" + + "If an attempt is made to set this attribute to a value greater than MaxHeatSetpointLimit or less " + + "than MinHeatSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If this attribute is set to a value that is greater than (UnoccupiedCoolingSetpoint - " + + "MinSetpointDeadBand), the value of UnoccupiedCoolingSetpoint shall be adjusted to" + + "\n" + + "+ MinSetpointDeadBand)." + + "\n" + + "If the occupancy status of the room is unknown, this attribute shall NOT be used." + + "\n" + + "If a client changes the value of this attribute, the server supports the PRES and OCC features, and " + + "the Occupied bit is not set on the Occupancy attribute, the value of the ActivePresetHandle " + + "attribute shall be set to null.", + + xref: { document: "cluster", section: "4.3.9.16" } + }), + + Attribute({ + name: "MinHeatSetpointLimit", id: 0x15, type: "temperature", access: "RW VM", conformance: "[HEAT]", + constraint: "desc", default: { type: "reference", name: "AbsMinHeatSetpointLimit" }, quality: "N", + + details: "Indicates the minimum level that the heating setpoint may be set to." + + "\n" + + "This attribute, and the following three attributes, allow the user to define setpoint limits more " + + "constrictive than the manufacturer imposed ones. Limiting users (e.g., in a commercial building) to " + + "such setpoint limits can help conserve power." + + "\n" + + "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute to a value " + + "which conflicts with setpoint values then those setpoints shall be adjusted by the minimum amount " + + "to permit this attribute to be set to the desired value. If an attempt is made to set this " + + "attribute to a value which is not consistent with the constraints and cannot be resolved by " + + "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", + + xref: { document: "cluster", section: "4.3.9.17" } + }), + + Attribute({ + name: "MaxHeatSetpointLimit", id: 0x16, type: "temperature", access: "RW VM", conformance: "[HEAT]", + constraint: "desc", default: { type: "reference", name: "AbsMaxHeatSetpointLimit" }, quality: "N", + + details: "Indicates the maximum level that the heating setpoint may be set to." + + "\n" + + "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute to a value " + + "which conflicts with setpoint values then those setpoints shall be adjusted by the minimum amount " + + "to permit this attribute to be set to the desired value. If an attempt is made to set this " + + "attribute to a value which is not consistent with the constraints and cannot be resolved by " + + "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", + + xref: { document: "cluster", section: "4.3.9.18" } + }), + + Attribute({ + name: "MinCoolSetpointLimit", id: 0x17, type: "temperature", access: "RW VM", conformance: "[COOL]", + constraint: "desc", default: { type: "reference", name: "AbsMinCoolSetpointLimit" }, quality: "N", + + details: "Indicates the minimum level that the cooling setpoint may be set to." + + "\n" + + "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute to a value " + + "which conflicts with setpoint values then those setpoints shall be adjusted by the minimum amount " + + "to permit this attribute to be set to the desired value. If an attempt is made to set this " + + "attribute to a value which is not consistent with the constraints and cannot be resolved by " + + "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", + + xref: { document: "cluster", section: "4.3.9.19" } + }), + + Attribute({ + name: "MaxCoolSetpointLimit", id: 0x18, type: "temperature", access: "RW VM", conformance: "[COOL]", + constraint: "desc", default: { type: "reference", name: "AbsMaxCoolSetpointLimit" }, quality: "N", + + details: "Indicates the maximum level that the cooling setpoint may be set to." + + "\n" + + "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute to a value " + + "which conflicts with setpoint values then those setpoints shall be adjusted by the minimum amount " + + "to permit this attribute to be set to the desired value. If an attempt is made to set this " + + "attribute to a value which is not consistent with the constraints and cannot be resolved by " + + "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", + + xref: { document: "cluster", section: "4.3.9.20" } + }), + + Attribute({ + name: "MinSetpointDeadBand", id: 0x19, type: "SignedTemperature", access: "R[W] VM", + conformance: "AUTO", constraint: "0 to 12.7°C", default: { type: "celsius", value: 2 }, + quality: "N", + + details: "On devices which support the AUTO feature, this attribute shall indicate the minimum difference " + + "between the Heat Setpoint and the Cool Setpoint." + + "\n" + + "Refer to Setpoint Limits for constraints." + + "\n" + + "NOTE" + + "\n" + + "Prior to revision 8 of this cluster specification the value of this attribute was constrained to a " + + "range of 0°C to 2.5°C." + + "\n" + + "NOTE" + + "\n" + + "For backwards compatibility, this attribute is optionally writeable. However any writes to this " + + "attribute shall be silently ignored.", + + xref: { document: "cluster", section: "4.3.9.21" } + }), + + Attribute({ + name: "RemoteSensing", id: 0x1a, type: "RemoteSensingBitmap", access: "RW VM", conformance: "O", + default: 0, quality: "N", + + details: "Indicates when the local temperature, outdoor temperature and occupancy are being sensed by remote " + + "networked sensors, rather than internal sensors." + + "\n" + + "If the LTNE feature is present in the server, the LocalTemperature RemoteSensing bit value shall " + + "always report a value of 0." + + "\n" + + "If the LocalTemperature RemoteSensing bit is written with a value of 1 when the LTNE feature is " + + "present, the write shall fail and the server shall report a CONSTRAINT_ERROR.", + + xref: { document: "cluster", section: "4.3.9.22" } + }), + + Attribute({ + name: "ControlSequenceOfOperation", id: 0x1b, type: "ControlSequenceOfOperationEnum", + access: "RW VM", conformance: "M", constraint: "desc", default: 4, quality: "N", + + details: "Indicates the overall operating environment of the thermostat, and thus the possible system modes " + + "that the thermostat can operate in." + + "\n" + + "If an attempt is made to write to this attribute, the server shall silently ignore the write and " + + "the value of this attribute shall remain unchanged. This behavior is in place for backwards " + + "compatibility with existing thermostats.", + + xref: { document: "cluster", section: "4.3.9.23" } + }), + + Attribute({ + name: "SystemMode", id: 0x1c, type: "SystemModeEnum", access: "RW VM", conformance: "M", + constraint: "desc", default: 1, quality: "N", + details: "Indicates the current operating mode of the thermostat. Its value shall be limited by the " + + "ControlSequenceOfOperation attribute.", + xref: { document: "cluster", section: "4.3.9.24" } + }), + + Attribute({ + name: "ThermostatRunningMode", id: 0x1e, type: "ThermostatRunningModeEnum", access: "R V", + conformance: "[AUTO]", constraint: "desc", default: 0, + details: "Indicates the running mode of the thermostat. This attribute uses the same values as SystemModeEnum " + + "but can only be Off, Cool or Heat. This attribute is intended to provide additional information " + + "when the thermostat’s system mode is in auto mode.", + xref: { document: "cluster", section: "4.3.9.26" } + }), + + Attribute({ + name: "StartOfWeek", id: 0x20, type: "StartOfWeekEnum", access: "R V", conformance: "SCH", + constraint: "desc", quality: "F", + + details: "Indicates the day of the week that this thermostat considers to be the start of week for weekly " + + "setpoint scheduling." + + "\n" + + "This attribute may be able to be used as the base to determine if the device supports weekly " + + "scheduling by reading the attribute. Successful response means that the weekly scheduling is " + + "supported.", + + xref: { document: "cluster", section: "4.3.9.27" } + }), + + Attribute({ + name: "NumberOfWeeklyTransitions", id: 0x21, type: "uint8", access: "R V", conformance: "SCH", + default: 0, quality: "F", + details: "Indicates how many weekly schedule transitions the thermostat is capable of handling.", + xref: { document: "cluster", section: "4.3.9.28" } + }), + + Attribute({ + name: "NumberOfDailyTransitions", id: 0x22, type: "uint8", access: "R V", conformance: "SCH", + default: 0, quality: "F", + details: "Indicates how many daily schedule transitions the thermostat is capable of handling.", + xref: { document: "cluster", section: "4.3.9.29" } + }), + + Attribute({ + name: "TemperatureSetpointHold", id: 0x23, type: "TemperatureSetpointHoldEnum", access: "RW VM", + conformance: "O", constraint: "desc", default: 0, quality: "N", + + details: "Indicates the temperature hold status on the thermostat. If hold status is on, the thermostat " + + "SHOULD maintain the temperature setpoint for the current mode until a system mode change. If hold " + + "status is off, the thermostat SHOULD follow the setpoint transitions specified by its internal " + + "scheduling program. If the thermostat supports setpoint hold for a specific duration, it SHOULD " + + "also implement the TemperatureSetpointHoldDuration attribute." + + "\n" + + "If the server supports a setpoint hold for a specific duration, it SHOULD also implement the " + + "SetpointHoldExpiryTimestamp attribute." + + "\n" + + "If this attribute is updated to SetpointHoldOn and the TemperatureSetpointHoldDuration has a non- " + + "null value and the SetpointHoldExpiryTimestamp is supported, the server shall update the " + + "SetpointHoldExpiryTimestamp with a value of current UTC timestamp, in seconds, plus the value in " + + "TemperatureSetpointHoldDuration multiplied by 60." + + "\n" + + "If this attribute is updated to SetpointHoldOff and the SetpointHoldExpiryTimestamp is supported, " + + "the server shall set the SetpointHoldExpiryTimestamp to null.", + + xref: { document: "cluster", section: "4.3.9.30" } + }), + + Attribute({ + name: "TemperatureSetpointHoldDuration", id: 0x24, type: "uint16", access: "RW VM", + conformance: "O", constraint: "max 1440", default: null, quality: "X N", + + details: "Indicates the period in minutes for which a setpoint hold is active. Thermostats that support hold " + + "for a specified duration SHOULD implement this attribute. The null value indicates the field is " + + "unused. All other values are reserved." + + "\n" + + "If this attribute is updated to a non-null value and the TemperatureSetpointHold is set to " + + "SetpointHoldOn and the SetpointHoldExpiryTimestamp is supported, the server shall update " + + "SetpointHoldExpiryTimestamp with a value of current UTC timestamp, in seconds, plus the new value " + + "of this attribute multiplied by 60." + + "\n" + + "If this attribute is set to null and the SetpointHoldExpiryTimestamp is supported, the server shall " + + "set the SetpointHoldExpiryTimestamp to null.", + + xref: { document: "cluster", section: "4.3.9.31" } + }), + + Attribute({ + name: "ThermostatProgrammingOperationMode", id: 0x25, type: "ProgrammingOperationModeBitmap", + access: "RW VM", conformance: "O", constraint: "desc", default: 0, quality: "P", + + details: "Indicates the operational state of the thermostat’s programming. The thermostat shall modify its " + + "programming operation when this attribute is modified by a client and update this attribute when " + + "its programming operation is modified locally by a user. The thermostat may support more than one " + + "active ProgrammingOperationModeBitmap. For example, the thermostat may operate simultaneously in " + + "Schedule Programming Mode and Recovery Mode." + + "\n" + + "Thermostats which contain a schedule may use this attribute to control how that schedule is used, " + + "even if they do not support the ScheduleConfiguration feature." + + "\n" + + "When ScheduleActive is not set, the setpoint is altered only by manual up/down changes at the " + + "thermostat or remotely, not by internal schedule programming." + + "\n" + + "NOTE" + + "\n" + + "Modifying the ScheduleActive bit does not clear or delete previous weekly schedule programming " + + "configurations.", + + xref: { document: "cluster", section: "4.3.9.32" } + }), + + Attribute({ + name: "ThermostatRunningState", id: 0x29, type: "RelayStateBitmap", access: "R V", conformance: "O", + constraint: "desc", + details: "Indicates the current relay state of the heat, cool, and fan relays. Unimplemented outputs shall be " + + "treated as if they were Off.", + xref: { document: "cluster", section: "4.3.9.33" } + }), + + Attribute({ + name: "SetpointChangeSource", id: 0x30, type: "SetpointChangeSourceEnum", access: "R V", + conformance: "O", constraint: "desc", default: 0, + + details: "Indicates the source of the current active OccupiedCoolingSetpoint or OccupiedHeatingSetpoint " + + "(i.e., who or what determined the current setpoint)." + + "\n" + + "This attribute enables service providers to determine whether changes to setpoints were initiated " + + "due to occupant comfort, scheduled programming or some other source (e.g., electric utility or " + + "other service provider). Because automation services may initiate frequent setpoint changes, this " + + "attribute clearly differentiates the source of setpoint changes made at the thermostat.", + + xref: { document: "cluster", section: "4.3.9.34" } + }), + + Attribute({ + name: "SetpointChangeAmount", id: 0x31, type: "TemperatureDifference", access: "R V", + conformance: "O", default: null, quality: "X", + details: "Indicates the delta between the current active OccupiedCoolingSetpoint or OccupiedHeatingSetpoint " + + "and the previous active setpoint. This attribute is meant to accompany the SetpointChangeSource " + + "attribute; devices implementing SetpointChangeAmount SHOULD also implement SetpointChangeSource." + + "\n" + + "The null value indicates that the previous setpoint was unknown.", + xref: { document: "cluster", section: "4.3.9.35" } + }), + + Attribute({ + name: "SetpointChangeSourceTimestamp", id: 0x32, type: "epoch-s", access: "R V", conformance: "O", + default: 0, + details: "Indicates the time in UTC at which the SetpointChangeAmount attribute change was recorded.", + xref: { document: "cluster", section: "4.3.9.36" } + }), + + Attribute({ + name: "OccupiedSetback", id: 0x34, type: "UnsignedTemperature", access: "RW VM", conformance: "SB", + constraint: "occupiedSetbackMin to occupiedSetbackMax", default: null, quality: "X N", + + details: "Indicates the amount that the Thermostat server will allow the Calculated Local Temperature to " + + "float above the OccupiedCoolingSetpoint (i.e., OccupiedCoolingSetpoint + OccupiedSetback) or below " + + "the OccupiedHeatingSetpoint setpoint (i.e., OccupiedHeatingSetpoint – OccupiedSetback) before " + + "initiating a state change to bring the temperature back to the user’s desired setpoint. This " + + "attribute is sometimes also referred to as the “span.”" + + "\n" + + "The purpose of this attribute is to allow remote configuration of the span between the desired " + + "setpoint and the measured temperature to help prevent over-cycling and reduce energy bills, though " + + "this may result in lower comfort on the part of some users." + + "\n" + + "The null value indicates the attribute is unused." + + "\n" + + "If the Thermostat client attempts to write OccupiedSetback to a value greater than " + + "OccupiedSetbackMax, the Thermostat server shall set its OccupiedSetback value to OccupiedSetbackMax " + + "and shall send a Write Attribute Response command with a Status Code field enumeration of SUCCESS " + + "response." + + "\n" + + "If the Thermostat client attempts to write OccupiedSetback to a value less than OccupiedSetbackMin, " + + "the Thermostat server shall set its OccupiedSetback value to OccupiedSetbackMin and shall send a " + + "Write Attribute Response command with a Status Code field enumeration of SUCCESS response.", + + xref: { document: "cluster", section: "4.3.9.37" } + }), + + Attribute({ + name: "OccupiedSetbackMin", id: 0x35, type: "UnsignedTemperature", access: "R V", conformance: "SB", + constraint: "max occupiedSetbackMax", default: null, quality: "X F", + details: "Indicates the minimum value that the Thermostat server will allow the OccupiedSetback attribute to " + + "be configured by a user." + + "\n" + + "The null value indicates the attribute is unused.", + xref: { document: "cluster", section: "4.3.9.38" } + }), + + Attribute({ + name: "OccupiedSetbackMax", id: 0x36, type: "UnsignedTemperature", access: "R V", conformance: "SB", + constraint: "occupiedSetbackMin to 25.4°C", default: null, quality: "X F", + details: "Indicates the maximum value that the Thermostat server will allow the OccupiedSetback attribute to " + + "be configured by a user." + + "\n" + + "The null value indicates the attribute is unused.", + xref: { document: "cluster", section: "4.3.9.39" } + }), + + Attribute({ + name: "UnoccupiedSetback", id: 0x37, type: "UnsignedTemperature", access: "RW VM", + conformance: "SB & OCC", constraint: "unoccupiedSetbackMin to unoccupiedSetbackMax", default: null, + quality: "X N", + + details: "Indicates the amount that the Thermostat server will allow the Calculated Local Temperature to " + + "float above the UnoccupiedCoolingSetpoint (i.e., UnoccupiedCoolingSetpoint + UnoccupiedSetback) or " + + "below the UnoccupiedHeatingSetpoint setpoint (i.e., UnoccupiedHeatingSetpoint - UnoccupiedSetback) " + + "before initiating a state change to bring the temperature back to the user’s desired setpoint. This " + + "attribute is sometimes also referred to as the “span.”" + + "\n" + + "The purpose of this attribute is to allow remote configuration of the span between the desired " + + "setpoint and the measured temperature to help prevent over-cycling and reduce energy bills, though " + + "this may result in lower comfort on the part of some users." + + "\n" + + "The null value indicates the attribute is unused." + + "\n" + + "If the Thermostat client attempts to write UnoccupiedSetback to a value greater than " + + "UnoccupiedSetbackMax, the Thermostat server shall set its UnoccupiedSetback value to " + + "UnoccupiedSetbackMax and shall send a Write Attribute Response command with a Status Code field " + + "enumeration of SUCCESS response." + + "\n" + + "If the Thermostat client attempts to write UnoccupiedSetback to a value less than " + + "UnoccupiedSetbackMin, the Thermostat server shall set its UnoccupiedSetback value to " + + "UnoccupiedSetbackMin and shall send a Write Attribute Response command with a Status Code field " + + "enumeration of SUCCESS response.", + + xref: { document: "cluster", section: "4.3.9.40" } + }), + + Attribute({ + name: "UnoccupiedSetbackMin", id: 0x38, type: "UnsignedTemperature", access: "R V", + conformance: "SB & OCC", constraint: "max unoccupiedSetbackMax", default: null, quality: "X F", + details: "Indicates the minimum value that the Thermostat server will allow the UnoccupiedSetback attribute " + + "to be configured by a user." + + "\n" + + "The null value indicates the attribute is unused.", + xref: { document: "cluster", section: "4.3.9.41" } + }), + + Attribute({ + name: "UnoccupiedSetbackMax", id: 0x39, type: "UnsignedTemperature", access: "R V", + conformance: "SB & OCC", constraint: "unoccupiedSetbackMin to 25.4°C", default: null, + quality: "X F", + details: "Indicates the maximum value that the Thermostat server will allow the UnoccupiedSetback attribute " + + "to be configured by a user." + + "\n" + + "The null value indicates the attribute is unused.", + xref: { document: "cluster", section: "4.3.9.42" } + }), + + Attribute( + { + name: "EmergencyHeatDelta", id: 0x3a, type: "UnsignedTemperature", access: "RW VM", + conformance: "O", default: { type: "celsius", value: 25 }, quality: "N", + + details: "Indicates the delta between the Calculated Local Temperature and the OccupiedHeatingSetpoint or " + + "UnoccupiedHeatingSetpoint attributes at which the Thermostat server will operate in emergency heat " + + "mode." + + "\n" + + "If the difference between the Calculated Local Temperature and OccupiedCoolingSetpoint or " + + "UnoccupiedCoolingSetpoint is greater than or equal to the EmergencyHeatDelta and the Thermostat " + + "server’s SystemMode attribute is in a heating-related mode, then the Thermostat server shall " + + "immediately switch to the SystemMode attribute value that provides the highest stage of heating " + + "(e.g., emergency heat) and continue operating in that running state until the " + + "OccupiedHeatingSetpoint value is reached. For example:" + + "\n" + + " • Calculated Local Temperature = 10.0°C" + + "\n" + + " • OccupiedHeatingSetpoint = 16.0°C" + + "\n" + + " • EmergencyHeatDelta = 2.0°C" + + "\n" + + "⇒ OccupiedHeatingSetpoint - Calculated Local Temperature ≥? EmergencyHeatDelta" + + "\n" + + "⇒ 16°C - 10°C ≥? 2°C" + + "\n" + + "⇒ TRUE >>> Thermostat server changes its SystemMode to operate in 2nd stage or emergency heat mode" + + "\n" + + "The purpose of this attribute is to provide Thermostat clients the ability to configure rapid " + + "heating when a setpoint is of a specified amount greater than the measured temperature. This allows " + + "the heated space to be quickly heated to the desired level set by the user.", + + xref: { document: "cluster", section: "4.3.9.43" } + } + ), + + Attribute({ + name: "AcType", id: 0x40, type: "ACTypeEnum", access: "RW VM", conformance: "O", constraint: "desc", + default: 0, quality: "N", + details: "Indicates the type of Mini Split ACTypeEnum of Mini Split AC is defined depending on how Cooling " + + "and Heating condition is achieved by Mini Split AC.", + xref: { document: "cluster", section: "4.3.9.44" } + }), + + Attribute({ + name: "AcCapacity", id: 0x41, type: "uint16", access: "RW VM", conformance: "O", default: 0, + quality: "N", + details: "Indicates capacity of Mini Split AC in terms of the format defined by the ACCapacityFormat attribute", + xref: { document: "cluster", section: "4.3.9.45" } + }), + + Attribute({ + name: "AcRefrigerantType", id: 0x42, type: "ACRefrigerantTypeEnum", access: "RW VM", + conformance: "O", constraint: "desc", default: 0, quality: "N", + details: "Indicates type of refrigerant used within the Mini Split AC.", + xref: { document: "cluster", section: "4.3.9.46" } + }), + + Attribute({ + name: "AcCompressorType", id: 0x43, type: "ACCompressorTypeEnum", access: "RW VM", conformance: "O", + constraint: "desc", default: 0, quality: "N", + details: "Indicates the type of compressor used within the Mini Split AC.", + xref: { document: "cluster", section: "4.3.9.47" } + }), + + Attribute({ + name: "AcErrorCode", id: 0x44, type: "ACErrorCodeBitmap", access: "RW VM", conformance: "O", + default: 0, + details: "Indicates the type of errors encountered within the Mini Split AC.", + xref: { document: "cluster", section: "4.3.9.48" } + }), + + Attribute({ + name: "AcLouverPosition", id: 0x45, type: "ACLouverPositionEnum", access: "RW VM", conformance: "O", + constraint: "desc", default: 0, quality: "N", + details: "Indicates the position of Louver on the AC.", + xref: { document: "cluster", section: "4.3.9.49" } + }), + + Attribute({ + name: "AcCoilTemperature", id: 0x46, type: "temperature", access: "R V", conformance: "O", + default: null, quality: "X", + details: "Indicates the temperature of the AC coil, as measured locally or remotely (over the network).", + xref: { document: "cluster", section: "4.3.9.50" } + }), + + Attribute({ + name: "AcCapacityFormat", id: 0x47, type: "ACCapacityFormatEnum", access: "RW VM", conformance: "O", + constraint: "desc", default: 0, quality: "N", + details: "Indicates the format for the ACCapacity attribute.", + xref: { document: "cluster", section: "4.3.9.51" } + }), + + Attribute( + { + name: "PresetTypes", id: 0x48, type: "list", access: "R V", conformance: "PRES", constraint: "desc", + quality: "F", + details: "Indicates the supported PresetScenarioEnum values, limits on how many presets can be created for " + + "each PresetScenarioEnum, and whether or not a thermostat can transition automatically to a given " + + "scenario.", + xref: { document: "cluster", section: "4.3.9.52" } + }, + + Field({ name: "entry", type: "PresetTypeStruct" }) + ), + + Attribute( + { + name: "ScheduleTypes", id: 0x49, type: "list", access: "R V", conformance: "MSCH", + constraint: "desc", quality: "F", + details: "Indicates the supported SystemMode values for Schedules, limits on how many schedules can be " + + "created for each SystemMode value, and whether or not a given SystemMode value supports transitions " + + "to Presets, target setpoints, or both.", + xref: { document: "cluster", section: "4.3.9.53" } + }, + + Field({ name: "entry", type: "ScheduleTypeStruct" }) + ), + + Attribute({ + name: "NumberOfPresets", id: 0x4a, type: "uint8", access: "R V", conformance: "PRES", default: 0, + quality: "F", + details: "Indicates the maximum number of entries supported by the Presets attribute.", + xref: { document: "cluster", section: "4.3.9.54" } + }), + + Attribute({ + name: "NumberOfSchedules", id: 0x4b, type: "uint8", access: "R V", conformance: "MSCH", default: 0, + quality: "F", + details: "Indicates the maximum number of entries supported by the Schedules attribute.", + xref: { document: "cluster", section: "4.3.9.55" } + }), + + Attribute({ + name: "NumberOfScheduleTransitions", id: 0x4c, type: "uint8", access: "R V", conformance: "MSCH", + default: 0, quality: "F", + details: "Indicates the maximum number of transitions per Schedules attribute entry.", + xref: { document: "cluster", section: "4.3.9.56" } + }), + + Attribute({ + name: "NumberOfScheduleTransitionPerDay", id: 0x4d, type: "uint8", access: "R V", + conformance: "MSCH", default: null, quality: "X F", + xref: { document: "cluster", section: "4.3.9" } + }), + + Attribute({ + name: "ActivePresetHandle", id: 0x4e, type: "octstr", access: "R V", conformance: "PRES", + constraint: "max 16", default: null, quality: "X N", + details: "Indicates the PresetHandle of the active preset. If this attribute is null, then there is no active " + + "preset.", + xref: { document: "cluster", section: "4.3.9.58" } + }), + + Attribute({ + name: "ActiveScheduleHandle", id: 0x4f, type: "octstr", access: "R V", conformance: "MSCH", + constraint: "max 16", default: null, quality: "X N", + details: "Indicates the ScheduleHandle of the active schedule. A null value in this attribute indicates that " + + "there is no active schedule.", + xref: { document: "cluster", section: "4.3.9.59" } + }), + + Attribute( + { + name: "Presets", id: 0x50, type: "list", access: "RW VM", conformance: "PRES", + constraint: "max numberOfPresets", default: [], quality: "N T", + + details: "This attribute shall contain the current list of configured presets. On receipt of a write request:" + + "\n" + + " 1. If the PresetHandle field is null, the PresetStruct shall be treated as an added preset, and " + + " the device shall create a new unique value for the PresetHandle field." + + "\n" + + " a. If the BuiltIn field is true, a response with the status code CONSTRAINT_ERROR shall be " + + " returned." + + "\n" + + " 2. If the PresetHandle field is not null, the PresetStruct shall be treated as a modification of " + + " an existing preset." + + "\n" + + " a. If the value of the PresetHandle field does not match any of the existing presets, a " + + " response with the status code NOT_FOUND shall be returned." + + "\n" + + " b. If the value of the PresetHandle field is duplicated on multiple presets in the updated " + + " list, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " c. If the BuiltIn field is true, and the PresetStruct in the current value with a matching " + + " PresetHandle field has a BuiltIn field set to false, a response with the status code " + + " CONSTRAINT_ERROR shall be returned." + + "\n" + + " d. If the BuiltIn field is false, and the PresetStruct in the current value with a matching " + + " PresetHandle field has a BuiltIn field set to true, a response with the status code " + + " CONSTRAINT_ERROR shall be returned." + + "\n" + + " 3. If the specified PresetScenarioEnum value does not exist in PresetTypes, a response with the " + + " status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " 4. If the Name is set, but the associated PresetTypeStruct does not have the SupportsNames bit " + + " set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " 5. If appending the received PresetStruct to the pending list of Presets would cause the total " + + " number of pending presets to exceed the value of the NumberOfPresets attribute, a response " + + " with the status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " 6. If appending the received PresetStruct to the pending list of Presets would cause the total " + + " number of pending presets whose PresetScenario field matches the appended preset’s " + + " PresetScenario field to exceed the value of the NumberOfPresets field on the PresetTypeStruct " + + " whose PresetScenario matches the appended preset’s PresetScenario field, a response with the " + + " status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " 7. Otherwise, the write shall be pended until receipt of a commit request, and the status code " + + " SUCCESS shall be returned." + + "\n" + + " a. If the BuiltIn field is null:" + + "\n" + + " i. If there is a PresetStruct in the current value with a matching PresetHandle field, the " + + " BuiltIn field on the pending PresetStruct shall be set to the value of the BuiltIn on the " + + " matching PresetStruct." + + "\n" + + " ii. Otherwise, the BuiltIn field on the pending PresetStruct shall be set to false." + + "\n" + + "On an attempt to commit, the status of this attribute shall be determined as follows:" + + "\n" + + " 1. For all existing presets:" + + "\n" + + " a. If, after applying all pending changes, the updated value of the Presets attribute would not " + + " contain a PresetStruct with a matching PresetHandle field, indicating the removal of the " + + " PresetStruct, the server shall check for invalid removal of the PresetStruct:" + + "\n" + + " i. If the BuiltIn field is true on the removed PresetStruct, the attribute status shall be " + + " CONSTRAINT_ERROR." + + "\n" + + " ii. If the MSCH feature is supported and the removed PresetHandle would be referenced by any " + + " PresetHandle on any ScheduleTransitionStruct on any ScheduleStruct in the updated value " + + " of the Schedules attribute, the attribute status shall be INVALID_IN_STATE." + + "\n" + + " iii. If the removed PresetHandle is equal to the value of the ActivePresetHandle attribute, " + + " the attribute status shall be INVALID_IN_STATE." + + "\n" + + " 2. Otherwise, the attribute status shall be SUCCESS.", + + xref: { document: "cluster", section: "4.3.9.60" } + }, + + Field({ name: "entry", type: "PresetStruct" }) + ), + + Attribute( + { + name: "Schedules", id: 0x51, type: "list", access: "RW VM", conformance: "MSCH", constraint: "desc", + default: [], quality: "N T", + + details: "This attribute shall contain a list of ScheduleStructs. On receipt of a write request:" + + "\n" + + " 1. For all schedules in the write request:" + + "\n" + + " a. If the ScheduleHandle field is null, the ScheduleStruct shall be treated as an added " + + " schedule, and the device shall create a new unique value for the ScheduleHandle field." + + "\n" + + " i. If the BuiltIn field is true, a response with the status code CONSTRAINT_ERROR shall be " + + " returned." + + "\n" + + " b. Otherwise, if the ScheduleHandle field is not null, the ScheduleStruct shall be treated as a " + + " modification of an existing schedule." + + "\n" + + " i. If the value of the ScheduleHandle field does not match any of the existing schedules, a " + + " response with the status code NOT_FOUND shall be returned." + + "\n" + + " ii. If the BuiltIn field is true, and the ScheduleStruct in the current value with a matching " + + " ScheduleHandle field has a BuiltIn field set to false, a response with the status code " + + " CONSTRAINT_ERROR shall be returned." + + "\n" + + " iii. If the BuiltIn field is false, and the ScheduleStruct in the current value with a " + + " matching ScheduleHandle field has a BuiltIn field set to true, a response with the " + + " status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " c. If the specified SystemMode does not exist in ScheduleTypes, a response with the status code " + + " CONSTRAINT_ERROR shall be returned." + + "\n" + + " d. If the number of transitions exceeds the NumberOfScheduleTransitions value, a response with " + + " the status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " e. If the value of the NumberOfScheduleTransitionsPerDay attribute is not null, and the number " + + " of transitions on any single day of the week exceeds the NumberOfScheduleTransitionsPerDay " + + " value, a response with the status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " f. If the PresetHandle field is present, but the associated ScheduleTypeStruct does not have " + + " the SupportsPresets bit set, a response with the status code CONSTRAINT_ERROR shall be " + + " returned." + + "\n" + + " g. If the PresetHandle field is present, but after applying all pending changes, the Presets " + + " attribute would not contain a PresetStruct whose PresetHandle field matches the value of the " + + " PresetHandle field, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " h. If the Name is set, but the associated ScheduleTypeStruct does not have the SupportsNames " + + " bit set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " i. For all transitions in all schedules in the write request:" + + "\n" + + " i. If the PresetHandle field is present, but the ScheduleTypeStruct matching the value of the " + + " SystemMode field on the encompassing ScheduleStruct does not have the SupportsPresets bit " + + " set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " j. If the PresetHandle field is present, but after applying all pending changes, the Presets " + + " attribute would not contain a PresetStruct whose PresetHandle field matches the value of the " + + " PresetHandle field, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " i. If the SystemMode field is present, but the ScheduleTypeStruct matching the value of the " + + " SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints " + + " bit set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " ii. If the SystemMode field is has a value of SystemModeOff, but the ScheduleTypeStruct " + + " matching the value of the SystemMode field on the encompassing ScheduleStruct does not " + + " have the SupportsOff bit set, a response with the status code CONSTRAINT_ERROR shall be " + + " returned." + + "\n" + + " k. If the HeatingSetpoint field is present, but the ScheduleTypeStruct matching the value of " + + " the SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints " + + " bit set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " l. If the CoolingSetpoint field is present, but the ScheduleTypeStruct matching the value of " + + " the SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints " + + " bit set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " 2. If appending the received ScheduleStruct to the pending list of Schedules would cause the " + + " total number of pending schedules to exceed the value of the NumberOfSchedules attribute, a " + + " response with the status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " 3. If appending the received ScheduleStruct to the pending list of Schedules would cause the " + + " total number of pending schedules whose SystemMode field matches the appended schedule’s " + + " SystemMode field to exceed the value of the NumberOfSchedules field on the ScheduleTypeStruct " + + " whose SystemMode field matches the appended schedule’s SystemMode field, a response with the " + + " status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " 4. Otherwise, the write shall be pended until receipt of a commit request, and the attribute " + + " status shall be SUCCESS." + + "\n" + + " a. If the BuiltIn field is null:" + + "\n" + + " i. If there is a ScheduleStruct in the current value with a matching ScheduleHandle field, " + + " the BuiltIn field on the pending ScheduleStruct shall be set to the value of the BuiltIn " + + " on the matching ScheduleStruct." + + "\n" + + " ii. Otherwise, the BuiltIn field on the pending ScheduleStruct shall be set to false." + + "\n" + + "On an attempt to commit, the status of this attribute shall be determined as follows:" + + "\n" + + " 1. For all existing schedules:" + + "\n" + + " a. If, after applying all pending changes, the updated value of the Schedules attribute would " + + " not contain a ScheduleStruct with a matching ScheduleHandle field, indicating the removal of " + + " the ScheduleStruct, the server shall check for invalid removal of the ScheduleStruct:" + + "\n" + + " i. If the BuiltIn field is true on the removed ScheduleStruct, the attribute status shall be " + + " CONSTRAINT_ERROR." + + "\n" + + " ii. If the removed ScheduleHandle is equal to the value of the ActiveScheduleHandle " + + " attribute, the attribute status shall be INVALID_IN_STATE." + + "\n" + + " 2. Otherwise, the attribute status shall be SUCCESS.", + + xref: { document: "cluster", section: "4.3.9.61" } + }, + + Field({ name: "entry", type: "ScheduleStruct" }) + ), + + Attribute({ + name: "SetpointHoldExpiryTimestamp", id: 0x52, type: "epoch-s", access: "R V", conformance: "O", + default: null, quality: "X N", + + details: "If there is a known time when the TemperatureSetpointHold shall be cleared, this attribute shall " + + "contain the timestamp in UTC indicating when that will happen. If there is no such known time, this " + + "attribute shall be null." + + "\n" + + "If the TemperatureSetpointHold is set to SetpointHoldOff or the TemperatureSetpointHoldDuration is " + + "set to null, this attribute shall be set to null indicating there is no hold on the Thermostat " + + "either with or without a duration.", + + xref: { document: "cluster", section: "4.3.9.62" } + }), + + Command( + { + name: "SetpointRaiseLower", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "4.3.10.1" } + }, + Field({ + name: "Mode", id: 0x0, type: "SetpointRaiseLowerModeEnum", conformance: "M", constraint: "desc", + details: "The field shall specify which setpoints are to be adjusted.", + xref: { document: "cluster", section: "4.3.10.1.1" } + }), + + Field({ + name: "Amount", id: 0x1, type: "int8", conformance: "M", + details: "This field shall indicate the amount (possibly negative) that should be added to the setpoint(s), " + + "in steps of 0.1°C.", + xref: { document: "cluster", section: "4.3.10.1.2" } + }) + ), + + Command( + { + name: "SetWeeklySchedule", id: 0x1, access: "M", conformance: "SCH", direction: "request", + response: "status", + + details: "This command is used to update the thermostat weekly setpoint schedule from a management system. If " + + "the thermostat already has a weekly setpoint schedule programmed, then it SHOULD replace each daily " + + "setpoint set as it receives the updates from the management system. For example, if the thermostat " + + "has 4 setpoints for every day of the week and is sent a SetWeeklySchedule command with one setpoint " + + "for Saturday then the thermostat SHOULD remove all 4 setpoints for Saturday and replace those with " + + "the updated setpoint but leave all other days unchanged. If the schedule is larger than what fits " + + "in one frame or contains more than 10 transitions, the schedule shall then be sent using multiple " + + "SetWeeklySchedule Commands.", + + xref: { document: "cluster", section: "4.3.10.2" } + }, + + Field({ + name: "NumberOfTransitionsForSequence", id: 0x0, type: "uint8", conformance: "M", + details: "This field shall indicate how many individual transitions to expect for this sequence of commands. " + + "If a device supports more than 10 transitions in its schedule they can send this by sending more " + + "than 1 “Set Weekly Schedule” command, each containing the separate information that the device " + + "needs to set.", + xref: { document: "cluster", section: "4.3.10.2.1" } + }), + + Field({ + name: "DayOfWeekForSequence", id: 0x1, type: "ScheduleDayOfWeekBitmap", conformance: "M", + constraint: "desc", + + details: "This field shall represent the day of the week at which all the transitions within the payload of " + + "the command SHOULD be associated to. This field is a bitmap and therefore the associated setpoint " + + "could overlap onto multiple days (you could set one transition time for all “week days” or whatever " + + "combination of days the implementation requests)." + + "\n" + + "Each setpoint transition will begin with the day of week for this transition. There can be up to 10 " + + "transitions for each command.", + + xref: { document: "cluster", section: "4.3.10.2.2" } + }), + + Field({ + name: "ModeForSequence", id: 0x2, type: "ScheduleModeBitmap", conformance: "M", constraint: "desc", + + details: "This field shall indicate how the application decodes the setpoint fields of each transition in the " + + "Transitions list." + + "\n" + + "If the HeatSetpointPresent bit is On, the HeatSetpoint field shall NOT be null in every entry of " + + "the Transitions list." + + "\n" + + "If the HeatSetpointPresent bit is Off, the HeatSetpoint field shall be null in every entry of the " + + "Transitions list." + + "\n" + + "If the CoolSetpointPresent bit is On, the CoolSetpoint field shall NOT be null in every entry of " + + "the Transitions list." + + "\n" + + "If the CoolSetpointPresent bit is Off, the CoolSetpoint field shall be null in every entry of the " + + "Transitions list." + + "\n" + + "At least one of the bits in the Mode For Sequence byte shall be on." + + "\n" + + "Both bits must be respected, even if the HEAT or COOL feature is not supported, to ensure the " + + "command is decoded and handled correctly.", + + xref: { document: "cluster", section: "4.3.10.2.3" } + }), + + Field( + { + name: "Transitions", id: 0x3, type: "list", conformance: "M", constraint: "max 10", + details: "This field shall contain the list of setpoint transitions used to update the specified daily " + + "schedules", + xref: { document: "cluster", section: "4.3.10.2.4" } + }, + + Field({ name: "entry", type: "WeeklyScheduleTransitionStruct" }) + ) + ), + + Command( + { + name: "GetWeeklySchedule", id: 0x2, access: "O", conformance: "SCH", direction: "request", + response: "GetWeeklyScheduleResponse", + xref: { document: "cluster", section: "4.3.10.3" } + }, + + Field({ + name: "DaysToReturn", id: 0x0, type: "ScheduleDayOfWeekBitmap", conformance: "M", + constraint: "desc", + details: "This field shall indicate the number of days the client would like to return the setpoint values " + + "for and could be any combination of single days or the entire week.", + xref: { document: "cluster", section: "4.3.10.3.1" } + }), + + Field({ + name: "ModeToReturn", id: 0x1, type: "ScheduleModeBitmap", conformance: "M", constraint: "desc", + details: "This field shall indicate the mode the client would like to return the set point values for and " + + "could be any combination of heat only, cool only or heat & cool.", + xref: { document: "cluster", section: "4.3.10.3.2" } + }) + ), + + Command( + { + name: "GetWeeklyScheduleResponse", id: 0x0, conformance: "SCH", direction: "response", + details: "This command has the same payload format as the Set Weekly Schedule.", + xref: { document: "cluster", section: "4.3.10.4" } + }, + Field({ name: "NumberOfTransitionsForSequence", id: 0x0, type: "uint8", conformance: "M" }), + Field({ + name: "DayOfWeekForSequence", id: 0x1, type: "ScheduleDayOfWeekBitmap", conformance: "M", + constraint: "desc" + }), + Field({ name: "ModeForSequence", id: 0x2, type: "ScheduleModeBitmap", conformance: "M", constraint: "desc" }), + Field( + { name: "Transitions", id: 0x3, type: "list", conformance: "M", constraint: "max 10" }, + Field({ name: "entry", type: "WeeklyScheduleTransitionStruct" }) + ) + ), + + Command({ + name: "ClearWeeklySchedule", id: 0x3, access: "M", conformance: "SCH", direction: "request", + response: "status", + details: "This command is used to clear the weekly schedule. The Clear weekly schedule has no payload." + + "\n" + + "Upon receipt, all transitions currently stored shall be cleared and a default response of SUCCESS " + + "shall be sent in response. There are no error responses to this command.", + xref: { document: "cluster", section: "4.3.10.5" } + }), + + Command( + { + name: "GetRelayStatusLogResponse", id: 0x1, conformance: "GetRelayStatusLog", direction: "response", + details: "This command is sent from the thermostat cluster server in response to the Get Relay Status Log. " + + "After the Relay Status Entry is sent over the air to the requesting client, the specific entry will " + + "be cleared from the thermostat internal log.", + xref: { document: "cluster", section: "4.3.10.7" } + }, + + Field({ + name: "TimeOfDay", id: 0x0, type: "uint16", conformance: "M", constraint: "max 1439", + details: "This field shall indicate the sample time of the day, in minutes since midnight, when the relay " + + "status was captured for this associated log entry. For example, 6am will be represented by 360 " + + "minutes since midnight and 11:30pm will be represented by 1410 minutes since midnight.", + xref: { document: "cluster", section: "4.3.10.7.1" } + }), + + Field({ + name: "RelayStatus", id: 0x1, type: "RelayStateBitmap", conformance: "M", constraint: "desc", + details: "This field shall indicate the relay status for thermostat when the log is captured. Each bit " + + "represents one relay used by the thermostat. If the bit is on, the associated relay is on and " + + "active. Each thermostat manufacturer can create its own mapping between the bitmap and the " + + "associated relay.", + xref: { document: "cluster", section: "4.3.10.7.2" } + }), + + Field({ + name: "LocalTemperature", id: 0x2, type: "temperature", conformance: "M", quality: "X", + details: "This field shall indicate the LocalTemperature when the log is captured. The null value indicates " + + "that LocalTemperature was invalid or unavailable.", + xref: { document: "cluster", section: "4.3.10.7.3" } + }), + + Field({ + name: "HumidityInPercentage", id: 0x3, type: "uint8", conformance: "M", constraint: "0% to 100%", + quality: "X" + }), + Field({ + name: "SetPoint", id: 0x4, type: "temperature", conformance: "M", + details: "This field shall indicate the target setpoint temperature when the log is captured.", + xref: { document: "cluster", section: "4.3.10.7.5" } + }), + Field({ + name: "UnreadEntries", id: 0x5, type: "uint16", conformance: "M", + details: "This field shall indicate the number of unread entries within the thermostat internal log system.", + xref: { document: "cluster", section: "4.3.10.7.6" } + }) + ), + + Command( + { + name: "SetActiveScheduleRequest", id: 0x5, access: "O", conformance: "MSCH", direction: "request", + response: "status", + xref: { document: "cluster", section: "4.3.10.8" } + }, + + Field({ + name: "ScheduleHandle", id: 0x0, type: "octstr", conformance: "M", constraint: "max 16", + details: "This field shall specify the value of the ScheduleHandle field on the ScheduleStruct to be made " + + "active.", + xref: { document: "cluster", section: "4.3.10.8.1" } + }) + ), + + Command( + { + name: "SetActivePresetRequest", id: 0x6, access: "O", conformance: "PRES", direction: "request", + response: "status", + xref: { document: "cluster", section: "4.3.10.9" } + }, + + Field({ + name: "PresetHandle", id: 0x0, type: "octstr", conformance: "M", constraint: "max 16", quality: "X", + details: "This field shall specify the value of the PresetHandle field on the PresetStruct to be made active. " + + "If the field is set to null, that indicates there should be no active preset.", + xref: { document: "cluster", section: "4.3.10.9.1" } + }) + ), + + Datatype( + { + name: "TemperatureDifference", type: "int16", + + details: "This data type is derived from int16 and represents a temperature difference with a resolution of " + + "0.01°C." + + "\n" + + " • value = (temperature in °C) x 100" + + "\n" + + " • -4°C ⇒ -400" + + "\n" + + " • 123.45°C ⇒ 12345" + + "\n" + + "The full (non-null) range of -327.67°C to 327.67°C may be used.", + + xref: { document: "cluster", section: "4.3.8.1" } + } + ), + + Datatype( + { + name: "SignedTemperature", type: "int8", + + details: "This data type is derived from int8 and represents a temperature from -12.7°C to 12.7°C with a " + + "resolution of 0.1°C." + + "\n" + + " • value = (temperature in °C) x 10" + + "\n" + + " • -4°C ⇒ -40" + + "\n" + + " • 12.3°C ⇒ 123" + + "\n" + + "This type is employed where compactness of representation is important and where the resolution and " + + "range are still satisfactory.", + + xref: { document: "cluster", section: "4.3.8.2" } + } + ), + + Datatype( + { + name: "UnsignedTemperature", type: "uint8", + + details: "This data type is derived from uint8 and represents a temperature from 0°C to 25.5°C with a " + + "resolution of 0.1°C." + + "\n" + + " • value = (temperature in °C) x 10" + + "\n" + + " • 4°C ⇒ 40" + + "\n" + + " • 12.3°C ⇒ 123" + + "\n" + + "This type is employed where compactness of representation is important and where the resolution and " + + "range are still satisfactory.", + + xref: { document: "cluster", section: "4.3.8.3" } + } + ), + + Datatype( + { name: "ACErrorCodeBitmap", type: "map32", xref: { document: "cluster", section: "4.3.8.4" } }, + Field({ name: "CompressorFail", constraint: "0", description: "Compressor Failure or Refrigerant Leakage" }), + Field({ name: "RoomSensorFail", constraint: "1", description: "Room Temperature Sensor Failure" }), + Field({ name: "OutdoorSensorFail", constraint: "2", description: "Outdoor Temperature Sensor Failure" }), + Field({ name: "CoilSensorFail", constraint: "3", description: "Indoor Coil Temperature Sensor Failure" }), + Field({ name: "FanFail", constraint: "4", description: "Fan Failure" }) + ), + + Datatype( + { name: "AlarmCodeBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.5" } }, + Field({ + name: "Initialization", constraint: "0", + description: "Initialization failure. The device failed to complete initialization at power-up." + }), + Field({ name: "Hardware", constraint: "1", description: "Hardware failure" }), + Field({ name: "SelfCalibration", constraint: "2", description: "Self-calibration failure" }) + ), + + Datatype( + { name: "HVACSystemTypeBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.6" } }, + + Field( + { + name: "CoolingStage", constraint: "1 to 1", + description: "Stage of cooling the HVAC system is using.", + + details: "These bits shall indicate what stage of cooling the HVAC system is using." + + "\n" + + " • 00 = Cool Stage 1" + + "\n" + + " • 01 = Cool Stage 2" + + "\n" + + " • 10 = Cool Stage 3" + + "\n" + + " • 11 = Reserved", + + xref: { document: "cluster", section: "4.3.8.6.1" } + } + ), + + Field( + { + name: "HeatingStage", constraint: "3 to 3", + description: "Stage of heating the HVAC system is using.", + + details: "These bits shall indicate what stage of heating the HVAC system is using." + + "\n" + + " • 00 = Heat Stage 1" + + "\n" + + " • 01 = Heat Stage 2" + + "\n" + + " • 10 = Heat Stage 3" + + "\n" + + " • 11 = Reserved", + + xref: { document: "cluster", section: "4.3.8.6.2" } + } + ), + + Field( + { + name: "HeatingIsHeatPump", constraint: "4", description: "Is the heating type Heat Pump.", + details: "This bit shall indicate whether the HVAC system is conventional or a heat pump." + + "\n" + + " • 0 = Conventional" + + "\n" + + " • 1 = Heat Pump", + xref: { document: "cluster", section: "4.3.8.6.3" } + } + ), + + Field( + { + name: "HeatingUsesFuel", constraint: "5", description: "Does the HVAC system use fuel.", + details: "This bit shall indicate whether the HVAC system uses fuel." + + "\n" + + " • 0 = Does not use fuel" + + "\n" + + " • 1 = Uses fuel", + xref: { document: "cluster", section: "4.3.8.6.4" } + } + ) + ), + + Datatype( + { name: "OccupancyBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.7" } }, + + Field({ + name: "Occupied", constraint: "0", description: "Indicates the occupancy state", + details: "If this bit is set, it shall indicate the occupied state else if the bit if not set, it shall " + + "indicate the unoccupied state.", + xref: { document: "cluster", section: "4.3.8.7.1" } + }) + ), + + Datatype( + { name: "PresetTypeFeaturesBitmap", type: "map16", xref: { document: "cluster", section: "4.3.8.8" } }, + Field({ + name: "Automatic", constraint: "0", + description: "Preset may be automatically activated by the thermostat" + }), + Field({ name: "SupportsNames", constraint: "1", description: "Preset supports user- provided names" }) + ), + + Datatype( + { name: "ProgrammingOperationModeBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.9" } }, + Field({ + name: "ScheduleActive", constraint: "0", + description: "Schedule programming mode. This enables any programmed weekly schedule configurations." + }), + Field({ name: "AutoRecovery", constraint: "1", description: "Auto/recovery mode" }), + Field({ name: "Economy", constraint: "2", description: "Economy/EnergyStar mode" }) + ), + + Datatype( + { name: "RelayStateBitmap", type: "map16", xref: { document: "cluster", section: "4.3.8.10" } }, + Field({ name: "Heat", constraint: "0", description: "Heat Stage On" }), + Field({ name: "Cool", constraint: "1", description: "Cool Stage On" }), + Field({ name: "Fan", constraint: "2", description: "Fan Stage On" }), + Field({ name: "HeatStage2", constraint: "3", description: "Heat 2nd Stage On" }), + Field({ name: "CoolStage2", constraint: "4", description: "Cool 2nd Stage On" }), + Field({ name: "FanStage2", constraint: "5", description: "Fan 2nd Stage On" }), + Field({ name: "FanStage3", constraint: "6", description: "Fan 3rd Stage On" }) + ), + + Datatype( + { name: "RemoteSensingBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.11" } }, + Field({ + name: "LocalTemperature", constraint: "0", + description: "Calculated Local Temperature is derived from a remote node" + }), + + Field({ + name: "OutdoorTemperature", constraint: "1", + description: "OutdoorTemperature is derived from a remote node", + details: "This bit shall be supported if the OutdoorTemperature attribute is supported.", + xref: { document: "cluster", section: "4.3.8.11.1" } + }), + + Field({ name: "Occupancy", constraint: "2", description: "Occupancy is derived from a remote node" }) + ), + + Datatype( + { name: "ScheduleTypeFeaturesBitmap", type: "map16", xref: { document: "cluster", section: "4.3.8.12" } }, + + Field({ + name: "SupportsPresets", constraint: "0", description: "Supports presets", + details: "This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the " + + "SystemMode field on the encompassing ScheduleTypeStruct supports specifying presets on " + + "ScheduleTransitionStructs contained in its Transitions field.", + xref: { document: "cluster", section: "4.3.8.12.1" } + }), + + Field({ + name: "SupportsSetpoints", constraint: "1", description: "Supports setpoints", + details: "This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the " + + "SystemMode field on the encompassing ScheduleTypeStruct supports specifying setpoints on " + + "ScheduleTransitionStructs contained in its Transitions field.", + xref: { document: "cluster", section: "4.3.8.12.2" } + }), + + Field({ + name: "SupportsNames", constraint: "2", description: "Supports user-provided names", + details: "This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the " + + "SystemMode field on the encompassing ScheduleTypeStruct supports setting the value of the Name " + + "field.", + xref: { document: "cluster", section: "4.3.8.12.3" } + }), + + Field({ + name: "SupportsOff", constraint: "3", description: "Supports transitioning to SystemModeOff", + details: "This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the " + + "SystemMode field on the encompassing ScheduleTypeStruct supports setting its SystemMode field to " + + "Off.", + xref: { document: "cluster", section: "4.3.8.12.4" } + }) + ), + + Datatype( + { name: "ScheduleDayOfWeekBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.13" } }, + Field({ name: "Sunday", constraint: "0", description: "Sunday" }), + Field({ name: "Monday", constraint: "1", description: "Monday" }), + Field({ name: "Tuesday", constraint: "2", description: "Tuesday" }), + Field({ name: "Wednesday", constraint: "3", description: "Wednesday" }), + Field({ name: "Thursday", constraint: "4", description: "Thursday" }), + Field({ name: "Friday", constraint: "5", description: "Friday" }), + Field({ name: "Saturday", constraint: "6", description: "Saturday" }), + Field({ name: "Away", constraint: "7", description: "Away or Vacation" }) + ), + + Datatype( + { name: "ScheduleModeBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.14" } }, + Field({ name: "HeatSetpointPresent", constraint: "0", description: "Adjust Heat Setpoint" }), + Field({ name: "CoolSetpointPresent", constraint: "1", description: "Adjust Cool Setpoint" }) + ), + Datatype( + { name: "ACCapacityFormatEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.15" } }, + Field({ name: "BtUh", id: 0x0, conformance: "O", description: "British Thermal Unit per Hour" }) + ), + + Datatype( + { name: "ACCompressorTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.16" } }, + Field({ name: "Unknown", id: 0x0, conformance: "O", description: "Unknown compressor type" }), + Field({ name: "T1", id: 0x1, conformance: "O", description: "Max working ambient 43 °C" }), + Field({ name: "T2", id: 0x2, conformance: "O", description: "Max working ambient 35 °C" }), + Field({ name: "T3", id: 0x3, conformance: "O", description: "Max working ambient 52 °C" }) + ), + + Datatype( + { name: "ACLouverPositionEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.17" } }, + Field({ name: "Closed", id: 0x1, conformance: "O", description: "Fully Closed" }), + Field({ name: "Open", id: 0x2, conformance: "O", description: "Fully Open" }), + Field({ name: "Quarter", id: 0x3, conformance: "O", description: "Quarter Open" }), + Field({ name: "Half", id: 0x4, conformance: "O", description: "Half Open" }), + Field({ name: "ThreeQuarters", id: 0x5, conformance: "O", description: "Three Quarters Open" }) + ), + + Datatype( + { name: "ACRefrigerantTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.18" } }, + Field({ name: "Unknown", id: 0x0, conformance: "O", description: "Unknown Refrigerant Type" }), + Field({ name: "R22", id: 0x1, conformance: "O", description: "R22 Refrigerant" }), + Field({ name: "R410A", id: 0x2, conformance: "O", description: "R410a Refrigerant" }), + Field({ name: "R407C", id: 0x3, conformance: "O", description: "R407c Refrigerant" }) + ), + + Datatype( + { name: "ACTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.19" } }, + Field({ name: "Unknown", id: 0x0, conformance: "O", description: "Unknown AC Type" }), + Field({ name: "CoolingFixed", id: 0x1, conformance: "O", description: "Cooling and Fixed Speed" }), + Field({ name: "HeatPumpFixed", id: 0x2, conformance: "O", description: "Heat Pump and Fixed Speed" }), + Field({ name: "CoolingInverter", id: 0x3, conformance: "O", description: "Cooling and Inverter" }), + Field({ name: "HeatPumpInverter", id: 0x4, conformance: "O", description: "Heat Pump and Inverter" }) + ), + + Datatype( + { name: "SetpointRaiseLowerModeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.20" } }, + Field({ name: "Heat", id: 0x0, conformance: "HEAT", description: "Adjust Heat Setpoint" }), + Field({ name: "Cool", id: 0x1, conformance: "COOL", description: "Adjust Cool Setpoint" }), + Field({ + name: "Both", id: 0x2, conformance: "HEAT | COOL", + description: "Adjust Heat Setpoint and Cool Setpoint" + }) + ), + + Datatype( + { + name: "ControlSequenceOfOperationEnum", type: "enum8", + + details: "NOTE" + + "\n" + + "CoolingAndHeating" + + "\n" + + "A thermostat indicating it supports CoolingAndHeating (or CoolingAndHeatingWithReheat) SHOULD be " + + "able to request heating or cooling on demand and will usually support the Auto SystemMode." + + "\n" + + "Systems which support cooling or heating, requiring external intervention to change modes or where " + + "the whole building must be in the same mode, SHOULD report CoolingOnly or HeatingOnly based on the " + + "current capability.", + + xref: { document: "cluster", section: "4.3.8.21" } + }, + + Field({ name: "CoolingOnly", id: 0x0, conformance: "[COOL]", description: "Heat and Emergency are not possible" }), + Field({ + name: "CoolingWithReheat", id: 0x1, conformance: "[COOL]", + description: "Heat and Emergency are not possible" + }), + Field({ + name: "HeatingOnly", id: 0x2, conformance: "[HEAT]", + description: "Cool and precooling (see Terms) are not possible" + }), + Field({ + name: "HeatingWithReheat", id: 0x3, conformance: "[HEAT]", + description: "Cool and precooling are not possible" + }), + Field({ name: "CoolingAndHeating", id: 0x4, conformance: "[HEAT & COOL]", description: "All modes are possible" }), + Field({ + name: "CoolingAndHeatingWithReheat", id: 0x5, conformance: "[HEAT & COOL]", + description: "All modes are possible" + }) + ), + + Datatype( + { name: "PresetScenarioEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.22" } }, + + Field({ + name: "Occupied", id: 0x1, conformance: "M", + description: "The thermostat-controlled area is occupied", + details: "This value shall indicate the preset for periods when the thermostat’s temperature-controlled area " + + "is occupied. It is intended for thermostats that can automatically determine occupancy.", + xref: { document: "cluster", section: "4.3.8.22.2" } + }), + + Field({ + name: "Unoccupied", id: 0x2, conformance: "M", + description: "The thermostat-controlled area is unoccupied", + details: "This value shall indicate the preset for periods when the thermostat’s temperature-controlled area " + + "is unoccupied. It is intended for thermostats that can automatically determine occupancy.", + xref: { document: "cluster", section: "4.3.8.22.3" } + }), + + Field({ + name: "Sleep", id: 0x3, conformance: "M", description: "Users are likely to be sleeping", + details: "This value shall indicate the preset for periods when users are likely to be asleep.", + xref: { document: "cluster", section: "4.3.8.22.4" } + }), + Field({ + name: "Wake", id: 0x4, conformance: "M", description: "Users are likely to be waking up", + details: "This value shall indicate the preset for periods when users are likely to be waking up.", + xref: { document: "cluster", section: "4.3.8.22.5" } + }), + + Field({ + name: "Vacation", id: 0x5, conformance: "M", description: "Users are on vacation", + details: "This value shall indicate the preset for periods when users are on vacation, or otherwise out-of- " + + "home for extended periods of time.", + xref: { document: "cluster", section: "4.3.8.22.6" } + }), + + Field({ + name: "GoingToSleep", id: 0x6, conformance: "M", + description: "Users are likely to be going to sleep", + details: "This value shall indicate the preset for periods when users are likely to be going to sleep.", + xref: { document: "cluster", section: "4.3.8.22.7" } + }), + + Field({ + name: "UserDefined", id: 0xfe, conformance: "M", description: "Custom presets", + details: "This value shall indicate a free-form preset; when set, the Name field on PresetStruct shall NOT be " + + "null.", + xref: { document: "cluster", section: "4.3.8.22.8" } + }) + ), + + Datatype( + { name: "SetpointChangeSourceEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.23" } }, + Field({ + name: "Manual", id: 0x0, conformance: "O", + description: "Manual, user-initiated setpoint change via the thermostat" + }), + Field({ + name: "Schedule", id: 0x1, conformance: "[SCH | MSCH]", + description: "Schedule/internal programming-initiated setpoint change" + }), + Field({ + name: "External", id: 0x2, conformance: "O", + description: "Externally-initiated setpoint change (e.g., DRLC cluster command, attribute write)" + }) + ), + + Datatype( + { name: "StartOfWeekEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.24" } }, + Field({ name: "Sunday", id: 0x0, conformance: "M" }), + Field({ name: "Monday", id: 0x1, conformance: "M" }), + Field({ name: "Tuesday", id: 0x2, conformance: "M" }), + Field({ name: "Wednesday", id: 0x3, conformance: "M" }), + Field({ name: "Thursday", id: 0x4, conformance: "M" }), + Field({ name: "Friday", id: 0x5, conformance: "M" }), + Field({ name: "Saturday", id: 0x6, conformance: "M" }) + ), + + Datatype( + { + name: "SystemModeEnum", type: "enum8", + details: "Table 9. Interpretation of Heat, Cool and Auto SystemModeEnum Values", + xref: { document: "cluster", section: "4.3.8.25" } + }, + Field({ + name: "Off", id: 0x0, conformance: "O", + description: "The Thermostat does not generate demand for Cooling or Heating" + }), + Field({ + name: "Auto", id: 0x1, conformance: "AUTO", + description: "Demand is generated for either Cooling or Heating, as required" + }), + Field({ name: "Cool", id: 0x3, conformance: "[COOL]", description: "Demand is only generated for Cooling" }), + Field({ name: "Heat", id: 0x4, conformance: "[HEAT]", description: "Demand is only generated for Heating" }), + Field({ + name: "EmergencyHeat", id: 0x5, conformance: "[HEAT]", + description: "2nd stage heating is in use to achieve desired temperature" + }), + Field({ name: "Precooling", id: 0x6, conformance: "[COOL]", description: "(see Terms)" }), + Field({ name: "FanOnly", id: 0x7, conformance: "O" }), + Field({ name: "Dry", id: 0x8, conformance: "O" }), + Field({ name: "Sleep", id: 0x9, conformance: "O" }) + ), + + Datatype( + { name: "ThermostatRunningModeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.26" } }, + Field({ + name: "Off", id: 0x0, conformance: "O", + description: "The Thermostat does not generate demand for Cooling or Heating" + }), + Field({ name: "Cool", id: 0x3, conformance: "[COOL]", description: "Demand is only generated for Cooling" }), + Field({ name: "Heat", id: 0x4, conformance: "[HEAT]", description: "Demand is only generated for Heating" }) + ), + + Datatype( + { name: "TemperatureSetpointHoldEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.27" } }, + Field({ name: "SetpointHoldOff", id: 0x0, conformance: "M", description: "Follow scheduling program" }), + Field({ + name: "SetpointHoldOn", id: 0x1, conformance: "M", + description: "Maintain current setpoint, regardless of schedule transitions" + }) + ), + + Datatype( + { name: "PresetStruct", type: "struct", xref: { document: "cluster", section: "4.3.8.28" } }, + + Field({ + name: "PresetHandle", id: 0x0, type: "octstr", conformance: "M", constraint: "max 16", quality: "X", + + details: "This field shall indicate a device generated identifier for this preset. It shall be unique on the " + + "device, and shall NOT be reused after the associated preset has been deleted." + + "\n" + + "This field shall only be null when the encompassing PresetStruct is appended to the Presets " + + "attribute for the purpose of creating a new Preset. Refer to Presets for the creation of Preset " + + "handles.", + + xref: { document: "cluster", section: "4.3.8.28.1" } + }), + + Field({ + name: "PresetScenario", id: 0x1, type: "PresetScenarioEnum", conformance: "M", + details: "This field shall indicate the associated PresetScenarioEnum value for this preset.", + xref: { document: "cluster", section: "4.3.8.28.2" } + }), + + Field({ + name: "Name", id: 0x2, type: "string", conformance: "O", constraint: "max 64", default: null, + quality: "X", + details: "This field shall indicate a name provided by a user. The null value shall indicate no name." + + "\n" + + "Within each subset of presets sharing the same PresetScenario field value, there shall NOT be any " + + "presets with the same value, including null as a value, in the Name field.", + xref: { document: "cluster", section: "4.3.8.28.3" } + }), + + Field({ + name: "CoolingSetpoint", id: 0x3, type: "temperature", conformance: "COOL", constraint: "desc", + default: { type: "celsius", value: 26 }, + details: "This field shall indicate the cooling setpoint for the preset. Refer to Setpoint Limits for value " + + "constraints.", + xref: { document: "cluster", section: "4.3.8.28.4" } + }), + + Field({ + name: "HeatingSetpoint", id: 0x4, type: "temperature", conformance: "HEAT", constraint: "desc", + default: { type: "celsius", value: 20 }, + details: "This field shall indicate the heating setpoint for the preset. Refer to Setpoint Limits for value " + + "constraints.", + xref: { document: "cluster", section: "4.3.8.28.5" } + }), + + Field({ + name: "BuiltIn", id: 0x5, type: "bool", conformance: "M", default: false, quality: "X", + details: "This field shall indicate whether the preset is marked as \"built-in\", meaning that it can be " + + "modified, but it cannot be deleted.", + xref: { document: "cluster", section: "4.3.8.28.6" } + }) + ), + + Datatype( + { name: "PresetTypeStruct", type: "struct", xref: { document: "cluster", section: "4.3.8.29" } }, + Field({ + name: "PresetScenario", id: 0x0, type: "PresetScenarioEnum", conformance: "M", + details: "This field shall specify a PresetScenarioEnum value supported by this thermostat.", + xref: { document: "cluster", section: "4.3.8.29.1" } + }), + Field({ + name: "NumberOfPresets", id: 0x1, type: "uint8", conformance: "M", default: 0, + details: "This field shall specify a limit for the number of presets for this PresetScenarioEnum.", + xref: { document: "cluster", section: "4.3.8.29.2" } + }), + Field({ + name: "PresetTypeFeatures", id: 0x2, type: "PresetTypeFeaturesBitmap", conformance: "M", default: 0, + details: "This field shall specify a bitmap of features for this PresetTypeStruct.", + xref: { document: "cluster", section: "4.3.8.29.3" } + }) + ), + + Datatype( + { + name: "WeeklyScheduleTransitionStruct", type: "struct", + details: "This represents a single transition in a Thermostat schedule", + xref: { document: "cluster", section: "4.3.8.30" } + }, + + Field({ + name: "TransitionTime", id: 0x0, type: "uint16", conformance: "M", constraint: "max 1439", + details: "This field shall represent the start time of the schedule transition during the associated day. The " + + "time will be represented by a 16 bits unsigned integer to designate the minutes since midnight. For " + + "example, 6am will be represented by 360 minutes since midnight and 11:30pm will be represented by " + + "1410 minutes since midnight.", + xref: { document: "cluster", section: "4.3.8.30.1" } + }), + + Field({ + name: "HeatSetpoint", id: 0x1, type: "temperature", conformance: "M", quality: "X", + details: "This field shall represent the heat setpoint to be applied at this associated transition start time.", + xref: { document: "cluster", section: "4.3.8.30.2" } + }), + Field({ + name: "CoolSetpoint", id: 0x2, type: "temperature", conformance: "M", quality: "X", + details: "This field shall represent the cool setpoint to be applied at this associated transition start time.", + xref: { document: "cluster", section: "4.3.8.30.3" } + }) + ), + + Datatype( + { name: "ScheduleStruct", type: "struct", xref: { document: "cluster", section: "4.3.8.31" } }, + + Field({ + name: "ScheduleHandle", id: 0x0, type: "octstr", conformance: "M", constraint: "max 16", + quality: "X", + + details: "This field shall indicate a device generated identifier for this schedule. It shall be unique on " + + "the device, and shall NOT be reused after the associated schedule has been deleted." + + "\n" + + "This field shall only be null when the encompassing ScheduleStruct is appended to the Schedules " + + "attribute for the purpose of creating a new Schedule. Refer to Schedules for the creation of " + + "Schedule handles.", + + xref: { document: "cluster", section: "4.3.8.31.1" } + }), + + Field({ + name: "SystemMode", id: 0x1, type: "SystemModeEnum", conformance: "M", constraint: "desc", + details: "This field shall specify the default thermostat system mode for transitions in this schedule. The " + + "only valid values for this field shall be Auto, Heat, and Cool.", + xref: { document: "cluster", section: "4.3.8.31.2" } + }), + + Field({ + name: "Name", id: 0x2, type: "string", conformance: "O", constraint: "max 64", + details: "This field shall specify a name for the ScheduleStruct.", + xref: { document: "cluster", section: "4.3.8.31.3" } + }), + Field({ + name: "PresetHandle", id: 0x3, type: "octstr", conformance: "O", constraint: "max 16", + details: "This field shall indicate the default PresetHandle value for transitions in this schedule.", + xref: { document: "cluster", section: "4.3.8.31.4" } + }), + + Field( + { + name: "Transitions", id: 0x4, type: "list", conformance: "M", + constraint: "1 to numberOfScheduleTransitions", default: [], + + details: "This field shall specify a list of transitions for the schedule." + + "\n" + + "This field shall NOT contain more than one ScheduleStruct with the same TransitionTime field and " + + "overlapping DayOfWeek fields; i.e. there shall be no duplicate transitions." + + "\n" + + "If the NumberOfScheduleTransitionsPerDay attribute is not null, then for each bit in " + + "ScheduleDayOfWeekBitmap, the number of transitions with that bit set in DayOfWeek shall NOT be " + + "greater than the value of the NumberOfScheduleTransitionsPerDay attribute." + + "\n" + + "For the purposes of determining which ScheduleStruct in this list is currently active, the current " + + "time shall be the number of minutes past midnight in the display value of the current time, not the " + + "actual number of minutes that have elapsed since midnight. On days which transition into or out of " + + "daylight saving time, certain values may repeat or not occur during the transition period." + + "\n" + + "A ScheduleTransitionStruct in this list shall be active if the current day of the week matches its " + + "DayOfWeek field and the current time is greater than or equal to the TransitionTime, but less than " + + "the TransitionTime on any other ScheduleTransitionStruct in the Transitions field whose DayOfWeek " + + "field also matches the current day of the week." + + "\n" + + "If the current time is less than every ScheduleTransitionStruct whose DayOfWeek field also matches " + + "the current day of the week, the server shall attempt the same process to identify the active " + + "ScheduleTransitionStruct for the day preceding the previously attempted day of the week, repeating " + + "until an active ScheduleTransitionStruct is found or the attempted day is the current day of the " + + "week again. If no active ScheduleTransitionStruct is found, then the active " + + "ScheduleTransitionStruct shall be the ScheduleTransitionStruct with the largest TransitionTime " + + "field from the set of ScheduleTransitionStructs whose DayOfWeek field matches the current day of " + + "the week.", + + xref: { document: "cluster", section: "4.3.8.31.5" } + }, + + Field({ name: "entry", type: "ScheduleTransitionStruct" }) + ), + + Field({ + name: "BuiltIn", id: 0x5, type: "bool", conformance: "M", default: false, quality: "X", + details: "This field shall indicate whether the schedule is marked as \"built-in\", meaning that it can be " + + "modified, but it cannot be deleted.", + xref: { document: "cluster", section: "4.3.8.31.6" } + }) + ), + + Datatype( + { + name: "ScheduleTransitionStruct", type: "struct", + + details: "This struct provides a time of day and a set of days of the week for a state transition within a " + + "schedule. The thermostat shall use the following order of precedence for determining a new setpoint " + + "at the time of transition:" + + "\n" + + " 1. If the PresetHandle field is provided, then the setpoint for the PresetStruct in the Presets " + + " attribute with that identifier shall be used" + + "\n" + + " 2. If either the HeatingSetpoint or CoolingSetpoint is provided, then it shall be used" + + "\n" + + " a. If the SystemMode field is provided, the HeatingSetpoint and CoolingSetpoint fields shall be " + + " interpreted using the SystemMode field" + + "\n" + + " b. If the SystemMode field is not provided, the HeatingSetpoint and CoolingSetpoint fields " + + " shall be interpreted using the SystemMode field on the parent ScheduleStruct" + + "\n" + + " 3. If neither the PresetHandle field or any Setpoint field is provided, then the PresetHandle " + + " field on the parent ScheduleStruct shall be used to determine the active PresetStruct" + + "\n" + + " 4. If the PresetHandle is not indicated and no setpoint is provided for the current SystemMode, " + + " the server shall use a default value for the current SystemMode." + + "\n" + + "If the setpoint was derived from a preset, then the ActivePresetHandle shall be set to the " + + "PresetHandle of that preset." + + "\n" + + "If a CoolingSetpoint was used to determine the cooling setpoint:" + + "\n" + + " • If the server supports the OCC feature, and the Occupied bit is not set on the Occupancy " + + " attribute, then the UnoccupiedCoolingSetpoint attribute shall be set to the CoolingSetpoint" + + "\n" + + " • Otherwise, the OccupiedCoolingSetpoint attribute shall be set to the CoolingSetpoint If a " + + " HeatingSetpoint was used to determine the heating setpoint:" + + "\n" + + " • If the server supports the OCC feature, and the Occupied bit is not set on the Occupancy " + + " attribute, then the UnoccupiedHeatingSetpoint attribute shall be set to the HeatingSetpoint" + + "\n" + + " • Otherwise, the OccupiedHeatingSetpoint attribute shall be set to the HeatingSetpoint The " + + " ScheduleTransitionStruct shall be invalid if all the following are true:" + + "\n" + + " • The HeatingSetpoint field is not provided" + + "\n" + + " • The PresetHandle field is not provided" + + "\n" + + " • The PresetHandle field on the encompassing ScheduleStruct is not provided" + + "\n" + + " • The SystemMode field is provided and has the value Heat or Auto, or the SystemMode field on the " + + " parent ScheduleStruct has the value Heat or Auto" + + "\n" + + "The ScheduleTransitionStruct shall be invalid if all the following are true:" + + "\n" + + " • The CoolingSetpoint field is not provided" + + "\n" + + " • The PresetHandle field is not provided" + + "\n" + + " • The PresetHandle field on the encompassing ScheduleStruct is not provided" + + "\n" + + " • The SystemMode field is provided and has the value Cool or Auto, or the SystemMode field on the " + + " parent ScheduleStruct has the value Cool or Auto", + + xref: { document: "cluster", section: "4.3.8.32" } + }, + + Field({ + name: "DayOfWeek", id: 0x0, type: "ScheduleDayOfWeekBitmap", conformance: "M", constraint: "desc", + details: "This field shall specify a bitmask of days of the week that the transition applies to. The Vacation " + + "bit shall NOT be set; vacation schedules shall be set via the vacation preset.", + xref: { document: "cluster", section: "4.3.8.32.1" } + }), + + Field({ + name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", constraint: "max 1439", + details: "This shall specify the time of day at which the transition becomes active, in terms of minutes " + + "within the day representing the wall clock, where 0 is 00:00:00, 1 is 00:01:00 and 1439 is 23:59:00." + + "\n" + + "Handling of transitions during the changeover of Daylight Saving Time is implementation-dependent.", + xref: { document: "cluster", section: "4.3.8.32.2" } + }), + + Field({ + name: "PresetHandle", id: 0x2, type: "octstr", conformance: "[PRES]", constraint: "max 16", + details: "This field shall specify the preset used at the TransitionTime. If this field is provided, then the " + + "SystemMode, CoolingSetpoint and HeatingSetpoint fields shall NOT be provided.", + xref: { document: "cluster", section: "4.3.8.32.3" } + }), + + Field({ + name: "SystemMode", id: 0x3, type: "SystemModeEnum", conformance: "O", constraint: "desc", + details: "This shall specify the default mode to which the thermostat will switch for this transition, " + + "overriding the default for the schedule. The only valid values for this field shall be Auto, Heat, " + + "Cool and Off. This field shall only be included when the required system mode differs from the " + + "schedule’s default SystemMode.", + xref: { document: "cluster", section: "4.3.8.32.4" } + }), + + Field({ + name: "CoolingSetpoint", id: 0x4, type: "temperature", conformance: "[COOL]", constraint: "desc", + details: "This field shall specify the cooling setpoint for the transition. If PresetHandle is set, this " + + "field shall NOT be included. Refer to Setpoint Limits for value constraints.", + xref: { document: "cluster", section: "4.3.8.32.5" } + }), + + Field({ + name: "HeatingSetpoint", id: 0x5, type: "temperature", conformance: "[HEAT]", constraint: "desc", + details: "This field shall specify the cooling setpoint for the transition. If PresetHandle is set, this " + + "field shall NOT be included. Refer to Setpoint Limits for value constraints.", + xref: { document: "cluster", section: "4.3.8.32.6" } + }) + ), + + Datatype( + { name: "ScheduleTypeStruct", type: "struct", xref: { document: "cluster", section: "4.3.8.33" } }, + + Field({ + name: "SystemMode", id: 0x0, type: "SystemModeEnum", conformance: "M", constraint: "desc", + details: "This field shall specify a SystemModeEnum supported by this thermostat for Schedules. The only " + + "valid values for this field shall be Auto, Heat, and Cool.", + xref: { document: "cluster", section: "4.3.8.33.1" } + }), + + Field({ + name: "NumberOfSchedules", id: 0x1, type: "uint8", conformance: "M", + constraint: "max numberOfSchedules", default: 0, + details: "This field shall specify a limit for the number of Schedules for this SystemMode.", + xref: { document: "cluster", section: "4.3.8.33.2" } + }), + + Field({ + name: "ScheduleTypeFeatures", id: 0x2, type: "ScheduleTypeFeaturesBitmap", conformance: "M", + constraint: "desc", default: 0, + details: "This field shall specify a bitmap of features for this schedule entry. At least one of " + + "SupportsPresets and SupportsSetpoints shall be set.", + xref: { document: "cluster", section: "4.3.8.33.3" } + }) + ) + ), + + Cluster( + { + name: "FanControl", id: 0x202, classification: "application", pics: "FAN", + details: "This cluster specifies an interface to control the speed of a fan.", + xref: { document: "cluster", section: "4.4" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "4.4.4" } }, + + Field({ + name: "SPD", constraint: "0", description: "MultiSpeed", + + details: "Legacy Fan Control cluster revision 0-1 defined 3 speeds (low, medium and high) plus automatic " + + "speed control but left it up to the implementer to decide what was supported. Therefore, it is " + + "assumed that legacy client implementations are capable of determining, from the server, the number " + + "of speeds supported between 1, 2, or 3, and whether automatic speed control is supported." + + "\n" + + "The MultiSpeed feature includes new attributes that support a running fan speed value from 0 to " + + "SpeedMax, which has a maximum of 100." + + "\n" + + "See Section 4.4.6.6.1 for more details.", + + xref: { document: "cluster", section: "4.4.4.1" } + }), + + Field({ name: "AUT", constraint: "1", description: "Auto", details: "Automatic mode supported for fan speed" }), + Field({ name: "RCK", constraint: "2", description: "Rocking", details: "Rocking movement supported" }), + Field({ name: "WND", constraint: "3", description: "Wind", details: "Wind emulation supported" }), + Field({ name: "STEP", constraint: "4", description: "Step", details: "Step command supported" }), + Field({ + name: "DIR", constraint: "5", description: "AirflowDirection", + details: "Airflow Direction attribute is supported" + }) + ), + + Attribute({ + name: "FanMode", id: 0x0, type: "FanModeEnum", access: "RW VO", conformance: "M", default: 0, + quality: "N", + + details: "Indicates the current speed mode of the fan. This attribute may be written by the client to request " + + "a different fan mode. A server shall return INVALID_IN_STATE to indicate that the fan is not in a " + + "state where the FanMode can be changed to the requested value. A server may have FanMode values " + + "that it can never be set to. For example, where this cluster appears on the same or another " + + "endpoint as other clusters with a system dependency, for example the Thermostat cluster, attempting " + + "to set the FanMode attribute of this cluster to Off may not be allowed by the system." + + "\n" + + "This attribute shall be set to one of the values in FanModeEnum." + + "\n" + + "When the FanMode attribute is successfully written to, the PercentSetting and SpeedSetting (if " + + "present) attributes shall be set to appropriate values, as defined by the Section 4.4.6.3.1 and " + + "Section 4.4.6.6.1 respectively, unless otherwise specified below." + + "\n" + + "When the FanMode attribute is set to any given mode, the PercentCurrent and SpeedCurrent (if " + + "present) shall indicate the actual currently operating fan speed, unless otherwise specified below.", + + xref: { document: "cluster", section: "4.4.6.1" } + }), + + Attribute({ + name: "FanModeSequence", id: 0x1, type: "FanModeSequenceEnum", access: "R V", conformance: "M", + quality: "F", + details: "This attribute indicates the fan speed ranges that shall be supported.", + xref: { document: "cluster", section: "4.4.6.2" } + }), + + Attribute({ + name: "PercentSetting", id: 0x2, type: "percent", access: "RW VO", conformance: "M", + constraint: "max 100", default: 0, quality: "X", + + details: "Indicates the speed setting for the fan. This attribute may be written by the client to indicate a " + + "new fan speed. If the client writes null to this attribute, the attribute value shall NOT change. A " + + "server shall return INVALID_IN_STATE to indicate that the fan is not in a state where the " + + "PercentSetting can be changed to the requested value." + + "\n" + + "If this is successfully written to 0, the server shall set the FanMode attribute value to Off.", + + xref: { document: "cluster", section: "4.4.6.3" } + }), + + Attribute({ + name: "PercentCurrent", id: 0x3, type: "percent", access: "R V", conformance: "M", + constraint: "max 100", + details: "Indicates the actual currently operating fan speed, or zero to indicate that the fan is off. There " + + "may be a temporary mismatch between the value of this attribute and the value of the PercentSetting " + + "attribute due to other system requirements that would not allow the fan to operate at the requested " + + "setting. See Section 4.4.6.3.1 for more details.", + xref: { document: "cluster", section: "4.4.6.4" } + }), + + Attribute({ + name: "SpeedMax", id: 0x4, type: "uint8", access: "R V", conformance: "SPD", constraint: "1 to 100", + quality: "F", + details: "Indicates that the fan has one speed (value of 1) or the maximum speed, if the fan is capable of " + + "multiple speeds.", + xref: { document: "cluster", section: "4.4.6.5" } + }), + + Attribute({ + name: "SpeedSetting", id: 0x5, type: "uint8", access: "RW VO", conformance: "SPD", + constraint: "max speedMax", default: 0, quality: "X", + + details: "Indicates the speed setting for the fan. This attribute may be written by the client to indicate a " + + "new fan speed. If the client writes null to this attribute, the attribute value shall NOT change. A " + + "server shall return INVALID_IN_STATE to indicate that the fan is not in a state where the " + + "SpeedSetting can be changed to the requested value." + + "\n" + + "If this is successfully written to 0, the server shall set the FanMode attribute value to Off. " + + "Please see the Section 4.4.6.6.1 for details on other values.", + + xref: { document: "cluster", section: "4.4.6.6" } + }), + + Attribute({ + name: "SpeedCurrent", id: 0x6, type: "uint8", access: "R V", conformance: "SPD", + constraint: "max speedMax", quality: "P", + details: "Indicates the actual currently operating fan speed, or zero to indicate that the fan is off. There " + + "may be a temporary mismatch between the value of this attribute and the value of the SpeedSetting " + + "attribute due to other system requirements that would not allow the fan to operate at the requested " + + "setting.", + xref: { document: "cluster", section: "4.4.6.7" } + }), + + Attribute({ + name: "RockSupport", id: 0x7, type: "RockBitmap", access: "R V", conformance: "RCK", + constraint: "desc", default: 0, quality: "F", + details: "This attribute is a bitmap that indicates what rocking motions the server supports.", + xref: { document: "cluster", section: "4.4.6.8" } + }), + + Attribute({ + name: "RockSetting", id: 0x8, type: "RockBitmap", access: "RW VO", conformance: "RCK", + constraint: "desc", default: 0, quality: "P", + + details: "This attribute is a bitmap that indicates the current active fan rocking motion settings. Each bit " + + "shall only be set to 1, if the corresponding bit in the RockSupport attribute is set to 1, " + + "otherwise a status code of CONSTRAINT_ERROR shall be returned." + + "\n" + + "If a combination of supported bits is set by the client, and the server does not support the " + + "combination, the lowest supported single bit in the combination shall be set and active, and all " + + "other bits shall indicate zero." + + "\n" + + "For example: If RockUpDown and RockRound are both set, but this combination is not possible, then " + + "only RockUpDown becomes active.", + + xref: { document: "cluster", section: "4.4.6.9" } + }), + + Attribute({ + name: "WindSupport", id: 0x9, type: "WindBitmap", access: "R V", conformance: "WND", + constraint: "desc", default: 0, quality: "F", + details: "This attribute is a bitmap that indicates what wind modes the server supports. At least one wind " + + "mode bit shall be set.", + xref: { document: "cluster", section: "4.4.6.10" } + }), + + Attribute({ + name: "WindSetting", id: 0xa, type: "WindBitmap", access: "RW VO", conformance: "WND", + constraint: "desc", default: 0, quality: "P", + + details: "This attribute is a bitmap that indicates the current active fan wind feature settings. Each bit " + + "shall only be set to 1, if the corresponding bit in the WindSupport attribute is set to 1, " + + "otherwise a status code of CONSTRAINT_ERROR shall be returned." + + "\n" + + "If a combination of supported bits is set by the client, and the server does not support the " + + "combination, the lowest supported single bit in the combination shall be set and active, and all " + + "other bits shall indicate zero." + + "\n" + + "For example: If Sleep Wind and Natural Wind are set, but this combination is not possible, then " + + "only Sleep Wind becomes active.", + + xref: { document: "cluster", section: "4.4.6.11" } + }), + + Attribute({ + name: "AirflowDirection", id: 0xb, type: "AirflowDirectionEnum", access: "RW VO", + conformance: "DIR", constraint: "desc", default: 0, quality: "P", + details: "Indicates the current airflow direction of the fan. This attribute may be written by the client to " + + "indicate a new airflow direction for the fan. This attribute shall be set to one of the values in " + + "the AirflowDirectionEnum table.", + xref: { document: "cluster", section: "4.4.6.12" } + }), + + Command( + { + name: "Step", id: 0x0, access: "O", conformance: "STEP", direction: "request", response: "status", + + details: "This command speeds up or slows down the fan, in steps, without the client having to know the fan " + + "speed. This command supports, for example, a user operated wall switch, where the user provides the " + + "feedback or control to stop sending this command when the proper speed is reached. The step speed " + + "values are implementation specific. How many step speeds are implemented is implementation specific." + + "\n" + + "This command supports these fields:", + + xref: { document: "cluster", section: "4.4.7.1" } + }, + + Field({ + name: "Direction", id: 0x0, type: "StepDirectionEnum", conformance: "M", default: 0, + details: "This field shall indicate whether the fan speed increases or decreases to the next step value.", + xref: { document: "cluster", section: "4.4.7.1.1" } + }), + Field({ + name: "Wrap", id: 0x1, type: "bool", conformance: "O", default: false, + details: "This field shall indicate if the fan speed wraps between highest and lowest step value.", + xref: { document: "cluster", section: "4.4.7.1.2" } + }), + Field({ + name: "LowestOff", id: 0x2, type: "bool", conformance: "O", default: true, + details: "This field shall indicate that the fan being off (speed value 0) is included as a step value.", + xref: { document: "cluster", section: "4.4.7.1.3" } + }) + ), + + Datatype( + { name: "RockBitmap", type: "map8", xref: { document: "cluster", section: "4.4.5.1" } }, + Field({ name: "RockLeftRight", constraint: "0", description: "Indicate rock left to right" }), + Field({ name: "RockUpDown", constraint: "1", description: "Indicate rock up and down" }), + Field({ name: "RockRound", constraint: "2", description: "Indicate rock around" }) + ), + + Datatype( + { name: "WindBitmap", type: "map8", xref: { document: "cluster", section: "4.4.5.2" } }, + Field({ name: "SleepWind", constraint: "0", description: "Indicate sleep wind" }), + Field({ name: "NaturalWind", constraint: "1", description: "Indicate natural wind" }) + ), + Datatype( + { name: "StepDirectionEnum", type: "enum8", xref: { document: "cluster", section: "4.4.5.3" } }, + Field({ name: "Increase", id: 0x0, conformance: "M", description: "Step moves in increasing direction" }), + Field({ name: "Decrease", id: 0x1, conformance: "M", description: "Step moves in decreasing direction" }) + ), + Datatype( + { name: "AirflowDirectionEnum", type: "enum8", xref: { document: "cluster", section: "4.4.5.4" } }, + Field({ name: "Forward", id: 0x0, conformance: "M", description: "Airflow is in the forward direction" }), + Field({ name: "Reverse", id: 0x1, conformance: "M", description: "Airflow is in the reverse direction" }) + ), + + Datatype( + { name: "FanModeEnum", type: "enum8", xref: { document: "cluster", section: "4.4.5.5" } }, + Field({ name: "Off", id: 0x0, conformance: "M", description: "Fan is off" }), + + Field({ + name: "Low", id: 0x1, conformance: "desc", description: "Fan using low speed", + details: "If the fan supports 2 or more speeds, the Low value shall be supported." + + "\n" + + "The Low value shall be supported if and only if the FanModeSequence attribute value is less than 4.", + xref: { document: "cluster", section: "4.4.5.5.1" } + }), + + Field({ + name: "Medium", id: 0x2, conformance: "desc", description: "Fan using medium speed", + details: "If the fan supports 3 or more speeds, the Medium value shall be supported." + + "\n" + + "The Medium value shall be supported if and only if the FanModeSequence attribute value is 0 or 2.", + xref: { document: "cluster", section: "4.4.5.5.2" } + }), + + Field({ name: "High", id: 0x3, conformance: "M", description: "Fan using high speed" }), + Field({ name: "On", id: 0x4, conformance: "D" }), + Field({ name: "Auto", id: 0x5, conformance: "AUT", description: "Fan is using auto mode" }), + Field({ name: "Smart", id: 0x6, conformance: "D", description: "Fan is using smart mode" }) + ), + + Datatype( + { name: "FanModeSequenceEnum", type: "enum8", xref: { document: "cluster", section: "4.4.5.6" } }, + Field({ + name: "OffLowMedHigh", id: 0x0, conformance: "[!AUT].a", + description: "Fan is capable of off, low, medium and high modes" + }), + Field({ + name: "OffLowHigh", id: 0x1, conformance: "[!AUT].a", + description: "Fan is capable of off, low and high modes" + }), + Field({ + name: "OffLowMedHighAuto", id: 0x2, conformance: "[AUT].a", + description: "Fan is capable of off, low, medium, high and auto modes" + }), + Field({ + name: "OffLowHighAuto", id: 0x3, conformance: "[AUT].a", + description: "Fan is capable of off, low, high and auto modes" + }), + Field({ + name: "OffHighAuto", id: 0x4, conformance: "[AUT].a", + description: "Fan is capable of off, high and auto modes" + }), + Field({ name: "OffHigh", id: 0x5, conformance: "[!AUT].a", description: "Fan is capable of off and high modes" }) + ) + ), + + Cluster( + { + name: "ThermostatUserInterfaceConfiguration", id: 0x204, classification: "application", + pics: "TSUIC", + details: "This cluster provides an interface to allow configuration of the user interface for a thermostat, " + + "or a thermostat controller device, that supports a keypad and LCD screen.", + xref: { document: "cluster", section: "4.5" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute({ + name: "TemperatureDisplayMode", id: 0x0, type: "TemperatureDisplayModeEnum", access: "RW VO", + conformance: "M", default: 0, + details: "Indicates the units of the temperature displayed on the thermostat screen.", + xref: { document: "cluster", section: "4.5.6.1" } + }), + + Attribute({ + name: "KeypadLockout", id: 0x1, type: "KeypadLockoutEnum", access: "RW VM", conformance: "M", + default: 0, + details: "Indicates the level of functionality that is available to the user via the keypad.", + xref: { document: "cluster", section: "4.5.6.2" } + }), + + Attribute({ + name: "ScheduleProgrammingVisibility", id: 0x2, type: "ScheduleProgrammingVisibilityEnum", + access: "RW VM", conformance: "O", default: 0, + + details: "This attribute is used to hide the weekly schedule programming functionality or menu on a " + + "thermostat from a user to prevent local user programming of the weekly schedule. The schedule " + + "programming may still be performed via a remote interface, and the thermostat may operate in " + + "schedule programming mode." + + "\n" + + "This attribute is designed to prevent local tampering with or disabling of schedules that may have " + + "been programmed by users or service providers via a more capable remote interface. The programming " + + "schedule shall continue to run even though it is not visible to the user locally at the thermostat.", + + xref: { document: "cluster", section: "4.5.6.3" } + }), + + Datatype( + { name: "TemperatureDisplayModeEnum", type: "enum8", xref: { document: "cluster", section: "4.5.5.1" } }, + Field({ name: "Celsius", id: 0x0, conformance: "M", description: "Temperature displayed in °C" }), + Field({ name: "Fahrenheit", id: 0x1, conformance: "M", description: "Temperature displayed in °F" }) + ), + + Datatype( + { + name: "KeypadLockoutEnum", type: "enum8", + details: "The interpretation of the various levels is device-dependent.", + xref: { document: "cluster", section: "4.5.5.2" } + }, + Field({ name: "NoLockout", id: 0x0, conformance: "M", description: "All functionality available to the user" }), + Field({ name: "Lockout1", id: 0x1, conformance: "M", description: "Level 1 reduced functionality" }), + Field({ name: "Lockout2", id: 0x2, conformance: "M", description: "Level 2 reduced functionality" }), + Field({ name: "Lockout3", id: 0x3, conformance: "M", description: "Level 3 reduced functionality" }), + Field({ name: "Lockout4", id: 0x4, conformance: "M", description: "Level 4 reduced functionality" }), + Field({ name: "Lockout5", id: 0x5, conformance: "M", description: "Least functionality available to the user" }) + ), + + Datatype( + { + name: "ScheduleProgrammingVisibilityEnum", type: "enum8", + xref: { document: "cluster", section: "4.5.5.3" } + }, + Field({ + name: "ScheduleProgrammingPermitted", id: 0x0, conformance: "M", + description: "Local schedule programming functionality is enabled at the thermostat" + }), + Field({ + name: "ScheduleProgrammingDenied", id: 0x1, conformance: "M", + description: "Local schedule programming functionality is disabled at the thermostat" + }) + ) + ), + + Cluster( + { + name: "ValveConfigurationAndControl", id: 0x81, classification: "application", pics: "VALCC", + details: "This cluster is used to configure a valve.", + xref: { document: "cluster", section: "4.6" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "4.6.4" } }, + + Field({ + name: "TS", conformance: "desc", constraint: "0", description: "TimeSync", + details: "This feature shall indicate that the valve uses Time Synchronization and UTC time to indicate " + + "duration and auto close time." + + "\n" + + "This feature shall NOT be supported unless the device supports the Time Synchronization cluster.", + xref: { document: "cluster", section: "4.6.4.1" } + }), + + Field({ + name: "LVL", conformance: "O", constraint: "1", description: "Level", + details: "This feature shall indicate that the valve is capable of being adjusted to a specific position, as " + + "a percentage, of its full range of motion.", + xref: { document: "cluster", section: "4.6.4.2" } + }) + ), + + Attribute({ + name: "OpenDuration", id: 0x0, type: "elapsed-s", access: "R V", conformance: "M", + constraint: "min 1", default: null, quality: "X", + details: "Indicates the total duration, in seconds, for which the valve will remain open for this current " + + "opening." + + "\n" + + "A value of null shall indicate the duration is not set, meaning that the valve will remain open " + + "until closed by the user or some other automation.", + xref: { document: "cluster", section: "4.6.7.1" } + }), + + Attribute({ + name: "DefaultOpenDuration", id: 0x1, type: "elapsed-s", access: "RW VO", conformance: "M", + constraint: "min 1", default: null, quality: "X N", + details: "Indicates the default duration, in seconds, for which the valve will remain open, if the " + + "OpenDuration field is not present in the Open command." + + "\n" + + "A value of null shall indicate the duration is not set, meaning that the valve will remain open " + + "until closed by the user or some other automation.", + xref: { document: "cluster", section: "4.6.7.2" } + }), + + Attribute({ + name: "AutoCloseTime", id: 0x2, type: "epoch-us", access: "R V", conformance: "TS", default: null, + quality: "X", + + details: "Indicates the UTC time when the valve will close, depending on value of the OpenDuration attribute." + + "\n" + + "Null:" + + "\n" + + " • When OpenDuration is null, or" + + "\n" + + " • When the valve does not have a synchronized UTCTime in the Time Synchronization cluster, or" + + "\n" + + " • When the valve is closed." + + "\n" + + "When the value of this attribute is earlier or equal to the current UTC time, the valve shall " + + "automatically transition to its closed position. The behavior of transitioning to the closed " + + "position, shall match the behavior described in the Close command." + + "\n" + + "If this attribute is not null and the Time Synchronization cluster receives a SetUTCTime command, " + + "modifying the current UTC time of the device, the value of this attribute shall be adjusted to " + + "match the new UTC time plus the value of the RemainingDuration attribute.", + + xref: { document: "cluster", section: "4.6.7.3" } + }), + + Attribute({ + name: "RemainingDuration", id: 0x3, type: "elapsed-s", access: "R V", conformance: "M", + default: null, quality: "X Q", + + details: "Indicates the remaining duration, in seconds, until the valve closes. Null:" + + "\n" + + " • When OpenDuration is null, or" + + "\n" + + " • When the valve is closed." + + "\n" + + "The value of this attribute shall only be reported in the following cases:" + + "\n" + + " • When it changes from null to any other value and vice versa, or" + + "\n" + + " • When it changes to 0, or" + + "\n" + + " • When it increases, or" + + "\n" + + " • When the closing time changes." + + "\n" + + "Meaning that clients SHOULD NOT rely on the reporting of this attribute in order to keep track of " + + "the remaining duration, due to this attribute not being reported during regular countdown." + + "\n" + + "When reading this attribute it shall return the remaining duration, in seconds, until the valve " + + "closes." + + "\n" + + "When the value of this attribute counts down to 0, the valve shall automatically transition to its " + + "closed position. The behavior of transitioning to the closed position shall match the behavior " + + "described in the Close command.", + + xref: { document: "cluster", section: "4.6.7.4" } + }), + + Attribute({ + name: "CurrentState", id: 0x4, type: "ValveStateEnum", access: "R V", conformance: "M", + default: null, quality: "X", + details: "Indicates the current state of the valve." + + "\n" + + "A value of null shall indicate that the current state is not known.", + xref: { document: "cluster", section: "4.6.7.5" } + }), + + Attribute({ + name: "TargetState", id: 0x5, type: "ValveStateEnum", access: "R V", conformance: "M", + default: null, quality: "X", + details: "Indicates the target state, while changing the state, of the valve." + + "\n" + + "A value of null shall indicate that no target position is set, since the change in state is either " + + "done or failed.", + xref: { document: "cluster", section: "4.6.7.6" } + }), + + Attribute({ + name: "CurrentLevel", id: 0x6, type: "percent", access: "R V", conformance: "LVL", default: null, + quality: "X", + + details: "Indicates the current level of the valve as a percentage value, between fully closed and fully " + + "open. During a transition from one level to another level, the valve SHOULD keep this attribute " + + "updated to the best of its ability, in order to represent the actual level of the valve during the " + + "movement." + + "\n" + + "A value of 100 percent shall indicate the fully open position. A value of 0 percent shall indicate " + + "the fully closed position." + + "\n" + + "A value of null shall indicate that the current state is not known.", + + xref: { document: "cluster", section: "4.6.7.7" } + }), + + Attribute({ + name: "TargetLevel", id: 0x7, type: "percent", access: "R V", conformance: "LVL", default: null, + quality: "X", + + details: "Indicates the target level of the valve as a percentage value, between fully closed and fully open." + + "\n" + + "The interpretation of the percentage value is the same as for the CurrentLevel attribute." + + "\n" + + "A value of null shall indicate that no target position is set, since the change of level is either " + + "done or failed.", + + xref: { document: "cluster", section: "4.6.7.8" } + }), + + Attribute({ + name: "DefaultOpenLevel", id: 0x8, type: "percent", access: "RW VO", conformance: "[LVL]", + constraint: "1 to 100", default: 100, quality: "N", + + details: "Indicates the default value used for the TargetLevel attribute, when a valve transitions from the " + + "closed to the open state, caused by an Open command, if a TargetLevel field is not present in the " + + "Open command." + + "\n" + + "If the LevelStep attribute is present and the value of a write interaction to this attribute field " + + "is not 100, the value shall be a supported value as defined by the LevelStep attribute, such that " + + "(Value received in the write interaction) % (Value of LevelStep attribute) equals 0. If the " + + "resulting value is not 0, the requested DefaultOpenLevel value is considered an unsupported value " + + "and a CONSTRAINT_ERROR status shall be returned.", + + xref: { document: "cluster", section: "4.6.7.9" } + }), + + Attribute({ + name: "ValveFault", id: 0x9, type: "ValveFaultBitmap", access: "R V", conformance: "O", default: 0, + details: "Indicates any faults registered by the valve.", + xref: { document: "cluster", section: "4.6.7.10" } + }), + + Attribute({ + name: "LevelStep", id: 0xa, type: "uint8", access: "R V", conformance: "[LVL]", + constraint: "1 to 50", default: 1, quality: "F", + + details: "Indicates the step size the valve can support." + + "\n" + + "The step size defined by this attribute is counted from 0 and the final step towards 100 may be " + + "different than what is defined in this attribute. For example, if the value of this attribute is " + + "15, it results in these target values being supported; 0, 15, 30, 45, 60, 75, 90 and 100." + + "\n" + + "The values of 0 and 100 shall always be supported, regardless of the value of this attribute.", + + xref: { document: "cluster", section: "4.6.7.11" } + }), + + Event( + { + name: "ValveStateChanged", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "This event shall be generated when the valve state changed. For level changes, after the end of " + + "movement, for state changes when the new state has been reached.", + xref: { document: "cluster", section: "4.6.9.1" } + }, + + Field({ + name: "ValveState", id: 0x0, type: "ValveStateEnum", conformance: "M", + details: "This field shall indicate the new state of the valve.", + xref: { document: "cluster", section: "4.6.9.1.1" } + }), + Field({ + name: "ValveLevel", id: 0x1, type: "percent", conformance: "LVL", + details: "This field shall indicate the new level of the valve.", + xref: { document: "cluster", section: "4.6.9.1.2" } + }) + ), + + Event( + { + name: "ValveFault", id: 0x1, access: "V", conformance: "O", priority: "info", + details: "This event shall be generated when the valve registers or clears a fault, e.g. not being able to " + + "transition to the requested target level or state.", + xref: { document: "cluster", section: "4.6.9.2" } + }, + + Field({ + name: "ValveFault", id: 0x0, type: "ValveFaultBitmap", conformance: "M", + details: "This field shall indicate the value of the ValveFault attribute, at the time this event is " + + "generated.", + xref: { document: "cluster", section: "4.6.9.2.1" } + }) + ), + + Command( + { + name: "Open", id: 0x0, access: "O", conformance: "M", direction: "request", response: "status", + details: "This command is used to set the valve to its open position.", + xref: { document: "cluster", section: "4.6.8.1" } + }, + + Field({ + name: "OpenDuration", id: 0x0, type: "elapsed-s", conformance: "O", constraint: "min 1", + quality: "X", + details: "This field shall indicate the duration that the valve will remain open for this specific Open " + + "command." + + "\n" + + "A value of null shall indicate the duration is not set, meaning that the valve will remain open " + + "until closed by the user or some other automation.", + xref: { document: "cluster", section: "4.6.8.1.1" } + }), + + Field({ + name: "TargetLevel", id: 0x1, type: "percent", conformance: "[LVL]", constraint: "min 1", + details: "This field shall indicate the target level used for this specific Open command.", + xref: { document: "cluster", section: "4.6.8.1.2" } + }) + ), + + Command({ + name: "Close", id: 0x1, access: "O", conformance: "M", direction: "request", response: "status", + details: "This command is used to set the valve to its closed position.", + xref: { document: "cluster", section: "4.6.8.2" } + }), + + Datatype( + { name: "ValveFaultBitmap", type: "map16", xref: { document: "cluster", section: "4.6.5.1" } }, + Field({ name: "GeneralFault", constraint: "0", description: "Unspecified fault detected" }), + Field({ name: "Blocked", constraint: "1", description: "Valve is blocked" }), + Field({ name: "Leaking", constraint: "2", description: "Valve has detected a leak" }), + Field({ name: "NotConnected", constraint: "3", description: "No valve is connected to controller" }), + Field({ name: "ShortCircuit", constraint: "4", description: "Short circuit is detected" }), + Field({ name: "CurrentExceeded", constraint: "5", description: "The available current has been exceeded" }) + ), + + Datatype( + { name: "ValveStateEnum", type: "enum8", xref: { document: "cluster", section: "4.6.5.2" } }, + Field({ name: "Closed", id: 0x0, conformance: "M", description: "Valve is in closed position" }), + Field({ name: "Open", id: 0x1, conformance: "M", description: "Valve is in open position" }), + Field({ + name: "Transitioning", id: 0x2, conformance: "M", + description: "Valve is transitioning between closed and open positions or between levels" + }) + ), + + Datatype( + { name: "StatusCodeEnum", type: "enum8", xref: { document: "cluster", section: "4.6.6.1" } }, + Field({ + name: "FailureDueToFault", id: 0x2, conformance: "M", + description: "The requested action could not be performed due to a fault on the valve." + }) + ) + ), + + Cluster( + { + name: "DoorLock", id: 0x101, classification: "application", pics: "DRLK", + details: "The door lock cluster provides an interface to a generic way to secure a door. The physical object " + + "that provides the locking functionality is abstracted from the cluster. The cluster has a small " + + "list of mandatory attributes and functions and a list of optional features." + + "\n" + + "Figure 16. Typical Usage of the Door Lock Cluster", + xref: { document: "cluster", section: "5.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 8 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "5.2.4" } }, + + Field({ + name: "PIN", conformance: "O", constraint: "0", description: "PinCredential", + + details: "If the User Feature is also supported then any PIN Code stored in the lock shall be associated with " + + "a User." + + "\n" + + "A lock may support multiple credential types so if the User feature is supported the UserType, " + + "UserStatus and Schedules are all associated with a User index and not directly with a PIN index. A " + + "User index may have several credentials associated with it.", + + xref: { document: "cluster", section: "5.2.4.1" } + }), + + Field({ + name: "RID", conformance: "O", constraint: "1", description: "RfidCredential", + + details: "If the User Feature is also supported then any RFID credential stored in the lock shall be " + + "associated with a User." + + "\n" + + "A lock may support multiple credential types so if the User feature is supported the UserType, " + + "UserStatus and Schedules are all associated with a User index and not directly with a RFID index. A " + + "User Index may have several credentials associated with it.", + + xref: { document: "cluster", section: "5.2.4.2" } + }), + + Field({ + name: "FGP", conformance: "P, O", constraint: "2", description: "FingerCredentials", + + details: "Currently the cluster only defines the metadata format for notifications when a fingerprint/ finger " + + "vein credential is used to access the lock and doesn’t describe how to create fingerprint/finger " + + "vein credentials. If the Users feature is also supported then the User that a fingerprint/finger " + + "vein is associated with can also have its UserType, UserStatus and Schedule modified." + + "\n" + + "A lock may support multiple credential types so if the User feature is supported the UserType, " + + "UserStatus and Schedules are all associated with a User index and not directly with a Finger index. " + + "A User Index may have several credentials associated with it.", + + xref: { document: "cluster", section: "5.2.4.3" } + }), + + Field({ + name: "WDSCH", conformance: "O", constraint: "4", description: "WeekDayAccessSchedules", + + details: "If the User feature is supported then Week Day Schedules are applied to a User and not a credential." + + "\n" + + "Week Day Schedules are used to restrict access to a specified time window on certain days of the " + + "week. The schedule is repeated each week." + + "\n" + + "The lock may automatically adjust the UserType when a schedule is created or cleared." + + "\n" + + "Support for WeekDayAccessSchedules requires that the lock has the capability of keeping track of " + + "local time.", + + xref: { document: "cluster", section: "5.2.4.4" } + }), + + Field({ + name: "DPS", conformance: "O", constraint: "5", description: "DoorPositionSensor", + details: "If this feature is supported this indicates that the lock has the ability to determine the position " + + "of the door which is separate from the state of the lock.", + xref: { document: "cluster", section: "5.2.4.5" } + }), + + Field({ + name: "FACE", conformance: "P, O", constraint: "6", description: "FaceCredentials", + + details: "Currently the cluster only defines the metadata format for notifications when a face recognition, " + + "iris, or retina credential is used to access the lock and doesn’t describe how to create face " + + "recognition, iris, or retina credentials. If the Users feature is also supported then the User that " + + "a face recognition, iris, or retina credential is associated with can also have its UserType, " + + "UserStatus and Schedule modified." + + "\n" + + "A lock may support multiple credential types so if the User feature is supported the UserType, " + + "UserStatus and Schedules are all associated with a User and not directly with a credential.", + + xref: { document: "cluster", section: "5.2.4.6" } + }), + + Field({ + name: "COTA", conformance: "O", constraint: "7", description: "CredentialOverTheAirAccess", + details: "If this feature is supported then the lock supports the ability to verify a credential provided in a" + + "\n" + + "lock/unlock command. Currently the cluster only supports providing the PIN credential to the " + + "lock/unlock commands. If this feature is supported then the PIN Credential feature shall also be " + + "supported.", + xref: { document: "cluster", section: "5.2.4.7" } + }), + + Field({ + name: "USR", conformance: "ALIRO, [PIN | RID | FGP | FACE]", constraint: "8", description: "User", + details: "If the User Feature is supported then a lock employs a User database. A User within the User " + + "database is used to associate credentials and schedules to single user record within the lock. This " + + "also means the UserType and UserStatus fields are associated with a User and not a credential.", + xref: { document: "cluster", section: "5.2.4.8" } + }), + + Field({ + name: "YDSCH", conformance: "O", constraint: "10", description: "YearDayAccessSchedules", + + details: "If the User feature is supported then Year Day Schedules are applied to a User and not a " + + "credential. Year Day Schedules are used to restrict access to a specified date and time window." + + "\n" + + "The lock may automatically adjust the UserType when a schedule is created or cleared." + + "\n" + + "Support for YearDayAccessSchedules requires that the lock has the capability of keeping track of " + + "local time.", + + xref: { document: "cluster", section: "5.2.4.9" } + }), + + Field({ + name: "HDSCH", conformance: "O", constraint: "11", description: "HolidaySchedules", + details: "This feature is used to setup Holiday Schedule in the lock device. A Holiday Schedule sets a start " + + "and stop end date/time for the lock to use the specified operating mode set by the Holiday Schedule." + + "\n" + + "Support for HolidaySchedules requires that the lock has the capability of keeping track of local " + + "time.", + xref: { document: "cluster", section: "5.2.4.10" } + }), + + Field({ + name: "UBOLT", conformance: "O", constraint: "12", description: "Unbolting", + details: "Locks that support this feature differentiate between unbolting and unlocking. The Unbolt Door " + + "command retracts the bolt without pulling the latch. The Unlock Door command fully unlocks the door " + + "by retracting the bolt and briefly pulling the latch. While the latch is pulled, the lock state " + + "changes to Unlatched. Locks without unbolting support don’t differentiate between unbolting and " + + "unlocking and perform the same operation for both commands.", + xref: { document: "cluster", section: "5.2.4.11" } + }), + + Field({ + name: "ALIRO", conformance: "O", constraint: "13", description: "AliroProvisioning", + details: "Locks that support this feature implement the Aliro specification as defined in [Aliro] and support " + + "Matter as a method for provisioning Aliro credentials.", + xref: { document: "cluster", section: "5.2.4.12" } + }), + + Field({ + name: "ALBU", conformance: "[ALIRO]", constraint: "14", description: "AliroBleuwb", + details: "Locks that support this feature implement the Bluetooth LE + UWB Access Control Flow as defined in " + + "[Aliro].", + xref: { document: "cluster", section: "5.2.4.13" } + }) + ), + + Attribute({ + name: "LockState", id: 0x0, type: "LockStateEnum", access: "R V", conformance: "M", + constraint: "desc", quality: "X P", + + details: "This attribute may be NULL if the lock hardware does not currently know the status of the locking " + + "mechanism. For example, a lock may not know the LockState status after a power cycle until the " + + "first lock actuation is completed." + + "\n" + + "The Not Fully Locked value is used by a lock to indicate that the state of the lock is somewhere " + + "between Locked and Unlocked so it is only partially secured. For example, a deadbolt could be " + + "partially extended and not in a dead latched state.", + + xref: { document: "cluster", section: "5.2.9.1" } + }), + + Attribute({ + name: "LockType", id: 0x1, type: "LockTypeEnum", access: "R V", conformance: "M", + constraint: "desc", + details: "Indicates the type of door lock as defined in LockTypeEnum.", + xref: { document: "cluster", section: "5.2.9.2" } + }), + + Attribute({ + name: "ActuatorEnabled", id: 0x2, type: "bool", access: "R V", conformance: "M", + details: "Indicates if the lock is currently able to (Enabled) or not able to (Disabled) process remote Lock, " + + "Unlock, or Unlock with Timeout commands.", + xref: { document: "cluster", section: "5.2.9.3" } + }), + + Attribute({ + name: "DoorState", id: 0x3, type: "DoorStateEnum", access: "R V", conformance: "DPS", + constraint: "desc", quality: "X P", + details: "Indicates the current door state as defined in DoorStateEnum." + + "\n" + + "Null only if an internal error prevents the retrieval of the current door state.", + xref: { document: "cluster", section: "5.2.9.4" } + }), + + Attribute({ + name: "DoorOpenEvents", id: 0x4, type: "uint32", access: "RW VM", conformance: "[DPS]", + details: "This attribute shall hold the number of door open events that have occurred since it was last " + + "zeroed.", + xref: { document: "cluster", section: "5.2.9.5" } + }), + + Attribute({ + name: "DoorClosedEvents", id: 0x5, type: "uint32", access: "RW VM", conformance: "[DPS]", + details: "This attribute shall hold the number of door closed events that have occurred since it was last " + + "zeroed.", + xref: { document: "cluster", section: "5.2.9.6" } + }), + + Attribute({ + name: "OpenPeriod", id: 0x6, type: "uint16", access: "RW VM", conformance: "[DPS]", + details: "This attribute shall hold the number of minutes the door has been open since the last time it " + + "transitioned from closed to open.", + xref: { document: "cluster", section: "5.2.9.7" } + }), + + Attribute({ + name: "NumberOfTotalUsersSupported", id: 0x11, type: "uint16", access: "R V", conformance: "USR", + default: 0, quality: "F", + details: "Indicates the number of total users supported by the lock.", + xref: { document: "cluster", section: "5.2.9.8" } + }), + + Attribute({ + name: "NumberOfPinUsersSupported", id: 0x12, type: "uint16", access: "R V", conformance: "PIN", + default: 0, quality: "F", + details: "Indicates the number of PIN users supported.", + xref: { document: "cluster", section: "5.2.9.9" } + }), + + Attribute({ + name: "NumberOfRfidUsersSupported", id: 0x13, type: "uint16", access: "R V", conformance: "RID", + default: 0, quality: "F", + details: "Indicates the number of RFID users supported.", + xref: { document: "cluster", section: "5.2.9.10" } + }), + + Attribute({ + name: "NumberOfWeekDaySchedulesSupportedPerUser", id: 0x14, type: "uint8", access: "R V", + conformance: "WDSCH", constraint: "max 253", default: 0, quality: "F", + details: "Indicates the number of configurable week day schedule supported per user.", + xref: { document: "cluster", section: "5.2.9.11" } + }), + + Attribute({ + name: "NumberOfYearDaySchedulesSupportedPerUser", id: 0x15, type: "uint8", access: "R V", + conformance: "YDSCH", constraint: "max 253", default: 0, quality: "F", + details: "Indicates the number of configurable year day schedule supported per user.", + xref: { document: "cluster", section: "5.2.9.12" } + }), + + Attribute({ + name: "NumberOfHolidaySchedulesSupported", id: 0x16, type: "uint8", access: "R V", + conformance: "HDSCH", constraint: "max 253", default: 0, quality: "F", + details: "Indicates the number of holiday schedules supported for the entire door lock device.", + xref: { document: "cluster", section: "5.2.9.13" } + }), + + Attribute({ + name: "MaxPinCodeLength", id: 0x17, type: "uint8", access: "R V", conformance: "PIN", quality: "F", + details: "Indicates the maximum length in bytes of a PIN Code on this device.", + xref: { document: "cluster", section: "5.2.9.14" } + }), + Attribute({ + name: "MinPinCodeLength", id: 0x18, type: "uint8", access: "R V", conformance: "PIN", quality: "F", + details: "Indicates the minimum length in bytes of a PIN Code on this device.", + xref: { document: "cluster", section: "5.2.9.15" } + }), + + Attribute({ + name: "MaxRfidCodeLength", id: 0x19, type: "uint8", access: "R V", conformance: "RID", quality: "F", + details: "Indicates the maximum length in bytes of a RFID Code on this device. The value depends on the RFID " + + "code range specified by the manufacturer, if media anti-collision identifiers (UID) are used as " + + "RFID code, a value of 20 (equals 10 Byte ISO 14443A UID) is recommended.", + xref: { document: "cluster", section: "5.2.9.16" } + }), + + Attribute({ + name: "MinRfidCodeLength", id: 0x1a, type: "uint8", access: "R V", conformance: "RID", quality: "F", + details: "Indicates the minimum length in bytes of a RFID Code on this device. The value depends on the RFID " + + "code range specified by the manufacturer, if media anti-collision identifiers (UID) are used as " + + "RFID code, a value of 8 (equals 4 Byte ISO 14443A UID) is recommended.", + xref: { document: "cluster", section: "5.2.9.17" } + }), + + Attribute({ + name: "CredentialRulesSupport", id: 0x1b, type: "CredentialRulesBitmap", access: "R V", + conformance: "USR", default: 1, quality: "F", + details: "This attribute shall contain a bitmap with the bits set for the values of CredentialRuleEnum " + + "supported on this device.", + xref: { document: "cluster", section: "5.2.9.18" } + }), + + Attribute({ + name: "NumberOfCredentialsSupportedPerUser", id: 0x1c, type: "uint8", access: "R V", + conformance: "USR", default: 0, quality: "F", + + details: "Indicates the number of credentials that could be assigned for each user." + + "\n" + + "Depending on the value of NumberOfRFIDUsersSupported and NumberOfPINUsersSupported it may not be " + + "possible to assign that number of credentials for a user." + + "\n" + + "For example, if the device supports only PIN and RFID credential types, " + + "NumberOfCredentialsSupportedPerUser is set to 10, NumberOfPINUsersSupported is set to 5 and " + + "NumberOfRFIDUsersSupported is set to 3, it will not be possible to actually assign 10 credentials " + + "for a user because maximum number of credentials in the database is 8.", + + xref: { document: "cluster", section: "5.2.9.19" } + }), + + Attribute({ + name: "Language", id: 0x21, type: "string", access: "R[W] VM", conformance: "O", + constraint: "max 3", quality: "P", + details: "Indicates the language for the on-screen or audible user interface using a 2- byte language code " + + "from ISO-639-1.", + xref: { document: "cluster", section: "5.2.9.20" } + }), + + Attribute({ + name: "LedSettings", id: 0x22, type: "LEDSettingEnum", access: "R[W] VM", conformance: "O", + default: 0, quality: "P", + details: "Indicates the settings for the LED support, as defined by LEDSettingEnum.", + xref: { document: "cluster", section: "5.2.9.21" } + }), + + Attribute({ + name: "AutoRelockTime", id: 0x23, type: "uint32", access: "R[W] VM", conformance: "O", quality: "P", + details: "Indicates the number of seconds to wait after unlocking a lock before it automatically locks again. " + + "0=disabled. If set, unlock operations from any source will be timed. For one time unlock with " + + "timeout use the specific command.", + xref: { document: "cluster", section: "5.2.9.22" } + }), + + Attribute({ + name: "SoundVolume", id: 0x24, type: "SoundVolumeEnum", access: "R[W] VM", conformance: "O", + default: 0, quality: "P", + details: "Indicates the sound volume on a door lock as defined by SoundVolumeEnum.", + xref: { document: "cluster", section: "5.2.9.23" } + }), + + Attribute({ + name: "OperatingMode", id: 0x25, type: "OperatingModeEnum", access: "R[W] VM", conformance: "M", + constraint: "desc", default: 0, quality: "P", + details: "Indicates the current operating mode of the lock as defined in OperatingModeEnum.", + xref: { document: "cluster", section: "5.2.9.24" } + }), + + Attribute({ + name: "SupportedOperatingModes", id: 0x26, type: "OperatingModesBitmap", access: "R V", + conformance: "M", default: 65526, quality: "F", + details: "This attribute shall contain a bitmap with all operating bits of the OperatingMode attribute " + + "supported by the lock. All operating modes NOT supported by a lock shall be set to one. The value " + + "of the OperatingMode enumeration defines the related bit to be set.", + xref: { document: "cluster", section: "5.2.9.25" } + }), + + Attribute({ + name: "DefaultConfigurationRegister", id: 0x27, type: "ConfigurationRegisterBitmap", access: "R V", + conformance: "O", default: 0, quality: "P", + + details: "Indicates the default configurations as they are physically set on the device (example: hardware " + + "dip switch setting, etc…) and represents the default setting for some of the" + + "\n" + + "attributes within this cluster (for example: LED, Auto Lock, Sound Volume, and Operating Mode " + + "attributes)." + + "\n" + + "This is a read-only attribute and is intended to allow clients to determine what changes may need " + + "to be made without having to query all the included attributes. It may be beneficial for the " + + "clients to know what the device’s original settings were in the event that the device needs to be " + + "restored to factory default settings." + + "\n" + + "If the Client device would like to query and modify the door lock server’s operating settings, it " + + "SHOULD send read and write attribute requests to the specific attributes." + + "\n" + + "For example, the Sound Volume attribute default value is Silent Mode. However, it is possible that " + + "the current Sound Volume is High Volume. Therefore, if the client wants to query/modify the current " + + "Sound Volume setting on the server, the client SHOULD read/write to the Sound Volume attribute.", + + xref: { document: "cluster", section: "5.2.9.26" } + }), + + Attribute({ + name: "EnableLocalProgramming", id: 0x28, type: "bool", access: "R[W] VA", conformance: "O", + default: true, quality: "P", + details: "This attribute shall enable/disable local programming on the door lock of certain features (see " + + "LocalProgrammingFeatures attribute). If this value is set to TRUE then local programming is enabled " + + "on the door lock for all features. If it is set to FALSE then local programming is disabled on the " + + "door lock for those features whose bit is set to 0 in the LocalProgrammingFeatures attribute. Local " + + "programming shall be enabled by default.", + xref: { document: "cluster", section: "5.2.9.27" } + }), + + Attribute({ + name: "EnableOneTouchLocking", id: 0x29, type: "bool", access: "RW VM", conformance: "O", + default: true, quality: "P", + details: "This attribute shall enable/disable the ability to lock the door lock with a single touch on the " + + "door lock.", + xref: { document: "cluster", section: "5.2.9.28" } + }), + + Attribute({ + name: "EnableInsideStatusLed", id: 0x2a, type: "bool", access: "RW VM", conformance: "O", + default: true, quality: "P", + details: "This attribute shall enable/disable an inside LED that allows the user to see at a glance if the " + + "door is locked.", + xref: { document: "cluster", section: "5.2.9.29" } + }), + + Attribute({ + name: "EnablePrivacyModeButton", id: 0x2b, type: "bool", access: "RW VM", conformance: "O", + default: true, quality: "P", + details: "This attribute shall enable/disable a button inside the door that is used to put the lock into " + + "privacy mode. When the lock is in privacy mode it cannot be manipulated from the outside.", + xref: { document: "cluster", section: "5.2.9.30" } + }), + + Attribute({ + name: "LocalProgrammingFeatures", id: 0x2c, type: "LocalProgrammingFeaturesBitmap", + access: "R[W] VA", conformance: "O", default: 0, quality: "P", + + details: "Indicates the local programming features that will be disabled when EnableLocalProgramming " + + "attribute is set to False. If a door lock doesn’t support disabling one aspect of local programming " + + "it shall return CONSTRAINT_ERROR during a write operation of this attribute. If the " + + "EnableLocalProgramming attribute is set to True then all local programming features shall be " + + "enabled regardless of the bits set to 0 in this attribute." + + "\n" + + "The features that can be disabled from local programming are defined in " + + "LocalProgrammingFeaturesBitmap.", + + xref: { document: "cluster", section: "5.2.9.31" } + }), + + Attribute({ + name: "WrongCodeEntryLimit", id: 0x30, type: "uint8", access: "R[W] VA", conformance: "PIN | RID", + constraint: "1 to 255", quality: "P", + + details: "Indicates the number of incorrect Pin codes or RFID presentment attempts a user is allowed to enter " + + "before the lock will enter a lockout state. The value of this attribute is compared to all failing " + + "forms of credential presentation, including Pin codes used in an Unlock Command when " + + "RequirePINforRemoteOperation is set to true. Valid range is 1-255 incorrect attempts. The lockout " + + "state will be for the duration of UserCodeTemporaryDisableTime. If the attribute accepts writes and " + + "an attempt to write the value 0 is made, the device shall respond with CONSTRAINT_ERROR." + + "\n" + + "The lock may reset the counter used to track incorrect credential presentations as required by " + + "internal logic, environmental events, or other reasons. The lock shall reset the counter if a valid " + + "credential is presented.", + + xref: { document: "cluster", section: "5.2.9.32" } + }), + + Attribute({ + name: "UserCodeTemporaryDisableTime", id: 0x31, type: "uint8", access: "R[W] VA", + conformance: "PIN | RID", constraint: "1 to 255", quality: "P", + details: "Indicates the number of seconds that the lock shuts down following wrong code entry. Valid range is " + + "1-255 seconds. Device can shut down to lock user out for specified amount of time. (Makes it " + + "difficult to try and guess a PIN for the device.) If the attribute accepts writes and an attempt to " + + "write the attribute to 0 is made, the device shall respond with CONSTRAINT_ERROR.", + xref: { document: "cluster", section: "5.2.9.33" } + }), + + Attribute({ + name: "SendPinOverTheAir", id: 0x32, type: "bool", access: "R[W] VA", conformance: "[!USR & PIN]", + default: true, quality: "P", + + details: "Indicates the door locks ability to send PINs over the air. If the attribute is True it is ok for " + + "the door lock server to send PINs over the air. This attribute determines the behavior of the " + + "server’s TX operation. If it is false, then it is not ok for the device to send PIN in any messages " + + "over the air." + + "\n" + + "The PIN field within any door lock cluster message shall keep the first octet unchanged and" + + "\n" + + "masks the actual code by replacing with 0xFF. For example (PIN \"1234\" ): If the attribute value is " + + "True, 0x04 0x31 0x32 0x33 0x34 shall be used in the PIN field in any door lock cluster message " + + "payload. If the attribute value is False, 0x04 0xFF 0xFF 0xFF 0xFF shall be used.", + + xref: { document: "cluster", section: "5.2.9.34" } + }), + + Attribute({ + name: "RequirePiNforRemoteOperation", id: 0x33, type: "bool", access: "R[W] VA", + conformance: "COTA & PIN", default: true, quality: "P", + details: "Indicates if the door lock requires an optional PIN. If this attribute is set to True, the door " + + "lock server requires that an optional PINs be included in the payload of remote lock operation " + + "events like Lock, Unlock, Unlock with Timeout and Toggle in order to function.", + xref: { document: "cluster", section: "5.2.9.35" } + }), + + Attribute({ + name: "SecurityLevel", id: 0x34, access: "R V", conformance: "D", default: "0", + xref: { document: "cluster", section: "5.2.9" } + }), + + Attribute({ + name: "ExpiringUserTimeout", id: 0x35, type: "uint16", access: "R[W] VA", conformance: "[USR]", + constraint: "1 to 2880", quality: "P", + details: "Indicates the number of minutes a PIN, RFID, Fingerprint, or other credential associated with a " + + "user of type ExpiringUser shall remain valid after its first use before expiring. When the " + + "credential expires the UserStatus for the corresponding user record shall be set to " + + "OccupiedDisabled.", + xref: { document: "cluster", section: "5.2.9.36" } + }), + + Attribute({ + name: "AlarmMask", id: 0x40, type: "AlarmMaskBitmap", access: "RW VA", conformance: "O", + default: 65535, quality: "P", + + details: "This attribute is only supported if the Alarms cluster is on the same endpoint. The alarm mask is " + + "used to turn on/off alarms for particular functions. Alarms for an alarm group are enabled if the " + + "associated alarm mask bit is set. Each bit represents a group of alarms. Entire alarm groups can be " + + "turned on or off by setting or clearing the associated bit in the alarm mask." + + "\n" + + "This mask DOES NOT apply to the Events mechanism of this cluster.", + + xref: { document: "cluster", section: "5.2.9.37" } + }), + + Attribute({ + name: "AliroReaderVerificationKey", id: 0x80, type: "octstr", access: "R A", conformance: "ALIRO", + constraint: "65", default: null, quality: "X", + details: "Indicates the verification key component of the Reader’s key pair as defined in [Aliro]. The value, " + + "if not null, shall be an uncompressed elliptic curve public key as defined in section 2.3.3 of SEC " + + "1." + + "\n" + + "Null if no Reader key pair has been configured on the lock. See SetAliroReaderConfig.", + xref: { document: "cluster", section: "5.2.9.38" } + }), + + Attribute({ + name: "AliroReaderGroupIdentifier", id: 0x81, type: "octstr", access: "R A", conformance: "ALIRO", + constraint: "16", default: null, quality: "X", + details: "Indicates the reader_group_identifier as defined in [Aliro]." + + "\n" + + "Null if no reader_group_identifier has been configured on the lock. See SetAliroReaderConfig.", + xref: { document: "cluster", section: "5.2.9.39" } + }), + + Attribute({ + name: "AliroReaderGroupSubIdentifier", id: 0x82, type: "octstr", access: "R A", + conformance: "ALIRO", constraint: "16", quality: "F", + details: "Indicates the reader_group_sub_identifier as defined in [Aliro].", + xref: { document: "cluster", section: "5.2.9.40" } + }), + + Attribute( + { + name: "AliroExpeditedTransactionSupportedProtocolVersions", id: 0x83, type: "list", access: "R A", + conformance: "ALIRO", constraint: "max 16[2]", default: [], quality: "F", + details: "Indicates the list of protocol versions supported for expedited transactions as defined in [Aliro].", + xref: { document: "cluster", section: "5.2.9.41" } + }, + + Field({ name: "entry", type: "octstr" }) + ), + + Attribute({ + name: "AliroGroupResolvingKey", id: 0x84, type: "octstr", access: "R A", conformance: "ALBU", + constraint: "16", default: null, quality: "X", + details: "Indicates the Group Resolving Key as defined in [Aliro]." + + "\n" + + "Null if no group resolving key has been configured on the lock. See SetAliroReaderConfig.", + xref: { document: "cluster", section: "5.2.9.42" } + }), + + Attribute( + { + name: "AliroSupportedBleuwbProtocolVersions", id: 0x85, type: "list", access: "R A", + conformance: "ALBU", constraint: "max 16[2]", default: [], quality: "F", + details: "Indicates the list of protocol versions supported for the Bluetooth LE + UWB Access Control Flow as " + + "defined in [Aliro].", + xref: { document: "cluster", section: "5.2.9.43" } + }, + + Field({ name: "entry", type: "octstr" }) + ), + + Attribute({ + name: "AliroBleAdvertisingVersion", id: 0x86, type: "uint8", access: "R A", conformance: "ALBU", + default: 0, quality: "F", + details: "Indicates the version of the Bluetooth LE advertisement as defined in [Aliro].", + xref: { document: "cluster", section: "5.2.9.44" } + }), + + Attribute({ + name: "NumberOfAliroCredentialIssuerKeysSupported", id: 0x87, type: "uint16", access: "R V", + conformance: "ALIRO", default: 0, quality: "F", + details: "Indicates the maximum number of AliroCredentialIssuerKey credentials that can be stored on the lock.", + xref: { document: "cluster", section: "5.2.9.45" } + }), + + Attribute({ + name: "NumberOfAliroEndpointKeysSupported", id: 0x88, type: "uint16", access: "R V", + conformance: "ALIRO", default: 0, quality: "F", + + details: "Indicates the maximum number of endpoint key credentials that can be stored on the lock. This limit " + + "applies to the sum of the number of AliroEvictableEndpointKey credentials and the number of " + + "AliroNonEvictableEndpointKey credentials." + + "\n" + + "NOTE" + + "\n" + + "The credential indices used for these two credential types are independent of each other, similar " + + "to all other credential types. As long as NumberOfAliroEndpointKeysSupported is at least 2 a client " + + "could add a credential of type AliroEvictableEndpointKey at any index from 1 to " + + "NumberOfAliroEndpointKeysSupported and also add a credential of type AliroNonEvictableEndpointKey " + + "at the same index, and both credentials would exist on the server.", + + xref: { document: "cluster", section: "5.2.9.46" } + }), + + Event( + { + name: "DoorLockAlarm", id: 0x0, access: "V", conformance: "M", priority: "critical", + details: "The door lock server provides several alarms which can be sent when there is a critical state on " + + "the door lock. The alarms available for the door lock server are listed in AlarmCodeEnum.", + xref: { document: "cluster", section: "5.2.11.1" } + }, + + Field({ + name: "AlarmCode", id: 0x0, type: "AlarmCodeEnum", conformance: "M", + details: "This field shall indicate the alarm code of the event that has happened.", + xref: { document: "cluster", section: "5.2.11.1.1" } + }) + ), + + Event( + { + name: "DoorStateChange", id: 0x1, access: "V", conformance: "DPS", priority: "critical", + details: "The door lock server sends out a DoorStateChange event when the door lock door state changes.", + xref: { document: "cluster", section: "5.2.11.2" } + }, + Field({ + name: "DoorState", id: 0x0, type: "DoorStateEnum", conformance: "M", + details: "This field shall indicate the new door state for this door event.", + xref: { document: "cluster", section: "5.2.11.2.1" } + }) + ), + + Event( + { + name: "LockOperation", id: 0x2, access: "V", conformance: "M", priority: "critical", + + details: "The door lock server sends out a LockOperation event when the event is triggered by the various " + + "lock operation sources." + + "\n" + + " • If the door lock server supports the Unbolt Door command, it shall generate a LockOperation " + + " event with LockOperationType set to Unlock after an Unbolt Door command succeeds." + + "\n" + + " • If the door lock server supports the Unbolting feature and an Unlock Door command is performed, " + + " it shall generate a LockOperation event with LockOperationType set to Unlatch when the " + + " unlatched state is reached and a LockOperation event with LockOperationType set to Unlock when " + + " the lock successfully completes the unlock → hold latch → release latch and return to unlock " + + " state operation." + + "\n" + + " • If the command fails during holding or releasing the latch but after passing the unlocked " + + " state, the door lock server shall generate a LockOperationError event with LockOperationType " + + " set to Unlatch and a LockOperation event with LockOperationType set to Unlock." + + "\n" + + " ◦ If it fails before reaching the unlocked state, the door lock server shall generate only a " + + " LockOperationError event with LockOperationType set to Unlock." + + "\n" + + " • Upon manual actuation, a door lock server that supports the Unbolting feature:" + + "\n" + + " ◦ shall generate a LockOperation event of LockOperationType Unlatch when it is actuated from " + + " the outside." + + "\n" + + " ◦ may generate a LockOperation event of LockOperationType Unlatch when it is actuated" + + "\n" + + "from the inside.", + + xref: { document: "cluster", section: "5.2.11.3" } + }, + + Field({ + name: "LockOperationType", id: 0x0, type: "LockOperationTypeEnum", conformance: "M", + details: "This field shall indicate the type of the lock operation that was performed.", + xref: { document: "cluster", section: "5.2.11.3.1" } + }), + Field({ + name: "OperationSource", id: 0x1, type: "OperationSourceEnum", conformance: "M", + details: "This field shall indicate the source of the lock operation that was performed.", + xref: { document: "cluster", section: "5.2.11.3.2" } + }), + + Field({ + name: "UserIndex", id: 0x2, type: "uint16", conformance: "M", quality: "X", + details: "This field shall indicate the UserIndex who performed the lock operation. This shall be null if " + + "there is no user index that can be determined for the given operation source. This shall NOT be " + + "null if a user index can be determined. In particular, this shall NOT be null if the operation was " + + "associated with a valid credential.", + xref: { document: "cluster", section: "5.2.11.3.3" } + }), + + Field({ + name: "FabricIndex", id: 0x3, type: "fabric-idx", conformance: "M", quality: "X", + details: "This field shall indicate the fabric index of the fabric that performed the lock operation. This " + + "shall be null if there is no fabric that can be determined for the given operation source. This " + + "shall NOT be null if the operation source is \"Remote\".", + xref: { document: "cluster", section: "5.2.11.3.4" } + }), + + Field({ + name: "SourceNode", id: 0x4, type: "node-id", conformance: "M", quality: "X", + details: "This field shall indicate the Node ID of the node that performed the lock operation. This shall be " + + "null if there is no Node associated with the given operation source. This shall NOT be null if the " + + "operation source is \"Remote\".", + xref: { document: "cluster", section: "5.2.11.3.5" } + }), + + Field( + { + name: "Credentials", id: 0x5, type: "list", conformance: "[USR]", + constraint: "1 to numberOfCredentialsSupportedPerUser", quality: "X", + details: "This field shall indicate the list of credentials used in performing the lock operation. This shall " + + "be null if no credentials were involved.", + xref: { document: "cluster", section: "5.2.11.3.6" } + }, + + Field({ name: "entry", type: "CredentialStruct" }) + ) + ), + + Event( + { + name: "LockOperationError", id: 0x3, access: "V", conformance: "M", priority: "critical", + details: "The door lock server sends out a LockOperationError event when a lock operation fails for various " + + "reasons.", + xref: { document: "cluster", section: "5.2.11.4" } + }, + + Field({ + name: "LockOperationType", id: 0x0, type: "LockOperationTypeEnum", conformance: "M", + details: "This field shall indicate the type of the lock operation that was performed.", + xref: { document: "cluster", section: "5.2.11.4.1" } + }), + Field({ + name: "OperationSource", id: 0x1, type: "OperationSourceEnum", conformance: "M", + details: "This field shall indicate the source of the lock operation that was performed.", + xref: { document: "cluster", section: "5.2.11.4.2" } + }), + Field({ + name: "OperationError", id: 0x2, type: "OperationErrorEnum", conformance: "M", + details: "This field shall indicate the lock operation error triggered when the operation was performed.", + xref: { document: "cluster", section: "5.2.11.4.3" } + }), + + Field({ + name: "UserIndex", id: 0x3, type: "uint16", conformance: "M", quality: "X", + details: "This field shall indicate the lock UserIndex who performed the lock operation. This shall be null " + + "if there is no user id that can be determined for the given operation source.", + xref: { document: "cluster", section: "5.2.11.4.4" } + }), + + Field({ + name: "FabricIndex", id: 0x4, type: "fabric-idx", conformance: "M", quality: "X", + details: "This field shall indicate the fabric index of the fabric that performed the lock operation. This " + + "shall be null if there is no fabric that can be determined for the given operation source. This " + + "shall NOT be null if the operation source is \"Remote\".", + xref: { document: "cluster", section: "5.2.11.4.5" } + }), + + Field({ + name: "SourceNode", id: 0x5, type: "node-id", conformance: "M", quality: "X", + details: "This field shall indicate the Node ID of the node that performed the lock operation. This shall be " + + "null if there is no Node associated with the given operation source. This shall NOT be null if the " + + "operation source is \"Remote\".", + xref: { document: "cluster", section: "5.2.11.4.6" } + }), + + Field( + { + name: "Credentials", id: 0x6, type: "list", conformance: "[USR]", + constraint: "1 to numberOfCredentialsSupportedPerUser", quality: "X", + details: "This field shall indicate the list of credentials used in performing the lock operation. This shall " + + "be null if no credentials were involved.", + xref: { document: "cluster", section: "5.2.11.4.7" } + }, + + Field({ name: "entry", type: "CredentialStruct" }) + ) + ), + + Event( + { + name: "LockUserChange", id: 0x4, access: "V", conformance: "USR", priority: "info", + details: "The door lock server sends out a LockUserChange event when a lock user, schedule, or credential " + + "change has occurred.", + xref: { document: "cluster", section: "5.2.11.5" } + }, + + Field({ + name: "LockDataType", id: 0x0, type: "LockDataTypeEnum", conformance: "M", + details: "This field shall indicate the lock data type that was changed.", + xref: { document: "cluster", section: "5.2.11.5.1" } + }), + Field({ + name: "DataOperationType", id: 0x1, type: "DataOperationTypeEnum", conformance: "M", + details: "This field shall indicate the data operation performed on the lock data type changed.", + xref: { document: "cluster", section: "5.2.11.5.2" } + }), + + Field({ + name: "OperationSource", id: 0x2, type: "OperationSourceEnum", conformance: "M", + constraint: "aliro, unspecified, keypad, remote", + details: "This field shall indicate the source of the user data change.", + xref: { document: "cluster", section: "5.2.11.5.3" } + }), + + Field({ + name: "UserIndex", id: 0x3, type: "uint16", conformance: "M", quality: "X", + details: "This field shall indicate the lock UserIndex associated with the change (if any). This shall be " + + "null if there is no specific user associated with the data operation. This shall be 0xFFFE if all " + + "users are affected (e.g. Clear Users).", + xref: { document: "cluster", section: "5.2.11.5.4" } + }), + + Field({ + name: "FabricIndex", id: 0x4, type: "fabric-idx", conformance: "M", quality: "X", + details: "This field shall indicate the fabric index of the fabric that performed the change (if any). This " + + "shall be null if there is no fabric that can be determined to have caused the change. This shall " + + "NOT be null if the operation source is \"Remote\".", + xref: { document: "cluster", section: "5.2.11.5.5" } + }), + + Field({ + name: "SourceNode", id: 0x5, type: "node-id", conformance: "M", quality: "X", + details: "This field shall indicate the Node ID that performed the change (if any). The Node ID of the node " + + "that performed the change. This shall be null if there was no Node involved in the change. This " + + "shall NOT be null if the operation source is \"Remote\".", + xref: { document: "cluster", section: "5.2.11.5.6" } + }), + + Field({ + name: "DataIndex", id: 0x6, type: "uint16", conformance: "M", quality: "X", + details: "This field shall indicate the index of the specific item that was changed (e.g. schedule, PIN, " + + "RFID, etc.) in the list of items identified by LockDataType. This shall be null if the LockDataType " + + "does not correspond to a list that can be indexed into (e.g. ProgrammingUser). This shall be 0xFFFE " + + "if all indices are affected (e.g. ClearPINCode, ClearRFIDCode, ClearWeekDaySchedule, " + + "ClearYearDaySchedule, etc.).", + xref: { document: "cluster", section: "5.2.11.5.7" } + }) + ), + + Command( + { + name: "LockDoor", id: 0x0, access: "O T", conformance: "M", direction: "request", + response: "status", + details: "This command causes the lock device to lock the door. This command includes an optional code for " + + "the lock. The door lock may require a PIN depending on the value of the " + + "RequirePINForRemoteOperation attribute.", + xref: { document: "cluster", section: "5.2.10.1" } + }, + + Field({ + name: "PinCode", id: 0x0, type: "octstr", conformance: "[COTA & PIN]", + + details: "If the RequirePINforRemoteOperation attribute is True then PINCode field shall be provided and the " + + "door lock shall NOT grant access if it is not provided." + + "\n" + + "If the PINCode field is provided, the door lock shall verify PINCode before granting access " + + "regardless of the value of RequirePINForRemoteOperation attribute." + + "\n" + + "When the PINCode field is provided an invalid PIN will count towards the WrongCodeEntryLimit and " + + "the UserCodeTemporaryDisableTime will be triggered if the WrongCodeEntryLimit is exceeded. The lock " + + "shall ignore any attempts to lock/unlock the door until the UserCodeTemporaryDisableTime expires.", + + xref: { document: "cluster", section: "5.2.10.1.1" } + }) + ), + + Command( + { + name: "UnlockDoor", id: 0x1, access: "O T", conformance: "M", direction: "request", + response: "status", + + details: "This command causes the lock device to unlock the door. This command includes an optional code for " + + "the lock. The door lock may require a code depending on the value of the " + + "RequirePINForRemoteOperation attribute." + + "\n" + + "NOTE" + + "\n" + + "If the attribute AutoRelockTime is supported the lock will transition to the locked state when the " + + "auto relock time has expired.", + + xref: { document: "cluster", section: "5.2.10.2" } + }, + + Field({ + name: "PinCode", id: 0x0, type: "octstr", conformance: "[COTA & PIN]", + details: "See PINCode field.", + xref: { document: "cluster", section: "5.2.10.2.1" } + }) + ), + + Command({ + name: "Toggle", id: 0x2, access: "O T", conformance: "X", direction: "request", response: "status", + xref: { document: "cluster", section: "5.2.10" } + }), + + Command( + { + name: "UnlockWithTimeout", id: 0x3, access: "O T", conformance: "O", direction: "request", + response: "status", + details: "This command causes the lock device to unlock the door with a timeout parameter. After the time in " + + "seconds specified in the timeout field, the lock device will relock itself automatically. This " + + "timeout parameter is only temporary for this message transition and overrides the default relock " + + "time as specified in the AutoRelockTime attribute. If the door lock device is not capable of or " + + "does not want to support temporary Relock Timeout, it SHOULD NOT support this optional command.", + xref: { document: "cluster", section: "5.2.10.3" } + }, + + Field({ + name: "Timeout", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall indicate the timeout in seconds to wait before relocking the door lock. This value " + + "is independent of the AutoRelockTime attribute value.", + xref: { document: "cluster", section: "5.2.10.3.1" } + }), + + Field({ + name: "PinCode", id: 0x1, type: "octstr", conformance: "[COTA & PIN]", + details: "See PINCode field.", + xref: { document: "cluster", section: "5.2.10.3.2" } + }) + ), + + Command( + { + name: "SetPinCode", id: 0x5, access: "A T", conformance: "!USR & PIN", direction: "request", + response: "status", + details: "Set a PIN Code into the lock." + + "\n" + + "Return status is a global status code or a cluster-specific status code from the Status Codes table " + + "and shall be one of the following values:", + xref: { document: "cluster", section: "5.2.10.4" } + }, + + Field({ + name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall indicate the user ID. The value of the UserID field shall be between 0 and the " + + "value of the NumberOfPINUsersSupported attribute.", + xref: { document: "cluster", section: "5.2.10.4.1" } + }), + + Field({ + name: "UserStatus", id: 0x1, type: "UserStatusEnum", conformance: "M", constraint: "desc", + default: 1, quality: "X", + details: "This field shall indicate the user status. Only the values 1 (Occupied/Enabled) and 3 " + + "(Occupied/Disabled) are allowed for UserStatus.", + xref: { document: "cluster", section: "5.2.10.4.2" } + }), + + Field({ name: "UserType", id: 0x2, type: "UserTypeEnum", conformance: "M", default: 0, quality: "X" }), + Field({ name: "Pin", id: 0x3, type: "octstr", conformance: "M" }) + ), + + Command( + { + name: "GetPinCode", id: 0x6, access: "A", conformance: "!USR & PIN", direction: "request", + response: "GetPinCodeResponse", + details: "Retrieve a PIN Code.", + xref: { document: "cluster", section: "5.2.10.5" } + }, + + Field({ + name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall indicate the user ID. The value of the UserID field shall be between 0 and the " + + "value of the NumberOfPINUsersSupported attribute.", + xref: { document: "cluster", section: "5.2.10.5.1" } + }) + ), + + Command( + { + name: "GetPinCodeResponse", id: 0x6, conformance: "!USR & PIN", direction: "response", + + details: "Returns the PIN for the specified user ID." + + "\n" + + "If the requested UserID is valid and the Code doesn’t exist, Get RFID Code Response shall have the " + + "following format:" + + "\n" + + "UserID = requested User ID UserStatus = 0 (Available) UserType = Null (Not supported) PINCode = 0 " + + "(zero length)" + + "\n" + + "If the requested UserID is invalid, send Default Response with an error status. The error status " + + "shall be equal to CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and " + + "NOT_FOUND if greater than or equal to the max number of users supported.", + + xref: { document: "cluster", section: "5.2.10.6" } + }, + + Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }), + Field({ + name: "UserStatus", id: 0x1, type: "UserStatusEnum", conformance: "M", constraint: "desc", + default: 0, quality: "X" + }), + Field({ name: "UserType", id: 0x2, type: "UserTypeEnum", conformance: "M", constraint: "desc", quality: "X" }), + Field({ name: "PinCode", id: 0x3, type: "octstr", conformance: "M", quality: "X" }) + ), + + Command( + { + name: "ClearPinCode", id: 0x7, access: "A T", conformance: "!USR & PIN", direction: "request", + response: "status", + details: "Clear a PIN code or all PIN codes." + + "\n" + + "For each PIN Code cleared whose user doesn’t have a RFID Code or other credential type, then " + + "corresponding user record’s UserStatus value shall be set to Available, and UserType value shall be " + + "set to UnrestrictedUser and all schedules shall be cleared.", + xref: { document: "cluster", section: "5.2.10.7" } + }, + + Field({ + name: "PinSlotIndex", id: 0x0, type: "uint16", conformance: "M", + constraint: "1 to numberOfPinUsersSupported, 65534", + details: "This field shall specify a valid PIN code slot index or 0xFFFE to indicate all PIN code slots shall " + + "be cleared.", + xref: { document: "cluster", section: "5.2.10.7.1" } + }) + ), + + Command({ + name: "ClearAllPinCodes", id: 0x8, access: "A T", conformance: "!USR & PIN", direction: "request", + response: "status", + + details: "Clear out all PINs on the lock." + + "\n" + + "NOTE" + + "\n" + + "On the server, the clear all PIN codes command SHOULD have the same effect as the ClearPINCode " + + "command with respect to the setting of user status, user type and schedules.", + + xref: { document: "cluster", section: "5.2.10.8" } + }), + + Command( + { + name: "SetUserStatus", id: 0x9, access: "A", conformance: "!USR & (PIN | RID | FGP)", + direction: "request", response: "status", + details: "Set the status of a user ID.", + xref: { document: "cluster", section: "5.2.10.9" } + }, + + Field({ + name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall indicate the user ID. The value of the UserID field shall be between 0 and the " + + "value of the NumberOfPINUsersSupported attribute.", + xref: { document: "cluster", section: "5.2.10.9.1" } + }), + + Field({ + name: "UserStatus", id: 0x1, type: "UserStatusEnum", conformance: "M", constraint: "desc", + details: "UserStatus value of Available is not allowed. In order to clear a user id, the ClearUser Command " + + "shall be used. For user status value please refer to UserStatusEnum.", + xref: { document: "cluster", section: "5.2.10.9.2" } + }) + ), + + Command( + { + name: "GetUserStatus", id: 0xa, access: "A", conformance: "!USR & (PIN | RID | FGP)", + direction: "request", response: "GetUserStatusResponse", + details: "Get the status of a user.", + xref: { document: "cluster", section: "5.2.10.10" } + }, + + Field({ + name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall indicate the user ID. The value of the UserID field shall be between 0 and the " + + "value of the NumberOfPINUsersSupported attribute.", + xref: { document: "cluster", section: "5.2.10.10.1" } + }) + ), + + Command( + { + name: "GetUserStatusResponse", id: 0xa, conformance: "!USR", direction: "response", + details: "Returns the user status for the specified user ID.", + xref: { document: "cluster", section: "5.2.10.11" } + }, + Field({ + name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall indicate the user ID provided in the request.", + xref: { document: "cluster", section: "5.2.10.11.1" } + }), + Field({ + name: "UserStatus", id: 0x1, type: "UserStatusEnum", conformance: "M", + details: "This field shall indicate the current status of the requested user ID.", + xref: { document: "cluster", section: "5.2.10.11.2" } + }) + ), + + Command( + { + name: "SetWeekDaySchedule", id: 0xb, access: "A", conformance: "WDSCH", direction: "request", + response: "status", + + details: "Set a weekly repeating schedule for a specified user." + + "\n" + + "The associated UserType may be changed to ScheduleRestrictedUser by the lock when a Week Day " + + "schedule is set." + + "\n" + + "Return status shall be one of the following values:", + + xref: { document: "cluster", section: "5.2.10.12" } + }, + + Field({ + name: "WeekDayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfWeekDaySchedulesSupportedPerUser", + details: "This field shall indicate the index of the Week Day schedule.", + xref: { document: "cluster", section: "5.2.10.12.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.12.2" } + }), + + Field({ + name: "DaysMask", id: 0x2, type: "DaysMaskBitmap", conformance: "M", + details: "This field shall indicate which week days the schedule is active.", + xref: { document: "cluster", section: "5.2.10.12.3" } + }), + Field({ + name: "StartHour", id: 0x3, type: "uint8", conformance: "M", constraint: "max 23", + details: "This field shall indicate the starting hour for the Week Day schedule.", + xref: { document: "cluster", section: "5.2.10.12.4" } + }), + Field({ + name: "StartMinute", id: 0x4, type: "uint8", conformance: "M", constraint: "max 59", + details: "This field shall indicate the starting minute for the Week Day schedule.", + xref: { document: "cluster", section: "5.2.10.12.5" } + }), + + Field({ + name: "EndHour", id: 0x5, type: "uint8", conformance: "M", constraint: "max 23", + details: "This field shall indicate the ending hour for the Week Day schedule. EndHour shall be equal to or " + + "greater than StartHour.", + xref: { document: "cluster", section: "5.2.10.12.6" } + }), + + Field({ + name: "EndMinute", id: 0x6, type: "uint8", conformance: "M", constraint: "max 59", + details: "This field shall indicate the ending minute for the Week Day schedule. If EndHour is equal to " + + "StartHour then EndMinute shall be greater than StartMinute." + + "\n" + + "If the EndHour is equal to 23 and the EndMinute is equal to 59 the Lock shall grant access to the " + + "user up until 23:59:59.", + xref: { document: "cluster", section: "5.2.10.12.7" } + }) + ), + + Command( + { + name: "GetWeekDaySchedule", id: 0xc, access: "A", conformance: "WDSCH", direction: "request", + response: "GetWeekDayScheduleResponse", + details: "Retrieve the specific weekly schedule for the specific user.", + xref: { document: "cluster", section: "5.2.10.13" } + }, + + Field({ + name: "WeekDayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfWeekDaySchedulesSupportedPerUser" + }), + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported" + }) + ), + + Command( + { + name: "GetWeekDayScheduleResponse", id: 0xc, conformance: "WDSCH", direction: "response", + details: "Returns the weekly repeating schedule data for the specified schedule index.", + xref: { document: "cluster", section: "5.2.10.14" } + }, + + Field({ + name: "WeekDayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfWeekDaySchedulesSupportedPerUser", + details: "This field shall indicate the index of the Week Day schedule.", + xref: { document: "cluster", section: "5.2.10.14.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.14.2" } + }), + + Field({ + name: "Status", id: 0x2, type: "status", conformance: "M", constraint: "desc", default: 0, + + details: "Status shall be one of the following values:" + + "\n" + + " • SUCCESS if both WeekDayIndex and UserIndex are valid and there is a corresponding schedule " + + " entry." + + "\n" + + " • INVALID_COMMAND if either WeekDayIndex and/or UserIndex values are not within valid range" + + "\n" + + " • NOT_FOUND if no corresponding schedule entry found for WeekDayIndex." + + "\n" + + " • NOT_FOUND if no corresponding user entry found for UserIndex." + + "\n" + + "If this field is SUCCESS, the optional fields for this command shall be present. For other (error) " + + "status values, only the fields up to the status field shall be present.", + + xref: { document: "cluster", section: "5.2.10.14.3" } + }), + + Field({ name: "DaysMask", id: 0x3, type: "DaysMaskBitmap", conformance: "O" }), + Field({ + name: "StartHour", id: 0x4, type: "uint8", conformance: "O", constraint: "max 23", + details: "This field shall indicate the starting hour for the Week Day schedule.", + xref: { document: "cluster", section: "5.2.10.14.4" } + }), + Field({ + name: "StartMinute", id: 0x5, type: "uint8", conformance: "O", constraint: "max 59", + details: "This field shall indicate the starting minute for the Week Day schedule.", + xref: { document: "cluster", section: "5.2.10.14.5" } + }), + + Field({ + name: "EndHour", id: 0x6, type: "uint8", conformance: "O", constraint: "max 23", + details: "This field shall indicate the ending hour for the Week Day schedule. EndHour shall be equal to or " + + "greater than StartHour.", + xref: { document: "cluster", section: "5.2.10.14.6" } + }), + + Field({ + name: "EndMinute", id: 0x7, type: "uint8", conformance: "O", constraint: "max 59", + details: "This field shall indicate the ending minute for the Week Day schedule. If EndHour is equal to " + + "StartHour then EndMinute shall be greater than StartMinute.", + xref: { document: "cluster", section: "5.2.10.14.7" } + }) + ), + + Command( + { + name: "ClearWeekDaySchedule", id: 0xd, access: "A", conformance: "WDSCH", direction: "request", + response: "status", + details: "Clear the specific weekly schedule or all weekly schedules for the specific user." + + "\n" + + "Return status shall be one of the following values:", + xref: { document: "cluster", section: "5.2.10.15" } + }, + + Field({ + name: "WeekDayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfWeekDaySchedulesSupportedPerUser, 254", + details: "This field shall indicate the Week Day schedule index to clear or 0xFE to clear all Week Day " + + "schedules for the specified user.", + xref: { document: "cluster", section: "5.2.10.15.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.15.2" } + }) + ), + + Command( + { + name: "SetYearDaySchedule", id: 0xe, access: "A", conformance: "YDSCH", direction: "request", + response: "status", + + details: "Set a time-specific schedule ID for a specified user." + + "\n" + + "The associated UserType may be changed to ScheduleRestrictedUser by the lock when a Year Day " + + "schedule is set." + + "\n" + + "Return status shall be one of the following values:", + + xref: { document: "cluster", section: "5.2.10.16" } + }, + + Field({ + name: "YearDayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfYearDaySchedulesSupportedPerUser", + details: "This field shall indicate the index of the Year Day schedule.", + xref: { document: "cluster", section: "5.2.10.16.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.16.2" } + }), + + Field({ + name: "LocalStartTime", id: 0x2, type: "epoch-s", conformance: "M", + details: "This field shall indicate the starting time for the Year Day schedule in Epoch Time in Seconds with " + + "local time offset based on the local timezone and DST offset on the day represented by the value.", + xref: { document: "cluster", section: "5.2.10.16.3" } + }), + + Field({ + name: "LocalEndTime", id: 0x3, type: "epoch-s", conformance: "M", + details: "This field shall indicate the ending time for the Year Day schedule in Epoch Time in Seconds with " + + "local time offset based on the local timezone and DST offset on the day represented by the value. " + + "LocalEndTime shall be greater than LocalStartTime.", + xref: { document: "cluster", section: "5.2.10.16.4" } + }) + ), + + Command( + { + name: "GetYearDaySchedule", id: 0xf, access: "A", conformance: "YDSCH", direction: "request", + response: "GetYearDayScheduleResponse", + details: "Retrieve the specific year day schedule for the specific schedule and user indexes.", + xref: { document: "cluster", section: "5.2.10.17" } + }, + + Field({ + name: "YearDayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfYearDaySchedulesSupportedPerUser" + }), + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported" + }) + ), + + Command( + { + name: "GetYearDayScheduleResponse", id: 0xf, conformance: "YDSCH", direction: "response", + details: "Returns the year day schedule data for the specified schedule and user indexes.", + xref: { document: "cluster", section: "5.2.10.18" } + }, + + Field({ + name: "YearDayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfYearDaySchedulesSupportedPerUser", + details: "This field shall indicate the index of the Year Day schedule.", + xref: { document: "cluster", section: "5.2.10.18.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.18.2" } + }), + + Field({ + name: "Status", id: 0x2, type: "status", conformance: "M", constraint: "desc", default: 0, + + details: "Status shall be one of the following values:" + + "\n" + + " • SUCCESS if both YearDayIndex and UserIndex are valid and there is a corresponding schedule " + + " entry." + + "\n" + + " • INVALID_COMMAND if either YearDayIndex and/or UserIndex values are not within valid range" + + "\n" + + " • NOT_FOUND if no corresponding schedule entry found for YearDayIndex." + + "\n" + + " • NOT_FOUND if no corresponding user entry found for UserIndex." + + "\n" + + "If this field is SUCCESS, the optional fields for this command shall be present. For other (error) " + + "status values, only the fields up to the status field shall be present.", + + xref: { document: "cluster", section: "5.2.10.18.3" } + }), + + Field({ + name: "LocalStartTime", id: 0x2, type: "epoch-s", conformance: "O", + details: "This field shall indicate the starting time for the Year Day schedule in Epoch Time in Seconds with " + + "local time offset based on the local timezone and DST offset on the day represented by the value. " + + "This shall be null if the schedule is not set for the YearDayIndex and UserIndex provided.", + xref: { document: "cluster", section: "5.2.10.18.4" } + }), + + Field({ + name: "LocalEndTime", id: 0x3, type: "epoch-s", conformance: "O", + details: "This field shall indicate the ending time for the Year Day schedule in Epoch Time in Seconds with " + + "local time offset based on the local timezone and DST offset on the day represented by the value. " + + "LocalEndTime shall be greater than LocalStartTime. This shall be null if the schedule is not set " + + "for the YearDayIndex and UserIndex provided.", + xref: { document: "cluster", section: "5.2.10.18.5" } + }) + ), + + Command( + { + name: "ClearYearDaySchedule", id: 0x10, access: "A", conformance: "YDSCH", direction: "request", + response: "status", + details: "Clears the specific year day schedule or all year day schedules for the specific user." + + "\n" + + "Return status shall be one of the following values:", + xref: { document: "cluster", section: "5.2.10.19" } + }, + + Field({ + name: "YearDayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfYearDaySchedulesSupportedPerUser, 254", + details: "This field shall indicate the Year Day schedule index to clear or 0xFE to clear all Year Day " + + "schedules for the specified user.", + xref: { document: "cluster", section: "5.2.10.19.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.19.2" } + }) + ), + + Command( + { + name: "SetHolidaySchedule", id: 0x11, access: "A", conformance: "HDSCH", direction: "request", + response: "status", + details: "Set the holiday Schedule by specifying local start time and local end time with respect to any Lock " + + "Operating Mode." + + "\n" + + "Return status shall be one of the following values:", + xref: { document: "cluster", section: "5.2.10.20" } + }, + + Field({ + name: "HolidayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfHolidaySchedulesSupported", + details: "This field shall indicate the index of the Holiday schedule.", + xref: { document: "cluster", section: "5.2.10.20.1" } + }), + + Field({ + name: "LocalStartTime", id: 0x1, type: "epoch-s", conformance: "M", + details: "This field shall indicate the starting time for the Holiday Day schedule in Epoch Time in Seconds " + + "with local time offset based on the local timezone and DST offset on the day represented by the " + + "value.", + xref: { document: "cluster", section: "5.2.10.20.2" } + }), + + Field({ + name: "LocalEndTime", id: 0x2, type: "epoch-s", conformance: "M", + details: "This field shall indicate the ending time for the Holiday Day schedule in Epoch Time in Seconds " + + "with local time offset based on the local timezone and DST offset on the day represented by the " + + "value. LocalEndTime shall be greater than LocalStartTime.", + xref: { document: "cluster", section: "5.2.10.20.3" } + }), + + Field({ + name: "OperatingMode", id: 0x3, type: "OperatingModeEnum", conformance: "M", + details: "This field shall indicate the operating mode to use during this Holiday schedule start/end time.", + xref: { document: "cluster", section: "5.2.10.20.4" } + }) + ), + + Command( + { + name: "GetHolidaySchedule", id: 0x12, access: "A", conformance: "HDSCH", direction: "request", + response: "GetHolidayScheduleResponse", + details: "Get the holiday schedule for the specified index.", + xref: { document: "cluster", section: "5.2.10.21" } + }, + + Field({ + name: "HolidayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfHolidaySchedulesSupported" + }) + ), + + Command( + { + name: "GetHolidayScheduleResponse", id: 0x12, conformance: "HDSCH", direction: "response", + details: "Returns the Holiday Schedule Entry for the specified Holiday ID.", + xref: { document: "cluster", section: "5.2.10.22" } + }, + + Field({ + name: "HolidayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfHolidaySchedulesSupported", + details: "This field shall indicate the index of the Holiday schedule.", + xref: { document: "cluster", section: "5.2.10.22.1" } + }), + + Field({ + name: "Status", id: 0x1, type: "status", conformance: "M", constraint: "desc", default: 0, + + details: "Status shall be one of the following values:" + + "\n" + + " • FAILURE if the attribute NumberOfHolidaySchedulesSupported is zero." + + "\n" + + " • SUCCESS if the HolidayIndex is valid and there is a corresponding schedule entry." + + "\n" + + " • INVALID_COMMAND if the HolidayIndex is not within valid range" + + "\n" + + " • NOT_FOUND if the HolidayIndex is within the valid range, however, there is not corresponding " + + " schedule entry found." + + "\n" + + "If this field is SUCCESS, the optional fields for this command shall be present. For other (error) " + + "status values, only the fields up to the status field shall be present.", + + xref: { document: "cluster", section: "5.2.10.22.2" } + }), + + Field({ + name: "LocalStartTime", id: 0x2, type: "epoch-s", conformance: "O", quality: "X", + details: "This field shall indicate the starting time for the Holiday schedule in Epoch Time in Seconds with " + + "local time offset based on the local timezone and DST offset on the day represented by the value. " + + "This shall be null if the schedule is not set for the HolidayIndex provided.", + xref: { document: "cluster", section: "5.2.10.22.3" } + }), + + Field({ + name: "LocalEndTime", id: 0x3, type: "epoch-s", conformance: "O", quality: "X", + details: "This field shall indicate the ending time for the Holiday schedule in Epoch Time in Seconds with " + + "local time offset based on the local timezone and DST offset on the day represented by the value. " + + "LocalEndTime shall be greater than LocalStartTime. This shall be null if the schedule is not set " + + "for the HolidayIndex provided.", + xref: { document: "cluster", section: "5.2.10.22.4" } + }), + + Field({ + name: "OperatingMode", id: 0x4, type: "OperatingModeEnum", conformance: "O", quality: "X", + details: "This field shall indicate the operating mode to use during this Holiday schedule start/end time. " + + "This shall be null if the schedule is not set for the HolidayIndex provided.", + xref: { document: "cluster", section: "5.2.10.22.5" } + }) + ), + + Command( + { + name: "ClearHolidaySchedule", id: 0x13, access: "A", conformance: "HDSCH", direction: "request", + response: "status", + details: "Clears the holiday schedule or all holiday schedules.", + xref: { document: "cluster", section: "5.2.10.23" } + }, + + Field({ + name: "HolidayIndex", id: 0x0, type: "uint8", conformance: "M", + constraint: "1 to numberOfHolidaySchedulesSupported, 254", + details: "This field shall indicate the Holiday schedule index to clear or 0xFE to clear all Holiday " + + "schedules.", + xref: { document: "cluster", section: "5.2.10.23.1" } + }) + ), + + Command( + { + name: "SetUserType", id: 0x14, access: "A", conformance: "!USR & (PIN | RID | FGP)", + direction: "request", response: "status", + details: "Set the user type for a specified user." + + "\n" + + "For user type value please refer to User Type Value." + + "\n" + + "Return status shall be one of the following values:", + xref: { document: "cluster", section: "5.2.10.24" } + }, + + Field({ + name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.24.1" } + }), + Field({ + name: "UserType", id: 0x1, type: "UserTypeEnum", conformance: "M", + details: "This field shall indicate the user type.", + xref: { document: "cluster", section: "5.2.10.24.2" } + }) + ), + + Command( + { + name: "GetUserType", id: 0x15, access: "A", conformance: "!USR & (PIN | RID | FGP)", + direction: "request", response: "GetUserTypeResponse", + details: "Retrieve the user type for a specific user.", + xref: { document: "cluster", section: "5.2.10.25" } + }, + + Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }) + ), + + Command( + { + name: "GetUserTypeResponse", id: 0x15, conformance: "!USR", direction: "response", + details: "Returns the user type for the specified user ID. If the requested User ID is invalid, send Default " + + "Response with an error status equal to FAILURE.", + xref: { document: "cluster", section: "5.2.10.26" } + }, + + Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }), + Field({ name: "UserType", id: 0x1, type: "UserTypeEnum", conformance: "M" }) + ), + + Command( + { + name: "SetRfidCode", id: 0x16, access: "A T", conformance: "!USR & RID", direction: "request", + response: "status", + details: "Set an ID for RFID access into the lock." + + "\n" + + "Return status is a global status code or a cluster-specific status code from the Status Codes table " + + "and shall be one of the following values:", + xref: { document: "cluster", section: "5.2.10.27" } + }, + + Field({ + name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall indicate the user ID." + + "\n" + + "The value of the UserID field shall be between 0 and the value of the NumberOfRFIDUsersSupported " + + "attribute.", + xref: { document: "cluster", section: "5.2.10.27.1" } + }), + + Field({ + name: "UserStatus", id: 0x1, type: "UserStatusEnum", conformance: "M", constraint: "desc", + default: 1, quality: "X", + details: "This field shall indicate what the status is for a specific user ID. The values are according to " + + "“Set PIN” while not all are supported." + + "\n" + + "Only the values 1 (Occupied/Enabled) and 3 (Occupied/Disabled) are allowed for UserStatus.", + xref: { document: "cluster", section: "5.2.10.27.2" } + }), + + Field({ + name: "UserType", id: 0x2, type: "UserTypeEnum", conformance: "M", constraint: "desc", default: 0, + quality: "X", + details: "The values are the same as used for SetPINCode command.", + xref: { document: "cluster", section: "5.2.10.27.3" } + }), + + Field({ name: "RfidCode", id: 0x3, type: "octstr", conformance: "M" }) + ), + + Command( + { + name: "GetRfidCode", id: 0x17, access: "A", conformance: "!USR & RID", direction: "request", + response: "GetRfidCodeResponse", + details: "Retrieve an RFID code.", + xref: { document: "cluster", section: "5.2.10.28" } + }, + + Field({ + name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall indicate the user ID." + + "\n" + + "The value of the UserID field shall be between 0 and the value of the NumberOfRFIDUsersSupported " + + "attribute.", + xref: { document: "cluster", section: "5.2.10.28.1" } + }) + ), + + Command( + { + name: "GetRfidCodeResponse", id: 0x17, conformance: "!USR & RID", direction: "response", + + details: "Returns the RFID code for the specified user ID." + + "\n" + + "If the requested User ID is valid and the Code doesn’t exist, Get RFID Code Response shall have the " + + "following format:" + + "\n" + + "User ID = requested User ID UserStatus = 0 (available) UserType = 0xFF (not supported) RFID Code = " + + "0 (zero length)" + + "\n" + + "If requested User ID is invalid, send Default Response with an error status. The error status shall " + + "be equal to CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and " + + "NOT_FOUND if greater than or equal to the max number of users supported.", + + xref: { document: "cluster", section: "5.2.10.29" } + }, + + Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }), + Field({ + name: "UserStatus", id: 0x1, type: "UserStatusEnum", conformance: "M", constraint: "desc", + default: 0, quality: "X" + }), + Field({ name: "UserType", id: 0x2, type: "UserTypeEnum", conformance: "M", constraint: "desc", quality: "X" }), + Field({ name: "RfidCode", id: 0x3, type: "octstr", conformance: "M", quality: "X" }) + ), + + Command( + { + name: "ClearRfidCode", id: 0x18, access: "A T", conformance: "!USR & RID", direction: "request", + response: "status", + details: "Clear an RFID code or all RFID codes." + + "\n" + + "For each RFID Code cleared whose user doesn’t have a PIN Code or other credential type, then the " + + "corresponding user record’s UserStatus value shall be set to Available, and UserType value shall be " + + "set to UnrestrictedUser and all schedules shall be cleared.", + xref: { document: "cluster", section: "5.2.10.30" } + }, + + Field({ + name: "RfidSlotIndex", id: 0x0, type: "uint16", conformance: "M", + constraint: "1 to numberOfRfidUsersSupported, 65534", + details: "This field shall indicate a valid RFID code slot index or 0xFFFE to indicate all RFID code slots " + + "shall be cleared.", + xref: { document: "cluster", section: "5.2.10.30.1" } + }) + ), + + Command({ + name: "ClearAllRfidCodes", id: 0x19, access: "A T", conformance: "!USR & RID", direction: "request", + response: "status", + details: "Clear out all RFIDs on the lock. If you clear all RFID codes and this user didn’t have a PIN code, " + + "the user status has to be set to \"0 Available\", the user type has to be set to the default value, " + + "and all schedules which are supported have to be set to the default values.", + xref: { document: "cluster", section: "5.2.10.31" } + }), + + Command( + { + name: "SetUser", id: 0x1a, access: "A T", conformance: "USR", direction: "request", + response: "status", + + details: "Set user into the lock." + + "\n" + + "Fields used for different use cases:" + + "\n" + + "Return status is a global status code or a cluster-specific status code from the Status Codes table " + + "and" + + "\n" + + "shall be one of the following values:" + + "\n" + + " • SUCCESS, if setting User was successful." + + "\n" + + " • FAILURE, if some unexpected internal error occurred setting User." + + "\n" + + " • OCCUPIED, if OperationType is Add and UserIndex points to an occupied slot." + + "\n" + + " • INVALID_COMMAND, if one or more fields violate constraints or are invalid or if OperationType " + + " is Modify and UserIndex points to an available slot.", + + xref: { document: "cluster", section: "5.2.10.32" } + }, + + Field({ + name: "OperationType", id: 0x0, type: "DataOperationTypeEnum", conformance: "M", + constraint: "add, modify", + details: "This field shall indicate the type of operation.", + xref: { document: "cluster", section: "5.2.10.32.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.32.2" } + }), + + Field({ + name: "UserName", id: 0x2, type: "string", conformance: "M", constraint: "max 10", quality: "X", + + details: "This field shall contain a string to use as a human readable identifier for the user. If UserName " + + "is null then:" + + "\n" + + " • If the OperationType is Add, the UserName in the resulting user record shall be set to an empty " + + " string." + + "\n" + + " • If the OperationType is Modify, the UserName in the user record shall NOT be changed from the " + + " current value." + + "\n" + + "If UserName is not null, the UserName in the user record shall be set to the provided value.", + + xref: { document: "cluster", section: "5.2.10.32.3" } + }), + + Field({ + name: "UserUniqueId", id: 0x3, type: "uint32", conformance: "M", default: 4294967295, quality: "X", + + details: "This field shall indicate the fabric assigned number to use for connecting this user to other users " + + "on other devices from the fabric’s perspective." + + "\n" + + "If UserUniqueID is null then:" + + "\n" + + " • If the OperationType is Add, the UserUniqueID in the resulting user record shall be set to " + + " default value specified above." + + "\n" + + " • If the OperationType is Modify, the UserUniqueID in the user record shall NOT be changed from " + + " the current value." + + "\n" + + "If UserUniqueID is not null, the UserUniqueID in the user record shall be set to the provided value.", + + xref: { document: "cluster", section: "5.2.10.32.4" } + }), + + Field({ + name: "UserStatus", id: 0x4, type: "UserStatusEnum", conformance: "M", + constraint: "occupiedEnabled, occupiedDisabled", default: 1, quality: "X", + + details: "This field shall indicate the UserStatus to assign to this user when created or modified. If " + + "UserStatus is null then:" + + "\n" + + " • If the OperationType is Add, the UserStatus in the resulting user record shall be set to " + + " default value specified above." + + "\n" + + " • If the OperationType is Modify, the UserStatus in the user record shall NOT be changed from the " + + " current value." + + "\n" + + "If UserStatus is not null, the UserStatus in the user record shall be set to the provided value.", + + xref: { document: "cluster", section: "5.2.10.32.5" } + }), + + Field({ + name: "UserType", id: 0x5, type: "UserTypeEnum", conformance: "M", + constraint: "unrestrictedUser, nonAccessUser, forcedUser, disposableUser, expiringUser, scheduleRestrictedUser, remoteOnlyUser", + default: 0, quality: "X", + + details: "This field shall indicate the UserType to assign to this user when created or modified. If UserType " + + "is null then:" + + "\n" + + " • If the OperationType is Add, the UserType in the resulting user record shall be set to default " + + " value specified above." + + "\n" + + " • If the OperationType is Modify, the UserType in the user record shall NOT be changed from the " + + " current value." + + "\n" + + "If UserType is not null, the UserType in the user record shall be set to the provided value.", + + xref: { document: "cluster", section: "5.2.10.32.6" } + }), + + Field({ + name: "CredentialRule", id: 0x6, type: "CredentialRuleEnum", conformance: "M", default: 0, + quality: "X", + + details: "This field shall indicate the CredentialRule to use for this user." + + "\n" + + "The valid CredentialRule enumeration values depends on the bits in the CredentialRulesBitmap map. " + + "Each bit in the map identifies a valid CredentialRule that can be used." + + "\n" + + "If CredentialRule is null then:" + + "\n" + + " • If the OperationType is Add, the CredentialRule in the resulting user record shall be set to " + + " default value specified above." + + "\n" + + " • If the OperationType is Modify, the CredentialRule in the user record shall NOT be changed from " + + " the current value." + + "\n" + + "If CredentialRule is not null, the CredentialRule in the user record shall be set to the provided " + + "value.", + + xref: { document: "cluster", section: "5.2.10.32.7" } + }) + ), + + Command( + { + name: "GetUser", id: 0x1b, access: "A", conformance: "USR", direction: "request", + response: "GetUserResponse", + + details: "Retrieve user." + + "\n" + + "An InvokeResponse command shall be sent with an appropriate error" + + "\n" + + "COMMAND, etc.) as needed otherwise the GetUserResponse Command shall be sent implying a status of " + + "SUCCESS.", + + xref: { document: "cluster", section: "5.2.10.33" } + }, + + Field({ + name: "UserIndex", id: 0x0, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported" + }) + ), + + Command( + { + name: "GetUserResponse", id: 0x1c, conformance: "USR", direction: "response", + details: "Returns the user for the specified UserIndex." + + "\n" + + "If the requested UserIndex is valid and the UserStatus is Available for the requested UserIndex " + + "then UserName, UserUniqueID, UserStatus, UserType, CredentialRule, Credentials, CreatorFabricIndex, " + + "and LastModifiedFabricIndex shall all be null in the response.", + xref: { document: "cluster", section: "5.2.10.34" } + }, + + Field({ + name: "UserIndex", id: 0x0, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.34.1" } + }), + + Field({ + name: "UserName", id: 0x1, type: "string", conformance: "M", constraint: "max 10", quality: "X", + details: "This field shall contain a string to use as a human readable identifier for the user.", + xref: { document: "cluster", section: "5.2.10.34.2" } + }), + Field({ + name: "UserUniqueId", id: 0x2, type: "uint32", conformance: "M", default: 0, quality: "X", + details: "See UserUniqueID field.", + xref: { document: "cluster", section: "5.2.10.34.3" } + }), + Field({ + name: "UserStatus", id: 0x3, type: "UserStatusEnum", conformance: "M", default: 0, quality: "X", + details: "This field shall indicate the UserStatus assigned to the user when created or modified.", + xref: { document: "cluster", section: "5.2.10.34.4" } + }), + Field({ + name: "UserType", id: 0x4, type: "UserTypeEnum", conformance: "M", default: 0, quality: "X", + details: "This field shall indicate the UserType assigned to this user when created or modified.", + xref: { document: "cluster", section: "5.2.10.34.5" } + }), + + Field({ + name: "CredentialRule", id: 0x5, type: "CredentialRuleEnum", conformance: "M", constraint: "desc", + default: 0, quality: "X", + details: "This field shall indicate the CredentialRule set for this user.", + xref: { document: "cluster", section: "5.2.10.34.6" } + }), + + Field( + { + name: "Credentials", id: 0x6, type: "list", conformance: "M", + constraint: "0 to numberOfCredentialsSupportedPerUser", quality: "X", + details: "This field shall contain a list of credentials for this user.", + xref: { document: "cluster", section: "5.2.10.34.7" } + }, + + Field({ name: "entry", type: "CredentialStruct" }) + ), + + Field({ + name: "CreatorFabricIndex", id: 0x7, type: "fabric-idx", conformance: "M", quality: "X", + details: "This field shall indicate the user’s creator fabric index. CreatorFabricIndex shall be null if " + + "UserStatus is set to Available or when the creator fabric cannot be determined (for example, when " + + "user was created outside the Interaction Model) and shall NOT be null otherwise. This value shall " + + "be set to 0 if the original creator fabric was deleted.", + xref: { document: "cluster", section: "5.2.10.34.8" } + }), + + Field({ + name: "LastModifiedFabricIndex", id: 0x8, type: "fabric-idx", conformance: "M", quality: "X", + details: "This field shall indicate the user’s last modifier fabric index. LastModifiedFabricIndex shall be " + + "null if UserStatus is set to Available or when the modifier fabric cannot be determined (for " + + "example, when user was modified outside the Interaction Model) and shall NOT be null otherwise. " + + "This value shall be set to 0 if the last modifier fabric was deleted.", + xref: { document: "cluster", section: "5.2.10.34.9" } + }), + + Field({ + name: "NextUserIndex", id: 0x9, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", quality: "X", + details: "This field shall indicate the next occupied UserIndex in the database which is useful for quickly " + + "identifying occupied user slots in the database. This shall NOT be null if there is at least one " + + "occupied entry after the requested UserIndex in the User database and shall be null if there are no " + + "more occupied entries.", + xref: { document: "cluster", section: "5.2.10.34.10" } + }) + ), + + Command( + { + name: "ClearUser", id: 0x1d, access: "A T", conformance: "USR", direction: "request", + response: "status", + + details: "Clears a user or all Users." + + "\n" + + "For each user to clear, all associated credentials (e.g. PIN, RFID, fingerprint, etc.) shall be " + + "cleared and the user entry values shall be reset to their default values (e.g. UserStatus shall be " + + "Available, UserType shall be UnrestrictedUser) and all associated schedules shall be cleared." + + "\n" + + "A LockUserChange event with the provided UserIndex shall be generated after successfully clearing " + + "users.", + + xref: { document: "cluster", section: "5.2.10.35" } + }, + + Field({ + name: "UserIndex", id: 0x0, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported, 65534", + details: "This field shall specify a valid User index or 0xFFFE to indicate all user slots shall be cleared.", + xref: { document: "cluster", section: "5.2.10.35.1" } + }) + ), + + Command( + { + name: "SetCredential", id: 0x22, access: "A T", conformance: "USR", direction: "request", + response: "SetCredentialResponse", + details: "Set a credential (e.g. PIN, RFID, Fingerprint, etc.) into the lock for a new user, existing user, " + + "or ProgrammingUser." + + "\n" + + "Fields used for different use cases:", + xref: { document: "cluster", section: "5.2.10.36" } + }, + + Field({ + name: "OperationType", id: 0x0, type: "DataOperationTypeEnum", conformance: "M", + constraint: "add, modify", + details: "This field shall indicate the set credential operation type requested.", + xref: { document: "cluster", section: "5.2.10.36.1" } + }), + + Field({ + name: "Credential", id: 0x1, type: "CredentialStruct", conformance: "M", + details: "This field shall contain a credential structure that contains the CredentialTypeEnum and the " + + "credential index (if applicable or 0 if not) to set.", + xref: { document: "cluster", section: "5.2.10.36.2" } + }), + + Field({ + name: "CredentialData", id: 0x2, type: "octstr", conformance: "M", constraint: "desc", + details: "This field shall indicate the credential data to set for the credential being added or modified. " + + "The length of the credential data shall conform to the limits of the CredentialType specified in " + + "the Credential structure otherwise an INVALID_COMMAND status shall be returned in the " + + "SetCredentialResponse command.", + xref: { document: "cluster", section: "5.2.10.36.3" } + }), + + Field({ + name: "UserIndex", id: 0x3, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", quality: "X", + details: "This field shall indicate the user index to the user record that corresponds to the credential " + + "being added or modified. This shall be null if OperationType is add and a new credential and user " + + "is being added at the same time.", + xref: { document: "cluster", section: "5.2.10.36.4" } + }), + + Field({ + name: "UserStatus", id: 0x4, type: "UserStatusEnum", conformance: "M", + constraint: "occupiedEnabled, occupiedDisabled", default: 1, quality: "X", + details: "This field shall indicate the user status to use in the new user record if a new user is being " + + "created. This shall be null if OperationType is Modify. This may be null when adding a new " + + "credential and user.", + xref: { document: "cluster", section: "5.2.10.36.5" } + }), + + Field({ + name: "UserType", id: 0x5, type: "UserTypeEnum", conformance: "M", + constraint: "unrestrictedUser, programmingUser, nonAccessUser, forcedUser, disposableUser, expiringUser, remoteOnlyUser", + default: 0, quality: "X", + details: "This field shall indicate the user type to use in the new user record if a new user is being " + + "created. This shall be null if OperationType is Modify. This may be null when adding a new " + + "credential and user.", + xref: { document: "cluster", section: "5.2.10.36.6" } + }) + ), + + Command( + { + name: "SetCredentialResponse", id: 0x23, conformance: "USR", direction: "response", + details: "Returns the status for setting the specified credential.", + xref: { document: "cluster", section: "5.2.10.37" } + }, + + Field({ + name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", + + details: "Status comes from the Status Codes table and shall be one of the following values:" + + "\n" + + " • SUCCESS, if setting user credential was successful." + + "\n" + + " • FAILURE, if some unexpected internal error occurred setting user credential." + + "\n" + + " • OCCUPIED, if OperationType is Add and CredentialIndex in Credential structure points to an " + + " occupied slot." + + "\n" + + " • OCCUPIED, if OperationType is Modify and CredentialIndex in Credential structure does not match " + + " the CredentialIndex that is already associated with the provided UserIndex." + + "\n" + + " • DUPLICATE, if CredentialData provided is a duplicate of another credential with the same " + + " CredentialType (e.g. duplicate PIN code)." + + "\n" + + " • RESOURCE_EXHAUSTED, if OperationType is Add and the new credential cannot be added due to " + + " resource constraints such as:" + + "\n" + + " ◦ The user referred to by UserIndex already has NumberOfCredentialsSupportedPerUser credentials " + + " associated." + + "\n" + + " ◦ The credential is of type AliroEvictableEndpointKey or AliroNonEvictableEndpointKey, and " + + " adding it would cause the total number of credentials of those two types to exceed " + + " NumberOfAliroEndpointKeysSupported." + + "\n" + + " • INVALID_COMMAND, if one or more fields violate constraints or are invalid." + + "\n" + + " • INVALID_COMMAND, if the CredentialIndex in the Credential provided exceeds the number of " + + " credentials of the provided CredentialType supported by the lock." + + "\n" + + " • INVALID_COMMAND, if OperationType is Modify and UserIndex points to an available slot.", + + xref: { document: "cluster", section: "5.2.10.37.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", default: 0, quality: "X", + details: "This field shall indicate the user index that was created with the new credential. If the status " + + "being returned is not success then this shall be null. This shall be null if OperationType was " + + "Modify; if the OperationType was Add and a new User was created this shall NOT be null and shall " + + "provide the UserIndex created. If the OperationType was Add and an existing User was associated " + + "with the new credential then this shall be null.", + xref: { document: "cluster", section: "5.2.10.37.2" } + }), + + Field({ + name: "NextCredentialIndex", id: 0x2, type: "uint16", conformance: "O", constraint: "desc", + quality: "X", + + details: "This field shall indicate the next available index in the database for the credential type set, " + + "which is useful for quickly identifying available credential slots in the database. This shall NOT " + + "be null if there is at least one available entry after the requested credential index in the " + + "corresponding database and shall be null if there are no more available entries. The " + + "NextCredentialIndex reported shall NOT exceed the maximum number of credentials for a particular " + + "credential type.", + + xref: { document: "cluster", section: "5.2.10.37.3" } + }) + ), + + Command( + { + name: "GetCredentialStatus", id: 0x24, access: "A", conformance: "USR", direction: "request", + response: "GetCredentialStatusResponse", + details: "Retrieve the status of a particular credential (e.g. PIN, RFID, Fingerprint, etc.) by index." + + "\n" + + "An InvokeResponse command shall be sent with an appropriate error (e.g. FAILURE, INVALID_COMMAND, " + + "etc.) as needed otherwise the GetCredentialStatusResponse command shall be sent implying a status " + + "of SUCCESS.", + xref: { document: "cluster", section: "5.2.10.38" } + }, + + Field({ + name: "Credential", id: 0x0, type: "CredentialStruct", conformance: "M", + details: "This field shall contain a credential structure that contains the CredentialTypeEnum and the " + + "credential index (if applicable or 0 if not) to retrieve the status for.", + xref: { document: "cluster", section: "5.2.10.38.1" } + }) + ), + + Command( + { + name: "GetCredentialStatusResponse", id: 0x25, conformance: "USR", direction: "response", + details: "Returns the status for the specified credential.", + xref: { document: "cluster", section: "5.2.10.39" } + }, + + Field({ + name: "CredentialExists", id: 0x0, type: "bool", conformance: "M", + details: "This field shall indicate if the requested credential type and index exists and is populated for " + + "the requested user index.", + xref: { document: "cluster", section: "5.2.10.39.1" } + }), + + Field({ + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", quality: "X", + details: "This field shall indicate the credential’s corresponding user index value if the credential exists. " + + "If CredentialType requested was ProgrammingPIN then UserIndex shall be null; otherwise, UserIndex " + + "shall be null if CredentialExists is set to False and shall NOT be null if CredentialExists is set " + + "to True.", + xref: { document: "cluster", section: "5.2.10.39.2" } + }), + + Field({ + name: "CreatorFabricIndex", id: 0x2, type: "fabric-idx", conformance: "M", quality: "X", + details: "This field shall indicate the credential’s creator fabric index. CreatorFabricIndex shall be null " + + "if CredentialExists is set to False or when the creator fabric cannot be determined (for example, " + + "when credential was created outside the Interaction Model) and shall NOT be null otherwise. This " + + "value shall be set to 0 if the original creator fabric was deleted.", + xref: { document: "cluster", section: "5.2.10.39.3" } + }), + + Field({ + name: "LastModifiedFabricIndex", id: 0x3, type: "fabric-idx", conformance: "M", quality: "X", + details: "This field shall indicate the credential’s last modifier fabric index. LastModifiedFabricIndex " + + "shall be null if CredentialExists is set to False or when the modifier fabric cannot be determined " + + "(for example, when credential was modified outside the Interaction Model) and shall NOT be null " + + "otherwise. This value shall be set to 0 if the last modifier fabric was deleted.", + xref: { document: "cluster", section: "5.2.10.39.4" } + }), + + Field({ + name: "NextCredentialIndex", id: 0x4, type: "uint16", conformance: "O", constraint: "desc", + quality: "X", + + details: "This field shall indicate the next occupied index in the database for the credential type " + + "requested, which is useful for quickly identifying occupied credential slots in the database. This " + + "shall NOT be null if there is at least one occupied entry after the requested credential index in " + + "the corresponding" + + "\n" + + "database and shall be null if there are no more occupied entries. The NextCredentialIndex reported " + + "shall NOT exceed the maximum number of credentials for a particular credential type.", + + xref: { document: "cluster", section: "5.2.10.39.5" } + }), + + Field({ + name: "CredentialData", id: 0x5, type: "octstr", conformance: "[ALIRO]", constraint: "desc", + quality: "X", + + details: "This field shall indicate the credential data for the requested user index." + + "\n" + + "If the CredentialType in the GetCredentialStatus command was not AliroCredentialIssuerKey, " + + "AliroEvictableEndpointKey, or AliroNonEvictableEndpointKey, this field shall NOT be included." + + "\n" + + "Otherwise, if CredentialExists is false this field shall be null." + + "\n" + + "Otherwise, the value of this field shall be the value of the relevant credential, as a 65-byte " + + "uncompressed elliptic curve public key as defined in section 2.3.3 of SEC 1." + + "\n" + + "NOTE" + + "\n" + + "Since the Aliro credentials are public keys, there is no security risk in allowing them to be read. " + + "Possession of the credential octet string does not allow operating the lock.", + + xref: { document: "cluster", section: "5.2.10.39.6" } + }) + ), + + Command( + { + name: "ClearCredential", id: 0x26, access: "A T", conformance: "USR", direction: "request", + response: "status", + + details: "Clear one, one type, or all credentials except ProgrammingPIN credential." + + "\n" + + "Fields used for different use cases:" + + "\n" + + "For each credential cleared whose user doesn’t have another valid credential, the corresponding " + + "user record shall be reset back to default values and its UserStatus value shall be set to " + + "Available and UserType value shall be set to UnrestrictedUser and all schedules shall be cleared. " + + "In this case a LockUserChange event shall be generated for the user being cleared." + + "\n" + + "Return status shall be one of the following values:", + + xref: { document: "cluster", section: "5.2.10.40" } + }, + + Field({ + name: "Credential", id: 0x0, type: "CredentialStruct", conformance: "M", constraint: "desc", + quality: "X", + details: "This field shall contain a credential structure that contains the CredentialTypeEnum and the " + + "credential index (0xFFFE for all credentials or 0 if not applicable) to clear. This shall be null " + + "if clearing all credential types otherwise it shall NOT be null.", + xref: { document: "cluster", section: "5.2.10.40.1" } + }) + ), + + Command( + { + name: "UnboltDoor", id: 0x27, access: "O T", conformance: "UBOLT", direction: "request", + response: "status", + + details: "This command causes the lock device to unlock the door without pulling the latch. This command " + + "includes an optional code for the lock. The door lock may require a code depending on the value of " + + "the RequirePINForRemoteOperation attribute." + + "\n" + + "NOTE" + + "\n" + + "If the attribute AutoRelockTime is supported, the lock will transition to the locked state when the " + + "auto relock time has expired.", + + xref: { document: "cluster", section: "5.2.10.41" } + }, + + Field({ + name: "PinCode", id: 0x0, type: "octstr", conformance: "[COTA & PIN]", + details: "See PINCode field.", + xref: { document: "cluster", section: "5.2.10.41.1" } + }) + ), + + Command( + { + name: "SetAliroReaderConfig", id: 0x28, access: "A T", conformance: "ALIRO", direction: "request", + response: "status", + details: "This command allows communicating an Aliro Reader configuration, as defined in [Aliro], to the lock.", + xref: { document: "cluster", section: "5.2.10.42" } + }, + + Field({ + name: "SigningKey", id: 0x0, type: "octstr", conformance: "M", constraint: "32", + details: "This field shall indicate the signing key component of the Reader’s key pair.", + xref: { document: "cluster", section: "5.2.10.42.1" } + }), + + Field({ + name: "VerificationKey", id: 0x1, type: "octstr", conformance: "M", constraint: "65", + details: "This field shall indicate the verification key component of the Reader’s key pair. This shall be an " + + "uncompressed elliptic curve public key as defined in section 2.3.3 of SEC 1.", + xref: { document: "cluster", section: "5.2.10.42.2" } + }), + + Field({ + name: "GroupIdentifier", id: 0x2, type: "octstr", conformance: "M", constraint: "16", + details: "This field shall indicate the reader group identifier for the lock.", + xref: { document: "cluster", section: "5.2.10.42.3" } + }), + Field({ + name: "GroupResolvingKey", id: 0x3, type: "octstr", conformance: "ALBU", constraint: "16", + details: "This field shall indicate the group resolving key for the lock.", + xref: { document: "cluster", section: "5.2.10.42.4" } + }) + ), + + Command({ + name: "ClearAliroReaderConfig", id: 0x29, access: "A T", conformance: "ALIRO", direction: "request", + response: "status", + + details: "This command allows clearing an existing Aliro Reader configuration for the lock. Administrators " + + "shall NOT clear an Aliro Reader configuration without explicit user permission." + + "\n" + + "NOTE" + + "\n" + + "Using this command will revoke the ability of all existing Aliro user devices that have the old " + + "verification key to interact with the lock. This effect is not restricted to a single fabric or " + + "otherwise scoped in any way.", + + xref: { document: "cluster", section: "5.2.10.43" } + }), + + Datatype( + { + name: "DaysMaskBitmap", type: "map8", + details: "This bitmap shall indicate the days of the week the Week Day schedule applies for.", + xref: { document: "cluster", section: "5.2.6.1" } + }, + Field({ name: "Sunday", constraint: "0", description: "Schedule is applied on Sunday" }), + Field({ name: "Monday", constraint: "1", description: "Schedule is applied on Monday" }), + Field({ name: "Tuesday", constraint: "2", description: "Schedule is applied on Tuesday" }), + Field({ name: "Wednesday", constraint: "3", description: "Schedule is applied on Wednesday" }), + Field({ name: "Thursday", constraint: "4", description: "Schedule is applied on Thursday" }), + Field({ name: "Friday", constraint: "5", description: "Schedule is applied on Friday" }), + Field({ name: "Saturday", constraint: "6", description: "Schedule is applied on Saturday" }) + ), + + Datatype( + { name: "CredentialRulesBitmap", type: "map8", xref: { document: "cluster", section: "5.2.6.2" } }, + Field({ name: "Single", constraint: "0", description: "Only one credential is required for lock operation" }), + Field({ name: "Dual", constraint: "1", description: "Any two credentials are required for lock operation" }), + Field({ name: "Tri", constraint: "2", description: "Any three credentials are required for lock operation" }) + ), + + Datatype( + { name: "OperatingModesBitmap", type: "map16", xref: { document: "cluster", section: "5.2.6.3" } }, + Field({ name: "Normal", constraint: "0", description: "Normal operation mode" }), + Field({ name: "Vacation", constraint: "1", description: "Vacation operation mode" }), + Field({ name: "Privacy", constraint: "2", description: "Privacy operation mode" }), + Field({ name: "NoRemoteLockUnlock", constraint: "3", description: "No remote lock and unlock operation mode" }), + Field({ name: "Passage", constraint: "4", description: "Passage operation mode" }) + ), + + Datatype( + { name: "ConfigurationRegisterBitmap", type: "map16", xref: { document: "cluster", section: "5.2.6.4" } }, + + Field( + { + name: "LocalProgramming", constraint: "0", + description: "The state of local programming functionality", + details: "This bit shall indicate the state related to local programming:" + + "\n" + + " • 0 = Local programming is disabled" + + "\n" + + " • 1 = Local programming is enabled", + xref: { document: "cluster", section: "5.2.6.4.1" } + } + ), + + Field( + { + name: "KeypadInterface", constraint: "1", description: "The state of the keypad interface", + details: "This bit shall indicate the state related to keypad interface:" + + "\n" + + " • 0 = Keypad interface is disabled" + + "\n" + + " • 1 = Keypad interface is enabled", + xref: { document: "cluster", section: "5.2.6.4.2" } + } + ), + + Field( + { + name: "RemoteInterface", constraint: "2", description: "The state of the remote interface", + details: "This bit shall indicate the state related to remote interface:" + + "\n" + + " • 0 = Remote interface is disabled" + + "\n" + + " • 1 = Remote interface is enabled", + xref: { document: "cluster", section: "5.2.6.4.3" } + } + ), + + Field( + { + name: "SoundVolume", constraint: "5", description: "Sound volume is set to Silent value", + details: "This bit shall indicate the state related to sound volume:" + + "\n" + + " • 0 = Sound volume value is 0 (Silent)" + + "\n" + + " • 1 = Sound volume value is equal to something other than 0", + xref: { document: "cluster", section: "5.2.6.4.4" } + } + ), + + Field( + { + name: "AutoRelockTime", constraint: "6", description: "Auto relock time it set to 0", + details: "This bit shall indicate the state related to auto relock time:" + + "\n" + + " • 0 = Auto relock time value is 0" + + "\n" + + " • 1 = Auto relock time value is equal to something other than 0", + xref: { document: "cluster", section: "5.2.6.4.5" } + } + ), + + Field( + { + name: "LedSettings", constraint: "7", description: "LEDs is disabled", + details: "This bit shall indicate the state related to LED settings:" + + "\n" + + " • 0 = LED settings value is 0 (NoLEDSignal)" + + "\n" + + " • 1 = LED settings value is equal to something other than 0", + xref: { document: "cluster", section: "5.2.6.4.6" } + } + ) + ), + + Datatype( + { name: "LocalProgrammingFeaturesBitmap", type: "map8", xref: { document: "cluster", section: "5.2.6.5" } }, + + Field( + { + name: "AddUsersCredentialsSchedules", constraint: "0", + description: "The state of the ability to add users, credentials or schedules on the device", + details: "This bit shall indicate whether the door lock is able to add Users/Credentials/Schedules locally:" + + "\n" + + " • 0 = This ability is disabled" + + "\n" + + " • 1 = This ability is enabled", + xref: { document: "cluster", section: "5.2.6.5.1" } + } + ), + + Field( + { + name: "ModifyUsersCredentialsSchedules", constraint: "1", + description: "The state of the ability to modify users, credentials or schedules on the device", + details: "This bit shall indicate whether the door lock is able to modify Users/Credentials/Schedules locally:" + + "\n" + + " • 0 = This ability is disabled" + + "\n" + + " • 1 = This ability is enabled", + xref: { document: "cluster", section: "5.2.6.5.2" } + } + ), + + Field( + { + name: "ClearUsersCredentialsSchedules", constraint: "2", + description: "The state of the ability to clear users, credentials or schedules on the device", + details: "This bit shall indicate whether the door lock is able to clear Users/Credentials/Schedules locally:" + + "\n" + + " • 0 = This ability is disabled" + + "\n" + + " • 1 = This ability is enabled", + xref: { document: "cluster", section: "5.2.6.5.3" } + } + ), + + Field( + { + name: "AdjustSettings", constraint: "3", + description: "The state of the ability to adjust settings on the device", + details: "This bit shall indicate whether the door lock is able to adjust lock settings locally:" + + "\n" + + " • 0 = This ability is disabled" + + "\n" + + " • 1 = This ability is enabled", + xref: { document: "cluster", section: "5.2.6.5.4" } + } + ) + ), + + Datatype( + { name: "AlarmMaskBitmap", type: "map16", xref: { document: "cluster", section: "5.2.6.6" } }, + Field({ name: "LockJammed", constraint: "0", description: "Locking Mechanism Jammed" }), + Field({ name: "LockFactoryReset", constraint: "1", description: "Lock Reset to Factory Defaults" }), + Field({ name: "LockRadioPowerCycled", constraint: "3", description: "RF Module Power Cycled" }), + Field({ name: "WrongCodeEntryLimit", constraint: "4", description: "Tamper Alarm - wrong code entry limit" }), + Field({ + name: "FrontEscutcheonRemoved", constraint: "5", + description: "Tamper Alarm - front escutcheon removed from main" + }), + Field({ name: "DoorForcedOpen", constraint: "6", description: "Forced Door Open under Door Locked Condition" }) + ), + + Datatype( + { + name: "AlarmCodeEnum", type: "enum8", + details: "This enumeration shall indicate the alarm type.", + xref: { document: "cluster", section: "5.2.6.7" } + }, + Field({ name: "LockJammed", id: 0x0, conformance: "M", description: "Locking Mechanism Jammed" }), + Field({ name: "LockFactoryReset", id: 0x1, conformance: "O", description: "Lock Reset to Factory Defaults" }), + Field({ name: "LockRadioPowerCycled", id: 0x3, conformance: "O", description: "Lock Radio Power Cycled" }), + Field({ + name: "WrongCodeEntryLimit", id: 0x4, conformance: "[USR]", + description: "Tamper Alarm - wrong code entry limit" + }), + Field({ + name: "FrontEsceutcheonRemoved", id: 0x5, conformance: "O", + description: "Tamper Alarm - front escutcheon removed from main" + }), + Field({ + name: "DoorForcedOpen", id: 0x6, conformance: "[DPS]", + description: "Forced Door Open under Door Locked Condition" + }), + Field({ name: "DoorAjar", id: 0x7, conformance: "[DPS]", description: "Door ajar" }), + Field({ name: "ForcedUser", id: 0x8, conformance: "[USR]", description: "Force User SOS alarm" }) + ), + + Datatype( + { + name: "CredentialRuleEnum", type: "enum8", + details: "This enumeration shall indicate the credential rule that can be applied to a particular user.", + xref: { document: "cluster", section: "5.2.6.8" } + }, + Field({ + name: "Single", id: 0x0, conformance: "USR", + description: "Only one credential is required for lock operation" + }), + Field({ + name: "Dual", id: 0x1, conformance: "[USR]", + description: "Any two credentials are required for lock operation" + }), + Field({ + name: "Tri", id: 0x2, conformance: "[USR]", + description: "Any three credentials are required for lock operation" + }) + ), + + Datatype( + { + name: "CredentialTypeEnum", type: "enum8", + details: "This enumeration shall indicate the credential type.", + xref: { document: "cluster", section: "5.2.6.9" } + }, + Field({ name: "ProgrammingPin", id: 0x0, conformance: "O", description: "Programming PIN code credential type" }), + Field({ name: "Pin", id: 0x1, conformance: "PIN", description: "PIN code credential type" }), + Field({ name: "Rfid", id: 0x2, conformance: "RID", description: "RFID identifier credential type" }), + Field({ name: "Fingerprint", id: 0x3, conformance: "FGP", description: "Fingerprint identifier credential type" }), + Field({ name: "FingerVein", id: 0x4, conformance: "FGP", description: "Finger vein identifier credential type" }), + Field({ name: "Face", id: 0x5, conformance: "FACE", description: "Face identifier credential type" }), + + Field({ + name: "AliroCredentialIssuerKey", id: 0x6, conformance: "ALIRO", + description: "A Credential Issuer public key as defined in [Aliro]", + + details: "Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in " + + "section 2.3.3 of SEC 1." + + "\n" + + "Credentials of this type shall NOT be used to allow operating the lock. They shall be used, as " + + "defined in [Aliro], to create new credentials of type AliroEvictableEndpointKey via a step-up " + + "transaction." + + "\n" + + "When performing the step-up transaction, the lock shall request the data element with identifier " + + "\"matter1\", and shall attempt to create a new credential of type AliroEvictableEndpointKey if and " + + "only if the data element is returned and the Access Credential can be validated using the " + + "AliroCredentialIssuerKey." + + "\n" + + "When a new credential of type AliroEvictableEndpointKey is added in this manner, it shall be " + + "associated with the same user record as the AliroCredentialIssuerKey credential that allowed the " + + "new credential to be added." + + "\n" + + "If there are no available credential slots to add a new AliroEvictableEndpointKey credential (i.e. " + + "either the NumberOfCredentialsSupportedPerUser or the NumberOfAliroEndpointKeysSupported limit has " + + "been reached) but there exist credentials of type AliroEvictableEndpointKey associated with the " + + "user record, the server shall remove one of those credentials using the same procedure it would " + + "follow for the ClearCredential command before adding the new credential." + + "\n" + + "If there are no available credential slots to add a new AliroEvictableEndpointKey credential (i.e. " + + "either the NumberOfCredentialsSupportedPerUser or the NumberOfAliroEndpointKeysSupported limit has " + + "been reached) and there do not exist credentials of type AliroEvictableEndpointKey associated with " + + "the user record, a new AliroEvictableEndpointKey credential shall NOT be created." + + "\n" + + "If the step-up process results in addition of new credentials, the corresponding LockUserChange " + + "event shall have OperationSource set to Aliro." + + "\n" + + "If the step-up process results in the lock state changing (e.g. locking or unlocking), the " + + "credential associated with those changes in the LockOperation events shall be the newly provisioned " + + "AliroEvictableEndpointKey credential if one was created. If no new AliroEvictableEndpointKey " + + "credential was created, the credential associated with the changes in the LockOperation events " + + "shall be the AliroCredentialIssuerKey credential used for the step-up.", + + xref: { document: "cluster", section: "5.2.6.9.1" } + }), + + Field({ + name: "AliroEvictableEndpointKey", id: 0x7, conformance: "ALIRO", + description: "An Endpoint public key as defined in [Aliro] which can be evicted if space is needed for another endpoint key", + details: "Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in " + + "section 2.3.3 of SEC 1.", + xref: { document: "cluster", section: "5.2.6.9.2" } + }), + + Field({ + name: "AliroNonEvictableEndpointKey", id: 0x8, conformance: "ALIRO", + description: "An Endpoint public key as defined in [Aliro] which cannot be evicted if space is needed for another endpoint key", + details: "Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in " + + "section 2.3.3 of SEC 1.", + xref: { document: "cluster", section: "5.2.6.9.3" } + }) + ), + + Datatype( + { + name: "DataOperationTypeEnum", type: "enum8", + details: "This enumeration shall indicate the data operation performed.", + xref: { document: "cluster", section: "5.2.6.10" } + }, + Field({ name: "Add", id: 0x0, conformance: "M", description: "Data is being added or was added" }), + Field({ name: "Clear", id: 0x1, conformance: "M", description: "Data is being cleared or was cleared" }), + Field({ name: "Modify", id: 0x2, conformance: "M", description: "Data is being modified or was modified" }) + ), + + Datatype( + { + name: "DoorStateEnum", type: "enum8", + details: "This enumeration shall indicate the current door state.", + xref: { document: "cluster", section: "5.2.6.11" } + }, + Field({ name: "DoorOpen", id: 0x0, conformance: "DPS", description: "Door state is open" }), + Field({ name: "DoorClosed", id: 0x1, conformance: "DPS", description: "Door state is closed" }), + Field({ name: "DoorJammed", id: 0x2, conformance: "[DPS]", description: "Door state is jammed" }), + Field({ + name: "DoorForcedOpen", id: 0x3, conformance: "[DPS]", + description: "Door state is currently forced open" + }), + Field({ + name: "DoorUnspecifiedError", id: 0x4, conformance: "[DPS]", + description: "Door state is invalid for unspecified reason" + }), + Field({ name: "DoorAjar", id: 0x5, conformance: "[DPS]", description: "Door state is ajar" }) + ), + + Datatype( + { + name: "LockDataTypeEnum", type: "enum8", + details: "This enumeration shall indicate the data type that is being or has changed.", + xref: { document: "cluster", section: "5.2.6.12" } + }, + Field({ + name: "Unspecified", id: 0x0, conformance: "O", + description: "Unspecified or manufacturer specific lock user data added, cleared, or modified." + }), + Field({ + name: "ProgrammingCode", id: 0x1, conformance: "O", + description: "Lock programming PIN code was added, cleared, or modified." + }), + Field({ + name: "UserIndex", id: 0x2, conformance: "M", + description: "Lock user index was added, cleared, or modified." + }), + Field({ + name: "WeekDaySchedule", id: 0x3, conformance: "WDSCH", + description: "Lock user week day schedule was added, cleared, or modified." + }), + Field({ + name: "YearDaySchedule", id: 0x4, conformance: "YDSCH", + description: "Lock user year day schedule was added, cleared, or modified." + }), + Field({ + name: "HolidaySchedule", id: 0x5, conformance: "HDSCH", + description: "Lock holiday schedule was added, cleared, or modified." + }), + Field({ + name: "Pin", id: 0x6, conformance: "PIN", + description: "Lock user PIN code was added, cleared, or modified." + }), + Field({ + name: "Rfid", id: 0x7, conformance: "RID", + description: "Lock user RFID code was added, cleared, or modified." + }), + Field({ + name: "Fingerprint", id: 0x8, conformance: "FGP", + description: "Lock user fingerprint was added, cleared, or modified." + }), + Field({ + name: "FingerVein", id: 0x9, conformance: "FGP", + description: "Lock user finger-vein information was added, cleared, or modified." + }), + Field({ + name: "Face", id: 0xa, conformance: "FACE", + description: "Lock user face information was added, cleared, or modified." + }), + Field({ + name: "AliroCredentialIssuerKey", id: 0xb, conformance: "ALIRO", + description: "An Aliro credential issuer key credential was added, cleared, or modified." + }), + Field({ + name: "AliroEvictableEndpointKey", id: 0xc, conformance: "ALIRO", + description: "An Aliro endpoint key credential which can be evicted credential was added, cleared, or modified." + }), + Field({ + name: "AliroNonEvictableEndpointKey", id: 0xd, conformance: "ALIRO", + description: "An Aliro endpoint key credential which cannot be evicted was added, cleared, or modified." + }) + ), + + Datatype( + { + name: "LockOperationTypeEnum", type: "enum8", + details: "This enumeration shall indicate the type of Lock operation performed.", + xref: { document: "cluster", section: "5.2.6.13" } + }, + Field({ name: "Lock", id: 0x0, conformance: "M", description: "Lock operation" }), + Field({ name: "Unlock", id: 0x1, conformance: "M", description: "Unlock operation" }), + Field({ + name: "NonAccessUserEvent", id: 0x2, conformance: "O", + description: "Triggered by keypad entry for user with User Type set to Non Access User" + }), + Field({ + name: "ForcedUserEvent", id: 0x3, conformance: "O", + description: "Triggered by using a user with UserType set to Forced User" + }), + Field({ name: "Unlatch", id: 0x4, conformance: "M", description: "Unlatch operation" }) + ), + + Datatype( + { + name: "OperationErrorEnum", type: "enum8", + details: "This enumeration shall indicate the error cause of the Lock/Unlock operation performed.", + xref: { document: "cluster", section: "5.2.6.14" } + }, + Field({ + name: "Unspecified", id: 0x0, conformance: "O", + description: "Lock/unlock error caused by unknown or unspecified source" + }), + Field({ + name: "InvalidCredential", id: 0x1, conformance: "USR", + description: "Lock/unlock error caused by invalid PIN, RFID, fingerprint or other credential" + }), + Field({ + name: "DisabledUserDenied", id: 0x2, conformance: "M", + description: "Lock/unlock error caused by disabled USER or credential" + }), + Field({ + name: "Restricted", id: 0x3, conformance: "WDSCH | YDSCH", + description: "Lock/unlock error caused by schedule restriction" + }), + Field({ + name: "InsufficientBattery", id: 0x4, conformance: "O", + description: "Lock/unlock error caused by insufficient battery power left to safely actuate the lock" + }) + ), + + Datatype( + { + name: "OperatingModeEnum", type: "enum8", + + details: "This enumeration shall indicate the lock operating mode." + + "\n" + + "The table below shows the operating mode and which interfaces are enabled, if supported, for each " + + "mode." + + "\n" + + "* Interface Operational: Yes, No or N/A" + + "\n" + + "NOTE" + + "\n" + + "For modes that disable the remote interface, the door lock shall respond to Lock, Unlock, Toggle, " + + "and Unlock with Timeout commands with a response status Failure and not take the action requested " + + "by those commands. The door lock shall NOT disable the radio or otherwise unbind or leave the " + + "network. It shall still respond to all other commands and requests.", + + xref: { document: "cluster", section: "5.2.6.15" } + }, + + Field({ + name: "Normal", id: 0x0, conformance: "M", + details: "The lock operates normally. All interfaces are enabled.", + xref: { document: "cluster", section: "5.2.6.15.1" } + }), + Field({ + name: "Vacation", id: 0x1, conformance: "O", + details: "Only remote interaction is enabled. The keypad shall only be operable by the master user.", + xref: { document: "cluster", section: "5.2.6.15.2" } + }), + + Field({ + name: "Privacy", id: 0x2, conformance: "O", + details: "This mode is only possible if the door is locked. Manual unlocking changes the mode to Normal " + + "operating mode. All external interaction with the door lock is disabled. This mode is intended to " + + "be used so that users, presumably inside the property, will have control over the entrance.", + xref: { document: "cluster", section: "5.2.6.15.3" } + }), + + Field({ + name: "NoRemoteLockUnlock", id: 0x3, conformance: "M", + details: "This mode only disables remote interaction with the lock. This does not apply to any remote " + + "proprietary means of communication. It specifically applies to the Lock, Unlock, Toggle, and Unlock " + + "with Timeout Commands.", + xref: { document: "cluster", section: "5.2.6.15.4" } + }), + + Field({ + name: "Passage", id: 0x4, conformance: "O", + details: "The lock is open or can be opened or closed at will without the use of a Keypad or other means of " + + "user validation (e.g. a lock for a business during work hours).", + xref: { document: "cluster", section: "5.2.6.15.5" } + }) + ), + + Datatype( + { + name: "OperationSourceEnum", type: "enum8", + details: "This enumeration shall indicate the source of the Lock/Unlock or user change operation performed.", + xref: { document: "cluster", section: "5.2.6.16" } + }, + Field({ + name: "Unspecified", id: 0x0, conformance: "O", + description: "Lock/unlock operation came from unspecified source" + }), + Field({ + name: "Manual", id: 0x1, conformance: "O", + description: "Lock/unlock operation came from manual operation (key, thumbturn, handle, etc)." + }), + Field({ + name: "ProprietaryRemote", id: 0x2, conformance: "O", + description: "Lock/unlock operation came from proprietary remote source (e.g. vendor app/cloud)" + }), + Field({ name: "Keypad", id: 0x3, conformance: "O", description: "Lock/unlock operation came from keypad" }), + Field({ + name: "Auto", id: 0x4, conformance: "O", + description: "Lock/unlock operation came from lock automatically (e.g. relock timer)" + }), + Field({ + name: "Button", id: 0x5, conformance: "O", + description: "Lock/unlock operation came from lock button (e.g. one touch or button)" + }), + Field({ + name: "Schedule", id: 0x6, conformance: "HDSCH", + description: "Lock/unlock operation came from lock due to a schedule" + }), + Field({ name: "Remote", id: 0x7, conformance: "M", description: "Lock/unlock operation came from remote node" }), + Field({ name: "Rfid", id: 0x8, conformance: "RID", description: "Lock/unlock operation came from RFID card" }), + Field({ + name: "Biometric", id: 0x9, conformance: "[USR]", + description: "Lock/unlock operation came from biometric source (e.g. face, fingerprint/fingervein)" + }), + Field({ + name: "Aliro", id: 0xa, conformance: "ALIRO", + description: "Lock/unlock operation came from an interaction defined in [Aliro], or user change operation was a step-up credential provisioning as defined in [Aliro]" + }) + ), + + Datatype( + { + name: "UserStatusEnum", type: "enum8", + details: "This enumeration shall indicate what the status is for a specific user ID.", + xref: { document: "cluster", section: "5.2.6.17" } + }, + Field({ name: "Available", id: 0x0, conformance: "M", description: "The user ID is available" }), + Field({ name: "OccupiedEnabled", id: 0x1, conformance: "M", description: "The user ID is occupied and enabled" }), + Field({ + name: "OccupiedDisabled", id: 0x3, conformance: "O", + description: "The user ID is occupied and disabled" + }) + ), + + Datatype( + { + name: "UserTypeEnum", type: "enum8", + details: "This enumeration shall indicate what the type is for a specific user ID.", + xref: { document: "cluster", section: "5.2.6.18" } + }, + + Field({ + name: "UnrestrictedUser", id: 0x0, conformance: "M", + description: "The user ID type is unrestricted", + details: "This value shall indicate the user has access 24/7 provided proper PIN or RFID is supplied (e.g., " + + "owner).", + xref: { document: "cluster", section: "5.2.6.18.1" } + }), + + Field({ + name: "YearDayScheduleUser", id: 0x1, conformance: "O", description: "The user ID type is schedule", + + details: "This value shall indicate the user has the ability to open lock within a specific time period " + + "(e.g., guest)." + + "\n" + + "When UserType is set to YearDayScheduleUser, user access shall be restricted as follows:" + + "\n" + + " • If no YearDaySchedules are set for the user, then access shall be denied" + + "\n" + + " • If one or more YearDaySchedules are set, user access shall be granted if and only if the " + + " current time falls within at least one of the YearDaySchedules. If current time is not known, " + + " user access shall NOT be granted.", + + xref: { document: "cluster", section: "5.2.6.18.2" } + }), + + Field({ + name: "WeekDayScheduleUser", id: 0x2, conformance: "O", description: "The user ID type is schedule", + + details: "This value shall indicate the user has the ability to open lock based on specific time period " + + "within a reoccurring weekly schedule (e.g., cleaning worker)." + + "\n" + + "When UserType is set to WeekDayScheduleUser, user access shall be restricted as follows:" + + "\n" + + " • If no WeekDaySchedules are set for the user, then access shall be denied" + + "\n" + + " • If one or more WeekDaySchedules are set, user access shall be granted if and only if the " + + " current time falls within at least one of the WeekDaySchedules. If current time is not known, " + + " user access shall NOT be granted.", + + xref: { document: "cluster", section: "5.2.6.18.3" } + }), + + Field({ + name: "ProgrammingUser", id: 0x3, conformance: "O", description: "The user ID type is programming", + details: "This value shall indicate the user has the ability to both program and operate the door lock. This " + + "user can manage the users and user schedules. In all other respects this user matches the " + + "unrestricted (default) user. ProgrammingUser is the only user that can disable the user interface " + + "(keypad, remote, etc…).", + xref: { document: "cluster", section: "5.2.6.18.4" } + }), + + Field({ + name: "NonAccessUser", id: 0x4, conformance: "O", description: "The user ID type is non access", + details: "This value shall indicate the user is recognized by the lock but does not have the ability to open " + + "the lock. This user will only cause the lock to generate the appropriate event notification to any " + + "bound devices.", + xref: { document: "cluster", section: "5.2.6.18.5" } + }), + + Field({ + name: "ForcedUser", id: 0x5, conformance: "[USR]", description: "The user ID type is forced", + details: "This value shall indicate the user has the ability to open lock but a ForcedUser LockOperationType " + + "and ForcedUser silent alarm will be emitted to allow a notified Node to alert emergency services or " + + "contacts on the user account when used.", + xref: { document: "cluster", section: "5.2.6.18.6" } + }), + + Field({ + name: "DisposableUser", id: 0x6, conformance: "[USR]", + description: "The user ID type is disposable", + details: "This value shall indicate the user has the ability to open lock once after which the lock shall " + + "change the corresponding user record UserStatus value to OccupiedDisabled automatically.", + xref: { document: "cluster", section: "5.2.6.18.7" } + }), + + Field({ + name: "ExpiringUser", id: 0x7, conformance: "[USR]", description: "The user ID type is expiring", + details: "This value shall indicate the user has the ability to open lock for ExpiringUserTimeout attribute " + + "minutes after the first use of the PIN code, RFID code, Fingerprint, or other credential. After " + + "ExpiringUserTimeout minutes the corresponding user record UserStatus value shall be set to " + + "OccupiedDisabled automatically by the lock. The lock shall persist the timeout across reboots such " + + "that the ExpiringUserTimeout is honored.", + xref: { document: "cluster", section: "5.2.6.18.8" } + }), + + Field({ + name: "ScheduleRestrictedUser", id: 0x8, conformance: "WDSCH | YDSCH", + description: "The user ID type is schedule restricted", + + details: "This value shall indicate the user access is restricted by Week Day and/or Year Day schedule. When " + + "UserType is set to ScheduleRestrictedUser, user access shall be restricted as follows:" + + "\n" + + " • If no WeekDaySchedules and no YearDaySchedules are set for the user, then access shall be denied" + + "\n" + + " • If one or more WeekDaySchedules are set, but no YearDaySchedules are set for the user, then " + + " user access shall be equivalent to the WeekDayScheduleUser UserType" + + "\n" + + " • If one or more YearDaySchedules are set, but no WeekDaySchedules are set for the user, then " + + " user access shall be equivalent to the YearDayScheduleUser UserType" + + "\n" + + " • If one or WeekDaySchedules are set AND one or more YearDaySchedules are set, then user access " + + " shall be granted if and only if the current time falls within at least one of the " + + " WeekDaySchedules AND the current time falls within at least one of the YearDaySchedules.", + + xref: { document: "cluster", section: "5.2.6.18.9" } + }), + + Field({ + name: "RemoteOnlyUser", id: 0x9, conformance: "USR & COTA & PIN", + description: "The user ID type is remote only", + details: "This value shall indicate the user access and PIN code is restricted to remote lock/unlock commands " + + "only. This type of user might be useful for regular delivery services or voice assistant unlocking " + + "operations to prevent a PIN code credential created for them from being used at the keypad. The PIN " + + "code credential would only be provided over-the-air for the lock/unlock commands.", + xref: { document: "cluster", section: "5.2.6.18.10" } + }) + ), + + Datatype( + { name: "LockStateEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.19" } }, + Field({ name: "NotFullyLocked", id: 0x0, conformance: "M", description: "Lock state is not fully locked" }), + Field({ name: "Locked", id: 0x1, conformance: "M", description: "Lock state is fully locked" }), + Field({ name: "Unlocked", id: 0x2, conformance: "M", description: "Lock state is fully unlocked" }), + Field({ + name: "Unlatched", id: 0x3, conformance: "O", + description: "Lock state is fully unlocked and the latch is pulled" + }) + ), + + Datatype( + { name: "LockTypeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.20" } }, + Field({ name: "DeadBolt", id: 0x0, conformance: "M", description: "Physical lock type is dead bolt" }), + Field({ name: "Magnetic", id: 0x1, conformance: "M", description: "Physical lock type is magnetic" }), + Field({ name: "Other", id: 0x2, conformance: "M", description: "Physical lock type is other" }), + Field({ name: "Mortise", id: 0x3, conformance: "M", description: "Physical lock type is mortise" }), + Field({ name: "Rim", id: 0x4, conformance: "M", description: "Physical lock type is rim" }), + Field({ name: "LatchBolt", id: 0x5, conformance: "M", description: "Physical lock type is latch bolt" }), + Field({ + name: "CylindricalLock", id: 0x6, conformance: "M", + description: "Physical lock type is cylindrical lock" + }), + Field({ name: "TubularLock", id: 0x7, conformance: "M", description: "Physical lock type is tubular lock" }), + Field({ + name: "InterconnectedLock", id: 0x8, conformance: "M", + description: "Physical lock type is interconnected lock" + }), + Field({ name: "DeadLatch", id: 0x9, conformance: "M", description: "Physical lock type is dead latch" }), + Field({ name: "DoorFurniture", id: 0xa, conformance: "M", description: "Physical lock type is door furniture" }), + Field({ name: "Eurocylinder", id: 0xb, conformance: "M", description: "Physical lock type is euro cylinder" }) + ), + + Datatype( + { name: "LEDSettingEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.21" } }, + Field({ name: "NoLedSignal", id: 0x0, conformance: "M", description: "Never use LED for signalization" }), + Field({ + name: "NoLedSignalAccessAllowed", id: 0x1, conformance: "M", + description: "Use LED signalization except for access allowed events" + }), + Field({ name: "LedSignalAll", id: 0x2, conformance: "M", description: "Use LED signalization for all events" }) + ), + + Datatype( + { name: "SoundVolumeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.22" } }, + Field({ name: "Silent", id: 0x0, conformance: "M", description: "Silent Mode" }), + Field({ name: "Low", id: 0x1, conformance: "M", description: "Low Volume" }), + Field({ name: "High", id: 0x2, conformance: "M", description: "High Volume" }), + Field({ name: "Medium", id: 0x3, conformance: "M", description: "Medium Volume" }) + ), + + Datatype( + { name: "EventTypeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.23" } }, + Field({ name: "Operation", id: 0x0, conformance: "M", description: "Event type is operation" }), + Field({ name: "Programming", id: 0x1, conformance: "M", description: "Event type is programming" }), + Field({ name: "Alarm", id: 0x2, conformance: "M", description: "Event type is alarm" }) + ), + + Datatype( + { + name: "CredentialStruct", type: "struct", + details: "This struct shall indicate the credential types and their corresponding indices (if any) for the " + + "event or user record.", + xref: { document: "cluster", section: "5.2.6.24" } + }, + + Field({ + name: "CredentialType", id: 0x0, type: "CredentialTypeEnum", conformance: "M", + details: "This field shall indicate the credential field used to authorize the lock operation.", + xref: { document: "cluster", section: "5.2.6.24.1" } + }), + + Field({ + name: "CredentialIndex", id: 0x1, type: "uint16", conformance: "M", default: 0, + details: "This field shall indicate the index of the specific credential used to authorize the lock operation " + + "in the list of credentials identified by CredentialType (e.g. PIN, RFID, etc.). This field shall be " + + "set to 0 if CredentialType is ProgrammingPIN or does not correspond to a list that can be indexed " + + "into.", + xref: { document: "cluster", section: "5.2.6.24.2" } + }) + ), + + Datatype( + { name: "StatusCodeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.7.1" } }, + Field({ + name: "Duplicate", id: 0x2, conformance: "M", + description: "Entry would cause a duplicate credential/ID." + }), + Field({ name: "Occupied", id: 0x3, conformance: "M", description: "Entry would replace an occupied slot." }) + ) + ), + + Cluster( + { + name: "WindowCovering", id: 0x102, classification: "application", pics: "WNCV", + details: "The window covering cluster provides an interface for controlling and adjusting automatic window " + + "coverings such as drapery motors, automatic shades, curtains and blinds.", + xref: { document: "cluster", section: "5.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 5 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "5.3.4" } }, + + Field({ + name: "LF", conformance: "O.a+", constraint: "0", description: "Lift", + details: "The Lift feature applies to window coverings that lift up and down (e.g. for a roller shade, Up and " + + "Down is lift Open and Close) or slide left to right (e.g. for a sliding curtain, Left and Right is " + + "lift Open and Close).", + xref: { document: "cluster", section: "5.3.4.1" } + }), + + Field({ + name: "TL", conformance: "O.a+", constraint: "1", description: "Tilt", + details: "The Tilt feature applies to window coverings with vertical or horizontal strips.", + xref: { document: "cluster", section: "5.3.4.2" } + }), + Field({ + name: "PA_LF", conformance: "[LF]", constraint: "2", description: "PositionAwareLift", + details: "Position aware lift control is supported." + }), + + Field({ + name: "ABS", conformance: "O", constraint: "3", description: "AbsolutePosition", + + details: "The percentage attributes shall indicate the position as a percentage between the " + + "InstalledOpenLimits and InstalledClosedLimits attributes of the window covering starting at the " + + "open (0.00%)." + + "\n" + + "As a general rule, absolute positioning (in centimeters or tenth of a degrees) SHOULD NOT be " + + "supported for new implementations.", + + xref: { document: "cluster", section: "5.3.4.4" } + }), + + Field({ + name: "PA_TL", conformance: "[TL]", constraint: "4", description: "PositionAwareTilt", + details: "Position aware tilt control is supported." + }) + ), + + Attribute({ + name: "Type", id: 0x0, type: "TypeEnum", access: "R V", conformance: "M", constraint: "desc", + default: 0, quality: "F", + details: "This attribute shall identify the type of window covering.", + xref: { document: "cluster", section: "5.3.6.1" } + }), + + Attribute({ + name: "PhysicalClosedLimitLift", id: 0x1, type: "uint16", access: "R V", + conformance: "[LF & PA_LF & ABS]", default: 0, quality: "F", + details: "Indicates the maximum possible encoder position possible (Unit cm, centimeters) to position the " + + "height of the window covering lift.", + xref: { document: "cluster", section: "5.3.6.2" } + }), + + Attribute({ + name: "PhysicalClosedLimitTilt", id: 0x2, type: "uint16", access: "R V", + conformance: "[TL & PA_TL & ABS]", default: 0, quality: "F", + details: "Indicates the maximum possible encoder position possible (Unit 0.1°, tenths of a degree) to " + + "position the angle of the window covering tilt.", + xref: { document: "cluster", section: "5.3.6.3" } + }), + + Attribute({ + name: "CurrentPositionLift", id: 0x3, type: "uint16", access: "R V", + conformance: "[LF & PA_LF & ABS]", constraint: "installedOpenLimitLift to installedClosedLimitLift", + default: null, quality: "X N", + details: "Indicates the actual lift position (Unit cm, centimeters) of the window covering from the " + + "fully-open position.", + xref: { document: "cluster", section: "5.3.6.4" } + }), + + Attribute({ + name: "CurrentPositionTilt", id: 0x4, type: "uint16", access: "R V", + conformance: "[TL & PA_TL & ABS]", constraint: "installedOpenLimitTilt to installedClosedLimitTilt", + default: null, quality: "X N", + details: "Indicates the actual tilt position (Unit 0.1°, tenths of a degree) of the window covering from the " + + "fully-open position.", + xref: { document: "cluster", section: "5.3.6.5" } + }), + + Attribute({ + name: "NumberOfActuationsLift", id: 0x5, type: "uint16", access: "R V", conformance: "[LF]", + default: 0, quality: "N", + details: "Indicates the total number of lift/slide actuations applied to the window covering since the device " + + "was installed.", + xref: { document: "cluster", section: "5.3.6.6" } + }), + + Attribute({ + name: "NumberOfActuationsTilt", id: 0x6, type: "uint16", access: "R V", conformance: "[TL]", + default: 0, quality: "N", + details: "Indicates the total number of tilt actuations applied to the window covering since the device was " + + "installed.", + xref: { document: "cluster", section: "5.3.6.7" } + }), + + Attribute({ + name: "ConfigStatus", id: 0x7, type: "ConfigStatusBitmap", access: "R V", conformance: "M", + constraint: "desc", quality: "N", + details: "This attribute specifies the configuration and status information of the window covering." + + "\n" + + "To change settings, devices shall write to the Mode attribute. The behavior causing the setting or " + + "clearing of each bit is vendor specific.", + xref: { document: "cluster", section: "5.3.6.8" } + }), + + Attribute({ + name: "CurrentPositionLiftPercentage", id: 0x8, type: "percent", access: "R V", + conformance: "[LF & PA_LF]", default: null, quality: "X N P", + details: "Indicates the actual position as a percentage from 0% to 100% with 1% default step. This attribute " + + "is equal to CurrentPositionLiftPercent100ths attribute divided by 100.", + xref: { document: "cluster", section: "5.3.6.11" } + }), + + Attribute({ + name: "CurrentPositionTiltPercentage", id: 0x9, type: "percent", access: "R V", + conformance: "[TL & PA_TL]", default: null, quality: "X N P", + details: "Indicates the actual position as a percentage from 0% to 100% with 1% default step. This attribute " + + "is equal to CurrentPositionTiltPercent100ths attribute divided by 100.", + xref: { document: "cluster", section: "5.3.6.12" } + }), + + Attribute({ + name: "OperationalStatus", id: 0xa, type: "OperationalStatusBitmap", access: "R V", + conformance: "M", default: 0, quality: "P", + details: "Indicates the currently ongoing operations and applies to all type of devices.", + xref: { document: "cluster", section: "5.3.6.15" } + }), + + Attribute({ + name: "TargetPositionLiftPercent100ths", id: 0xb, type: "percent100ths", access: "R V", + conformance: "LF & PA_LF", default: null, quality: "X P", + details: "Indicates the position where the window covering lift will go or is moving to as a percentage (Unit " + + "0.01%).", + xref: { document: "cluster", section: "5.3.6.13" } + }), + + Attribute({ + name: "TargetPositionTiltPercent100ths", id: 0xc, type: "percent100ths", access: "R V", + conformance: "TL & PA_TL", default: null, quality: "X P", + details: "Indicates the position where the window covering tilt will go or is moving to as a percentage (Unit " + + "0.01%).", + xref: { document: "cluster", section: "5.3.6.14" } + }), + + Attribute({ + name: "EndProductType", id: 0xd, type: "EndProductTypeEnum", access: "R V", conformance: "M", + constraint: "desc", default: 0, quality: "F", + details: "This attribute SHOULD provide more detail about the product type than can be determined from the " + + "main category indicated by the Type attribute." + + "\n" + + "The table below helps to match the EndProductType attribute with the Type attribute.", + xref: { document: "cluster", section: "5.3.6.16" } + }), + + Attribute({ + name: "CurrentPositionLiftPercent100ths", id: 0xe, type: "percent100ths", access: "R V", + conformance: "LF & PA_LF", constraint: "max 10000", default: null, quality: "X N P", + details: "Indicates the actual position as a percentage with a minimal step of 0.01%. E.g Max 10000 equals " + + "100.00%.", + xref: { document: "cluster", section: "5.3.6.9" } + }), + + Attribute({ + name: "CurrentPositionTiltPercent100ths", id: 0xf, type: "percent100ths", access: "R V", + conformance: "TL & PA_TL", constraint: "max 10000", default: null, quality: "X N P", + details: "Indicates the actual position as a percentage with a minimal step of 0.01%. E.g Max 10000 equals " + + "100.00%.", + xref: { document: "cluster", section: "5.3.6.10" } + }), + + Attribute({ + name: "InstalledOpenLimitLift", id: 0x10, type: "uint16", access: "R V", + conformance: "LF & PA_LF & ABS", constraint: "max 65534", default: 0, quality: "N", + details: "Indicates the open limit for lifting the window covering whether position (in centimeters) is " + + "encoded or timed.", + xref: { document: "cluster", section: "5.3.6.17" } + }), + + Attribute({ + name: "InstalledClosedLimitLift", id: 0x11, type: "uint16", access: "R V", + conformance: "LF & PA_LF & ABS", constraint: "max 65534", default: 65534, quality: "N", + details: "Indicates the closed limit for lifting the window covering whether position (in centimeters) is " + + "encoded or timed.", + xref: { document: "cluster", section: "5.3.6.18" } + }), + + Attribute({ + name: "InstalledOpenLimitTilt", id: 0x12, type: "uint16", access: "R V", + conformance: "TL & PA_TL & ABS", constraint: "max 65534", default: 0, quality: "N", + details: "Indicates the open limit for tilting the window covering whether position (in tenth of a degree) is " + + "encoded or timed.", + xref: { document: "cluster", section: "5.3.6.19" } + }), + + Attribute({ + name: "InstalledClosedLimitTilt", id: 0x13, type: "uint16", access: "R V", + conformance: "TL & PA_TL & ABS", constraint: "max 65534", default: 65534, quality: "N", + details: "Indicates the closed limit for tilting the window covering whether position (in tenth of a degree) " + + "is encoded or timed.", + xref: { document: "cluster", section: "5.3.6.20" } + }), + + Attribute({ name: "VelocityLift", id: 0x14, conformance: "D", xref: { document: "cluster", section: "5.3.6" } }), + Attribute({ name: "AccelerationTimeLift", id: 0x15, conformance: "D", xref: { document: "cluster", section: "5.3.6" } }), + Attribute({ name: "DecelerationTimeLift", id: 0x16, conformance: "D", xref: { document: "cluster", section: "5.3.6" } }), + + Attribute({ + name: "Mode", id: 0x17, type: "ModeBitmap", access: "RW VM", conformance: "M", default: 0, + quality: "N", + + details: "The Mode attribute allows configuration of the window covering, such as: reversing the motor " + + "direction, placing the window covering into calibration mode, placing the motor into maintenance " + + "mode, disabling the network, and disabling status LEDs." + + "\n" + + "In the case a device does not support or implement a specific mode, e.g. the device has a specific " + + "installation method and reversal is not relevant or the device does not include a maintenance mode, " + + "any write interaction to the Mode attribute, with an unsupported mode bit or any out of bounds bits " + + "set, must be ignored and a response containing the status of CONSTRAINT_ERROR will be returned.", + + xref: { document: "cluster", section: "5.3.6.21" } + }), + + Attribute({ + name: "IntermediateSetpointsLift", id: 0x18, conformance: "D", + xref: { document: "cluster", section: "5.3.6" } + }), + Attribute({ + name: "IntermediateSetpointsTilt", id: 0x19, conformance: "D", + xref: { document: "cluster", section: "5.3.6" } + }), + + Attribute({ + name: "SafetyStatus", id: 0x1a, type: "SafetyStatusBitmap", access: "R V", conformance: "O", + constraint: "desc", default: 0, quality: "P", + details: "The SafetyStatus attribute reflects the state of the safety sensors and the common issues " + + "preventing movements. By default for nominal operation all flags are cleared (0). A device might " + + "support none, one or several bit flags from this attribute (all optional).", + xref: { document: "cluster", section: "5.3.6.22" } + }), + + Command({ + name: "UpOrOpen", id: 0x0, access: "O", conformance: "M", direction: "request", response: "status", + + details: "Upon receipt of this command, the window covering will adjust its position so the physical " + + "lift/slide and tilt is at the maximum open/up position. This will happen as fast as possible. The " + + "server attributes shall be updated as follows:" + + "\n" + + "if the PositionAware feature is supported:" + + "\n" + + " • TargetPositionLiftPercent100ths attribute shall be set to 0.00%." + + "\n" + + " • TargetPositionTiltPercent100ths attribute shall be set to 0.00%." + + "\n" + + "The server positioning attributes will follow the movements, once the movement has successfully " + + "finished, the server attributes shall be updated as follows:" + + "\n" + + "if the PositionAware feature is supported:" + + "\n" + + " • CurrentPositionLiftPercent100ths attribute shall be 0.00%." + + "\n" + + " • CurrentPositionLiftPercentage attribute shall be 0%." + + "\n" + + " • CurrentPositionTiltPercent100ths attribute shall be 0.00%." + + "\n" + + " • CurrentPositionTiltPercentage attribute shall be 0%. if the AbsolutePosition feature is " + + " supported:" + + "\n" + + " • CurrentPositionLift attribute shall be equal to the InstalledOpenLimitLift attribute." + + "\n" + + " • CurrentPositionTilt attribute shall be equal to the InstalledOpenLimitTilt attribute.", + + xref: { document: "cluster", section: "5.3.7.1" } + }), + + Command({ + name: "DownOrClose", id: 0x1, access: "O", conformance: "M", direction: "request", + response: "status", + + details: "Upon receipt of this command, the window covering will adjust its position so the physical " + + "lift/slide and tilt is at the maximum closed/down position. This will happen as fast as possible. " + + "The server attributes supported shall be updated as follows:" + + "\n" + + "if the PositionAware feature is supported:" + + "\n" + + " • TargetPositionLiftPercent100ths attribute shall be set to 100.00%." + + "\n" + + " • TargetPositionTiltPercent100ths attribute shall be set to 100.00%." + + "\n" + + "The server positioning attributes will follow the movements, once the movement has successfully " + + "finished, the server attributes shall be updated as follows:" + + "\n" + + "if the PositionAware feature is supported:" + + "\n" + + " • CurrentPositionLiftPercent100ths attribute shall be 100.00%." + + "\n" + + " • CurrentPositionLiftPercentage attribute shall be 100%." + + "\n" + + " • CurrentPositionTiltPercent100ths attribute shall be 100.00%." + + "\n" + + " • CurrentPositionTiltPercentage attribute shall be 100%. if the AbsolutePosition feature is " + + " supported:" + + "\n" + + " • CurrentPositionLift attribute shall be equal to the InstalledClosedLimitLift attribute." + + "\n" + + " • CurrentPositionTilt attribute shall be equal to the InstalledClosedLimitTilt attribute.", + + xref: { document: "cluster", section: "5.3.7.2" } + }), + + Command({ + name: "StopMotion", id: 0x2, access: "O", conformance: "M", direction: "request", + response: "status", + + details: "Upon receipt of this command, the window covering will stop any adjusting to the physical tilt and " + + "lift/slide that is currently occurring. The server attributes supported shall be updated as follows:" + + "\n" + + " • TargetPositionLiftPercent100ths attribute will be set to CurrentPositionLiftPercent100ths " + + " attribute value." + + "\n" + + " • TargetPositionTiltPercent100ths attribute will be set to CurrentPositionTiltPercent100ths " + + " attribute value.", + + xref: { document: "cluster", section: "5.3.7.3" } + }), + + Command( + { + name: "GoToLiftValue", id: 0x4, access: "O", conformance: "[LF & ABS]", direction: "request", + response: "status", + xref: { document: "cluster", section: "5.3.7.4" } + }, + Field({ + name: "LiftValue", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall specify the requested physical lift/slide position in unit cm (centimeters).", + xref: { document: "cluster", section: "5.3.7.4.1" } + }) + ), + + Command( + { + name: "GoToLiftPercentage", id: 0x5, access: "O", conformance: "LF & PA_LF, [LF]", + direction: "request", response: "status", + + details: "Upon receipt of this command, the server will adjust the window covering to the lift/slide " + + "percentage specified in the payload of this command." + + "\n" + + "If the command includes LiftPercent100thsValue, then TargetPositionLiftPercent100ths attribute " + + "shall be set to LiftPercent100thsValue. Otherwise the TargetPositionLiftPercent100ths attribute " + + "shall be set to LiftPercentageValue * 100." + + "\n" + + "If a client includes LiftPercent100thsValue in the command, the LiftPercentageValue shall be set to " + + "LiftPercent100thsValue / 100, so a legacy server which only supports LiftPercentageValue (not " + + "LiftPercent100thsValue) has a value to set the target position." + + "\n" + + "If the server does not support the PositionAware feature, then a zero percentage shall be treated " + + "as a UpOrOpen command and a non-zero percentage shall be treated as an DownOrClose command. If the " + + "device is only a tilt control device, then the command SHOULD be ignored and a UNSUPPORTED_COMMAND " + + "status SHOULD be returned.", + + xref: { document: "cluster", section: "5.3.7.5" } + }, + + Field({ name: "LiftPercent100thsValue", id: 0x0, type: "percent100ths", conformance: "M", constraint: "desc" }) + ), + + Command( + { + name: "GoToTiltValue", id: 0x7, access: "O", conformance: "[TL & ABS]", direction: "request", + response: "status", + xref: { document: "cluster", section: "5.3.7.6" } + }, + Field({ + name: "TiltValue", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall specify the requested physical tilt position in unit 0.1° (tenth of a degrees).", + xref: { document: "cluster", section: "5.3.7.6.1" } + }) + ), + + Command( + { + name: "GoToTiltPercentage", id: 0x8, access: "O", conformance: "TL & PA_TL, [TL]", + direction: "request", response: "status", + + details: "Upon receipt of this command, the server will adjust the window covering to the tilt percentage " + + "specified in the payload of this command." + + "\n" + + "If the command includes TiltPercent100thsValue, then TargetPositionTiltPercent100ths attribute " + + "shall be set to TiltPercent100thsValue. Otherwise the TargetPositionTiltPercent100ths attribute " + + "shall be set to TiltPercentageValue * 100." + + "\n" + + "If a client includes TiltPercent100thsValue in the command, the TiltPercentageValue shall be set to " + + "TiltPercent100thsValue / 100, so a legacy server which only supports TiltPercentageValue (not " + + "TiltPercent100thsValue) has a value to set the target position." + + "\n" + + "If the server does not support the PositionAware feature, then a zero percentage shall be treated " + + "as a UpOrOpen command and a non-zero percentage shall be treated as an DownOrClose command. If the " + + "device is only a tilt control device, then the command SHOULD be ignored and a UNSUPPORTED_COMMAND " + + "status SHOULD be returned.", + + xref: { document: "cluster", section: "5.3.7.7" } + }, + + Field({ name: "TiltPercent100thsValue", id: 0x0, type: "percent100ths", conformance: "M", constraint: "desc" }) + ), + + Datatype( + { name: "ConfigStatusBitmap", type: "map8", xref: { document: "cluster", section: "5.3.5.1" } }, + + Field( + { + name: "Operational", constraint: "0", description: "Device is operational.", + details: "This bit shall indicate whether the window covering is operational for regular use:" + + "\n" + + " • 0 = Not Operational" + + "\n" + + " • 1 = Operational", + xref: { document: "cluster", section: "5.3.5.1.1" } + } + ), + + Field({ name: "OnlineReserved", constraint: "1" }), + + Field( + { + name: "LiftMovementReversed", constraint: "2", description: "The lift movement is reversed.", + details: "This bit shall indicate whether the lift movement is reversed:" + + "\n" + + " • 0 = Lift movement is normal" + + "\n" + + " • 1 = Lift movement is reversed", + xref: { document: "cluster", section: "5.3.5.1.2" } + } + ), + + Field( + { + name: "LiftPositionAware", constraint: "3", + description: "Supports the PositionAwareLift feature (PA_LF).", + details: "This bit shall indicate whether the window covering supports the PositionAwareLift feature:" + + "\n" + + " • 0 = Lift control is not position aware" + + "\n" + + " • 1 = Lift control is position aware (PA_LF)", + xref: { document: "cluster", section: "5.3.5.1.3" } + } + ), + + Field( + { + name: "TiltPositionAware", constraint: "4", + description: "Supports the PositionAwareTilt feature (PA_TL).", + details: "This bit shall indicate whether the window covering supports the PositionAwareTilt feature:" + + "\n" + + " • 0 = Tilt control is not position aware" + + "\n" + + " • 1 = Tilt control is position aware (PA_TL)", + xref: { document: "cluster", section: "5.3.5.1.4" } + } + ), + + Field( + { + name: "LiftEncoderControlled", constraint: "5", description: "Uses an encoder for lift.", + + details: "This bit shall indicate whether a position aware controlled window covering is employing an encoder " + + "for positioning the height of the window covering:" + + "\n" + + " • 0 = Timer Controlled" + + "\n" + + " • 1 = Encoder Controlled", + + xref: { document: "cluster", section: "5.3.5.1.5" } + } + ), + + Field( + { + name: "TiltEncoderControlled", constraint: "6", description: "Uses an encoder for tilt.", + + details: "This bit shall indicate whether a position aware controlled window covering is employing an encoder " + + "for tilting the window covering:" + + "\n" + + " • 0 = Timer Controlled" + + "\n" + + " • 1 = Encoder Controlled", + + xref: { document: "cluster", section: "5.3.5.1.6" } + } + ) + ), + + Datatype( + { name: "ModeBitmap", type: "map8", xref: { document: "cluster", section: "5.3.5.2" } }, + + Field( + { + name: "MotorDirectionReversed", constraint: "0", description: "Reverse the lift direction.", + details: "This bit shall control the motor direction:" + + "\n" + + " • 0 = Lift movement is normal" + + "\n" + + " • 1 = Lift movement is reversed", + xref: { document: "cluster", section: "5.3.5.2.1" } + } + ), + + Field( + { + name: "CalibrationMode", constraint: "1", description: "Perform a calibration.", + details: "This bit shall set the window covering into calibration mode:" + + "\n" + + " • 0 = Normal mode" + + "\n" + + " • 1 = Calibration mode", + xref: { document: "cluster", section: "5.3.5.2.2" } + } + ), + + Field( + { + name: "MaintenanceMode", constraint: "2", description: "Freeze all motions for maintenance.", + details: "This bit shall set the window covering into maintenance mode:" + + "\n" + + " • 0 = Normal mode" + + "\n" + + " • 1 = Maintenance mode", + xref: { document: "cluster", section: "5.3.5.2.3" } + } + ), + + Field( + { + name: "LedFeedback", constraint: "3", description: "Control the LEDs feedback.", + details: "This bit shall control feedback LEDs:" + + "\n" + + " • 0 = LEDs are off" + + "\n" + + " • 1 = LEDs will display feedback", + xref: { document: "cluster", section: "5.3.5.2.4" } + } + ) + ), + + Datatype( + { + name: "OperationalStatusBitmap", type: "map8", + + details: "The OperationalStatusBitmap is using several internal operational state fields (composed of 2 bits) " + + "following this definition:" + + "\n" + + " • 00b = Currently not moving" + + "\n" + + " • 01b = Currently opening (e.g. moving from closed to open)." + + "\n" + + " • 10b = Currently closing (e.g. moving from open to closed)." + + "\n" + + " • 11b = Reserved", + + xref: { document: "cluster", section: "5.3.5.3" } + }, + + Field({ + name: "Global", constraint: "1 to 1", description: "Global operational state.", + details: "These bits shall indicate in which direction the covering is currently moving or if it has stopped. " + + "Global operational state shall always reflect the overall motion of the device.", + xref: { document: "cluster", section: "5.3.5.3.1" } + }), + + Field({ + name: "Lift", constraint: "3 to 3", description: "Lift operational state.", + details: "These bits shall indicate in which direction the covering’s lift is currently moving or if it has " + + "stopped.", + xref: { document: "cluster", section: "5.3.5.3.2" } + }), + + Field({ + name: "Tilt", constraint: "5 to 5", description: "Tilt operational state.", + details: "These bits shall indicate in which direction the covering’s tilt is currently moving or if it has " + + "stopped.", + xref: { document: "cluster", section: "5.3.5.3.3" } + }) + ), + + Datatype( + { name: "SafetyStatusBitmap", type: "map16", xref: { document: "cluster", section: "5.3.5.4" } }, + Field({ + name: "RemoteLockout", constraint: "0", + description: "Movement commands are ignored (locked out). e.g. not granted authorization, outside some time/date range." + }), + Field({ + name: "TamperDetection", constraint: "1", + description: "Tampering detected on sensors or any other safety equipment. Ex: a device has been forcedly moved without its actuator(s)." + }), + Field({ + name: "FailedCommunication", constraint: "2", + description: "Communication failure to sensors or other safety equipment." + }), + Field({ + name: "PositionFailure", constraint: "3", + description: "Device has failed to reach the desired position. e.g. with position aware device, time expired before TargetPosition is reached." + }), + Field({ + name: "ThermalProtection", constraint: "4", + description: "Motor(s) and/or electric circuit thermal protection activated." + }), + Field({ name: "ObstacleDetected", constraint: "5", description: "An obstacle is preventing actuator movement." }), + Field({ + name: "Power", constraint: "6", + description: "Device has power related issue or limitation e.g. device is running w/ the help of a backup battery or power might not be fully available at the moment." + }), + Field({ + name: "StopInput", constraint: "7", + description: "Local safety sensor (not a direct obstacle) is preventing movements (e.g. Safety EU Standard EN60335)." + }), + Field({ + name: "MotorJammed", constraint: "8", + description: "Mechanical problem related to the motor(s) detected." + }), + Field({ name: "HardwareFailure", constraint: "9", description: "PCB, fuse and other electrics problems." }), + Field({ + name: "ManualOperation", constraint: "10", + description: "Actuator is manually operated and is preventing actuator movement (e.g. actuator is disengaged/decoupled)." + }), + Field({ name: "Protection", constraint: "11", description: "Protection is activated." }) + ), + + Datatype( + { name: "TypeEnum", type: "enum8", xref: { document: "cluster", section: "5.3.5.5" } }, + Field({ name: "RollerShade", id: 0x0, conformance: "LF", description: "RollerShade" }), + Field({ name: "RollerShade2Motor", id: 0x1, conformance: "LF", description: "RollerShade - 2 Motor" }), + Field({ name: "RollerShadeExterior", id: 0x2, conformance: "LF", description: "RollerShade - Exterior" }), + Field({ + name: "RollerShadeExterior2Motor", id: 0x3, conformance: "LF", + description: "RollerShade - Exterior - 2 Motor" + }), + Field({ name: "Drapery", id: 0x4, conformance: "LF", description: "Drapery (curtain)" }), + Field({ name: "Awning", id: 0x5, conformance: "LF", description: "Awning" }), + Field({ name: "Shutter", id: 0x6, conformance: "LF | TL", description: "Shutter" }), + Field({ name: "TiltBlindTiltOnly", id: 0x7, conformance: "TL", description: "Tilt Blind - Tilt Only" }), + Field({ name: "TiltBlindLiftAndTilt", id: 0x8, conformance: "LF & TL", description: "Tilt Blind - Lift & Tilt" }), + Field({ name: "ProjectorScreen", id: 0x9, conformance: "LF", description: "Projector Screen" }), + Field({ name: "Unknown", id: 0xff, conformance: "O", description: "Unknown" }) + ), + + Datatype( + { name: "EndProductTypeEnum", type: "enum8", xref: { document: "cluster", section: "5.3.5.6" } }, + Field({ name: "RollerShade", id: 0x0, conformance: "LF", description: "Simple Roller Shade" }), + Field({ name: "RomanShade", id: 0x1, conformance: "LF", description: "Roman Shade" }), + Field({ name: "BalloonShade", id: 0x2, conformance: "LF", description: "Balloon Shade" }), + Field({ name: "WovenWood", id: 0x3, conformance: "LF", description: "Woven Wood" }), + Field({ name: "PleatedShade", id: 0x4, conformance: "LF", description: "Pleated Shade" }), + Field({ name: "CellularShade", id: 0x5, conformance: "LF", description: "Cellular Shade" }), + Field({ name: "LayeredShade", id: 0x6, conformance: "LF", description: "Layered Shade" }), + Field({ name: "LayeredShade2D", id: 0x7, conformance: "LF", description: "Layered Shade 2D" }), + Field({ name: "SheerShade", id: 0x8, conformance: "LF & TL", description: "Sheer Shade" }), + Field({ name: "TiltOnlyInteriorBlind", id: 0x9, conformance: "TL", description: "Tilt Only Interior Blind" }), + Field({ name: "InteriorBlind", id: 0xa, conformance: "LF & TL", description: "Interior Blind" }), + Field({ + name: "VerticalBlindStripCurtain", id: 0xb, conformance: "LF & TL", + description: "Vertical Blind, Strip Curtain" + }), + Field({ name: "InteriorVenetianBlind", id: 0xc, conformance: "LF & TL", description: "Interior Venetian Blind" }), + Field({ name: "ExteriorVenetianBlind", id: 0xd, conformance: "LF & TL", description: "Exterior Venetian Blind" }), + Field({ name: "LateralLeftCurtain", id: 0xe, conformance: "LF", description: "Lateral Left Curtain" }), + Field({ name: "LateralRightCurtain", id: 0xf, conformance: "LF", description: "Lateral Right Curtain" }), + Field({ name: "CentralCurtain", id: 0x10, conformance: "LF", description: "Central Curtain" }), + Field({ name: "RollerShutter", id: 0x11, conformance: "LF", description: "Roller Shutter" }), + Field({ name: "ExteriorVerticalScreen", id: 0x12, conformance: "LF", description: "Exterior Vertical Screen" }), + Field({ name: "AwningTerracePatio", id: 0x13, conformance: "LF", description: "Awning Terrace (Patio)" }), + Field({ name: "AwningVerticalScreen", id: 0x14, conformance: "LF", description: "Awning Vertical Screen" }), + Field({ name: "TiltOnlyPergola", id: 0x15, conformance: "LF | TL", description: "Tilt Only Pergola" }), + Field({ name: "SwingingShutter", id: 0x16, conformance: "LF | TL", description: "Swinging Shutter" }), + Field({ name: "SlidingShutter", id: 0x17, conformance: "LF | TL", description: "Sliding Shutter" }), + Field({ name: "Unknown", id: 0xff, conformance: "O", description: "Unknown" }) + ) + ), + + Cluster( + { + name: "AccountLogin", id: 0x50e, classification: "application", pics: "ALOGIN", + + details: "This cluster provides commands that facilitate user account login on a Content App or a node. For " + + "example, a Content App running on a Video Player device, which is represented as an endpoint (see " + + "Device Type Library document), can use this cluster to help make the user account on the Content " + + "App match the user account on the Client." + + "\n" + + "Often a fabric administrator will facilitate commissioning of a Client (such as a Casting Video " + + "Client), and invoke commands on the AccountLogin cluster on the Content App associated with that " + + "client. Specifically:" + + "\n" + + " 1. GetSetupPIN in order to attempt to obtain the Passcode for commissioning." + + "\n" + + " 2. Login in order to let the Content App know that commissioning has completed. The Content App " + + " can use information provided in this command in order to determine the user account associated " + + " with the client, and potentially assume that user account." + + "\n" + + " 3. Logout in order to let the Content App know that client access has been removed, and " + + " potentially clear the current user account." + + "\n" + + "The cluster server for this cluster may be supported on each endpoint that represents a Content App " + + "on a Video Player device." + + "\n" + + "See Device Type Library document for details of how a Content App, represented as an endpoint on" + + "\n" + + "the Video Player device, may implement the cluster server for this cluster to simplify account " + + "login for its users.", + + xref: { document: "cluster", section: "6.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Event( + { + name: "LoggedOut", id: 0x0, access: "S A", conformance: "O", priority: "critical", + details: "This event can be used by the Content App to indicate that the current user has logged out. In " + + "response to this event, the Fabric Admin shall remove access to this Content App by the specified " + + "Node. If no Node is provided, then the Fabric Admin shall remove access to all non-Admin Nodes.", + xref: { document: "cluster", section: "6.2.5.1" } + }, + + Field({ + name: "Node", id: 0x0, type: "node-id", conformance: "O", + details: "This field shall provide the Node ID corresponding to the user account that has logged out, if that " + + "Node ID is available. If it is NOT available, this field shall NOT be present in the event.", + xref: { document: "cluster", section: "6.2.5.1.1" } + }) + ), + + Command( + { + name: "GetSetupPin", id: 0x0, access: "F A T", conformance: "M", direction: "request", + response: "GetSetupPinResponse", + + details: "The purpose of this command is to determine if the active user account of the given Content App " + + "matches the active user account of a given Commissionee, and when it does, return a Setup PIN code " + + "which can be used for password-authenticated session establishment (PASE) with the Commissionee." + + "\n" + + "For example, a Video Player with a Content App Platform may invoke this command on one of its " + + "Content App endpoints to facilitate commissioning of a Phone App made by the same vendor as the " + + "Content App. If the accounts match, then the Content App may return a setup code that can be used" + + "\n" + + "by the Video Player to commission the Phone App without requiring the user to physically input a " + + "setup code." + + "\n" + + "The account match is determined by the Content App using a method which is outside the scope of " + + "this specification and will typically involve a central service which is in communication with both " + + "the Content App and the Commissionee. The GetSetupPIN command is needed in order to provide the " + + "Commissioner/Admin with a Setup PIN when this Commissioner/Admin is operated by a different vendor " + + "from the Content App." + + "\n" + + "This method is used to facilitate Setup PIN exchange (for PASE) between Commissioner and " + + "Commissionee when the same user account is active on both nodes. With this method, the Content App " + + "satisfies proof of possession related to commissioning by requiring the same user account to be " + + "active on both Commissionee and Content App, while the Commissioner/Admin ensures user consent by " + + "prompting the user prior to invocation of the command." + + "\n" + + "Upon receipt of this command, the Content App checks if the account associated with the Temporary " + + "Account Identifier sent by the client is the same account that is active on itself. If the accounts " + + "are the same, then the Content App returns the GetSetupPIN Response which includes a Setup PIN that " + + "may be used for PASE with the Commissionee." + + "\n" + + "The Temporary Account Identifier for a Commissionee may be populated with the Rotating ID field of " + + "the client’s commissionable node advertisement (see Rotating Device Identifier section in " + + "[MatterCore]) encoded as an octet string where the octets of the Rotating Device Identifier are " + + "encoded as 2-character sequences by representing each octet’s value as a 2-digit hexadecimal " + + "number, using uppercase letters." + + "\n" + + "The Setup PIN is a character string so that it can accommodate different future formats, including " + + "alpha-numeric encodings. For a Commissionee it shall be populated with the Manual Pairing Code (see " + + "Manual Pairing Code section in [MatterCore]) encoded as a string (11 characters) or the Passcode " + + "portion of the Manual Pairing Code (when less than 11 characters) ." + + "\n" + + "The server shall implement rate limiting to prevent brute force attacks. No more than 10 unique " + + "requests in a 10 minute period shall be allowed; a command response status of FAILURE should sent " + + "for additional commands received within the 10 minute period. Because access to this command is " + + "limited to nodes with Admin-level access, and the user is prompted for consent prior to " + + "Commissioning, there are in place multiple obstacles to successfully mounting a brute force attack. " + + "A Content App that supports this command shall ensure that the Temporary Account Identifier used by " + + "its clients is not valid for more than 10 minutes.", + + xref: { document: "cluster", section: "6.2.4.1" } + }, + + Field({ + name: "TempAccountIdentifier", id: 0x0, type: "string", conformance: "M", constraint: "16 to 100", + details: "This field shall specify the client’s Temporary Account Identifier. The length of this field shall " + + "be at least 16 characters to protect the account holder against password guessing attacks.", + xref: { document: "cluster", section: "6.2.4.1.1" } + }) + ), + + Command( + { + name: "GetSetupPinResponse", id: 0x1, access: "F", conformance: "M", direction: "response", + details: "This message is sent in response to the GetSetupPIN command, and contains the Setup PIN code, or " + + "null when the account identified in the request does not match the active account of the running " + + "Content App.", + xref: { document: "cluster", section: "6.2.4.2" } + }, + + Field({ + name: "SetupPin", id: 0x0, type: "string", conformance: "M", constraint: "desc", + + details: "This field shall provide the setup PIN code as a text string at least 8 characters in length or " + + "empty string to indicate that the accounts do not match." + + "\n" + + "NOTE" + + "\n" + + "Newer cluster clients should be aware that AccountLogin cluster version 1 specified an 11 digit " + + "minimum length.", + + xref: { document: "cluster", section: "6.2.4.2.1" } + }) + ), + + Command( + { + name: "Login", id: 0x2, access: "F A T", conformance: "M", direction: "request", response: "status", + + details: "The purpose of this command is to allow the Content App to assume the user account of a given " + + "Commissionee by leveraging the Setup PIN code input by the user during the commissioning process." + + "\n" + + "For example, a Video Player with a Content App Platform may invoke this command on one of its " + + "Content App endpoints after the commissioning has completed of a Phone App made by the same vendor " + + "as the Content App. The Content App may determine whether the Temporary Account Identifier maps to " + + "an account with a corresponding Setup PIN and, if so, it may automatically login to the account for " + + "the corresponding user. The end result is that a user performs commissioning of a Phone App to a " + + "Video Player by inputting the Setup PIN for the Phone App into the Video Player UX. Once " + + "commissioning has completed, the Video Player invokes this command to allow the corresponding " + + "Content App to assume the same user account as the Phone App." + + "\n" + + "The verification of Setup PIN for the given Temporary Account Identifier is determined by the " + + "Content App using a method which is outside the scope of this specification and will typically " + + "involve a central service which is in communication with both the Content App and the Commissionee. " + + "Implementations of such a service should impose aggressive time outs for any mapping of Temporary " + + "Account Identifier to Setup PIN in order to prevent accidental login due to delayed invocation." + + "\n" + + "Upon receipt, the Content App checks if the account associated with the client’s Temp Account " + + "Identifier has a current active Setup PIN with the given value. If the Setup PIN is valid for the " + + "user account associated with the Temp Account Identifier, then the Content App may make that user " + + "account active." + + "\n" + + "The Temporary Account Identifier for a Commissionee may be populated with the Rotating ID field of " + + "the client’s commissionable node advertisement encoded as an octet string where the octets of the " + + "Rotating Device Identifier are encoded as 2-character sequences by representing each octet’s value " + + "as a 2-digit hexadecimal number, using uppercase letters." + + "\n" + + "The Setup PIN for a Commissionee may be populated with the Manual Pairing Code encoded as a string " + + "of decimal numbers (11 characters) or the Passcode portion of the Manual Pairing Code encoded as a " + + "string of decimal numbers (8 characters) ." + + "\n" + + "The server shall implement rate limiting to prevent brute force attacks. No more than 10 unique " + + "requests in a 10 minute period shall be allowed; a command response status of FAILURE should sent " + + "for additional commands received within the 10 minute period. Because access to this command is " + + "limited to nodes with Admin-level access, and the user is involved when obtaining the SetupPIN, " + + "there are in place multiple obstacles to successfully mounting a brute force attack. A Content App " + + "that supports this command shall ensure that the Temporary Account Identifier used by its clients " + + "is not valid for more than 10 minutes.", + + xref: { document: "cluster", section: "6.2.4.3" } + }, + + Field({ + name: "TempAccountIdentifier", id: 0x0, type: "string", conformance: "M", constraint: "16 to 100", + details: "This field shall specify the client’s temporary account identifier.", + xref: { document: "cluster", section: "6.2.4.3.1" } + }), + + Field({ + name: "SetupPin", id: 0x1, type: "string", conformance: "M", constraint: "min 8", + + details: "This field shall provide the setup PIN code as a text string at least 8 characters in length." + + "\n" + + "NOTE" + + "\n" + + "Newer cluster clients should be aware that AccountLogin cluster version 1 specified an 11 digit " + + "minimum length.", + + xref: { document: "cluster", section: "6.2.4.3.2" } + }), + + Field({ + name: "Node", id: 0x2, type: "node-id", conformance: "O", + details: "This optional field shall provide the Node ID of the Client. This field can be used by the Content " + + "App to keep track of Nodes which currently have access to it.", + xref: { document: "cluster", section: "6.2.4.3.3" } + }) + ), + + Command( + { + name: "Logout", id: 0x3, access: "F O T", conformance: "M", direction: "request", + response: "status", + details: "The purpose of this command is to instruct the Content App to clear the current user account. This " + + "command SHOULD be used by clients of a Content App to indicate the end of a user session.", + xref: { document: "cluster", section: "6.2.4.4" } + }, + + Field({ + name: "Node", id: 0x0, type: "node-id", conformance: "O", + details: "This optional field shall provide the Node ID of the Client. This field can be used by the Content" + + "\n" + + "App to keep track of Nodes which currently have access to it.", + xref: { document: "cluster", section: "6.2.4.4.1" } + }) + ) + ), + + Cluster( + { + name: "ApplicationBasic", id: 0x50d, classification: "application", pics: "APBSC", + + details: "This cluster provides information about a Content App running on a Video Player device which is " + + "represented as an endpoint (see Device Type Library document)." + + "\n" + + "The cluster server for this cluster should be supported on each endpoint that represents a Content " + + "App on a Video Player device. This cluster provides identification information about the Content " + + "App such as vendor and product.", + + xref: { document: "cluster", section: "6.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "VendorName", id: 0x0, type: "string", access: "R V", conformance: "O", constraint: "max 32", + quality: "F", + details: "This attribute shall specify a human readable (displayable) name of the vendor for the Content App.", + xref: { document: "cluster", section: "6.3.5.1" } + }), + + Attribute({ + name: "VendorId", id: 0x1, type: "vendor-id", access: "R V", conformance: "O", quality: "F", + details: "This attribute, if present, shall specify the Connectivity Standards Alliance assigned Vendor ID " + + "for the Content App.", + xref: { document: "cluster", section: "6.3.5.2" } + }), + + Attribute({ + name: "ApplicationName", id: 0x2, type: "string", access: "R V", conformance: "M", + constraint: "desc", quality: "F", + details: "This attribute shall specify a human readable (displayable) name of the Content App assigned by the " + + "vendor. For example, \"NPR On Demand\". The maximum length of the ApplicationName attribute is 256 " + + "bytes of UTF-8 characters.", + xref: { document: "cluster", section: "6.3.5.3" } + }), + + Attribute({ + name: "ProductId", id: 0x3, type: "uint16", access: "R V", conformance: "O", quality: "F", + details: "This attribute, if present, shall specify a numeric ID assigned by the vendor to identify a " + + "specific Content App made by them. If the Content App is certified by the Connectivity Standards " + + "Alliance, then this would be the Product ID as specified by the vendor for the certification.", + xref: { document: "cluster", section: "6.3.5.4" } + }), + + Attribute({ + name: "Application", id: 0x4, type: "ApplicationStruct", access: "R V", conformance: "M", + constraint: "desc", quality: "F", + details: "This attribute shall specify a Content App which consists of an Application ID using a specified " + + "catalog.", + xref: { document: "cluster", section: "6.3.5.5" } + }), + + Attribute({ + name: "Status", id: 0x5, type: "ApplicationStatusEnum", access: "R V", conformance: "M", + constraint: "desc", + details: "This attribute shall specify the current running status of the application.", + xref: { document: "cluster", section: "6.3.5.6" } + }), + + Attribute({ + name: "ApplicationVersion", id: 0x6, type: "string", access: "R V", conformance: "M", + constraint: "max 32", quality: "F", + details: "This attribute shall specify a human readable (displayable) version of the Content App assigned by " + + "the vendor. The maximum length of the ApplicationVersion attribute is 32 bytes of UTF-8 characters.", + xref: { document: "cluster", section: "6.3.5.7" } + }), + + Attribute( + { + name: "AllowedVendorList", id: 0x7, type: "list", access: "R A", conformance: "M", quality: "F", + details: "This attribute is a list of vendor IDs. Each entry is a vendor-id.", + xref: { document: "cluster", section: "6.3.5.8" } + }, + Field({ name: "entry", type: "vendor-id" }) + ), + + Datatype( + { name: "ApplicationStatusEnum", type: "enum8", xref: { document: "cluster", section: "6.3.4.1" } }, + Field({ name: "Stopped", id: 0x0, conformance: "M", description: "Application is not running." }), + Field({ + name: "ActiveVisibleFocus", id: 0x1, conformance: "M", + description: "Application is running, is visible to the user, and is the active target for input." + }), + Field({ + name: "ActiveHidden", id: 0x2, conformance: "M", + description: "Application is running but not visible to the user." + }), + Field({ + name: "ActiveVisibleNotFocus", id: 0x3, conformance: "M", + description: "Application is running and visible, but is not the active target for input." + }) + ), + + Datatype( + { + name: "ApplicationStruct", type: "struct", + details: "This indicates a global identifier for an Application given a catalog.", + xref: { document: "cluster", section: "6.3.4.2" } + }, + + Field({ + name: "CatalogVendorId", id: 0x0, type: "uint16", conformance: "M", + + details: "This field shall indicate the Connectivity Standards Alliance issued vendor ID for the catalog. The " + + "DIAL registry shall use value 0x0000." + + "\n" + + "It is assumed that Content App Platform providers (see Video Player Architecture section in " + + "[MatterDevLib]) will have their own catalog vendor ID (set to their own Vendor ID) and will assign " + + "an ApplicationID to each Content App.", + + xref: { document: "cluster", section: "6.3.4.2.1" } + }), + + Field({ + name: "ApplicationId", id: 0x1, type: "string", conformance: "M", + details: "This field shall indicate the application identifier, expressed as a string, such as \"123456-5433\", " + + "\"PruneVideo\" or \"Company X\". This field shall be unique within a catalog." + + "\n" + + "For the DIAL registry catalog, this value shall be the DIAL prefix.", + xref: { document: "cluster", section: "6.3.4.2.2" } + }) + ) + ), + + Cluster( + { + name: "ApplicationLauncher", id: 0x50c, classification: "application", pics: "APPLAUNCHER", + + details: "This cluster provides an interface for launching applications on a Video Player device such as a TV." + + "\n" + + "This cluster is supported on endpoints that can launch Applications, such as a Casting Video Player " + + "device with a Content App Platform. It supports identifying an Application by global identifier " + + "from a given catalog, and launching it. It also supports tracking the currently in-focus " + + "Application." + + "\n" + + "Depending on the support for the Application Platform feature, the cluster can either support " + + "launching the application corresponding to the endpoint on which the cluster is supported (AP " + + "feature not supported) or it can support launching any application (AP feature supported).", + + xref: { document: "cluster", section: "6.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.4.4" } }, + Field({ + name: "AP", constraint: "0", description: "ApplicationPlatform", + details: "Support for attributes and commands required for endpoint to support launching any application " + + "within the supported application catalogs" + }) + ), + + Attribute( + { + name: "CatalogList", id: 0x0, type: "list", access: "R V", conformance: "AP", quality: "N", + + details: "This attribute shall specify the list of supported application catalogs, where each entry in the " + + "list is the CSA-issued vendor ID for the catalog. The DIAL registry (see [DIAL Registry]) shall use " + + "value 0x0000." + + "\n" + + "It is expected that Content App Platform providers will have their own catalog vendor ID (set to " + + "their own Vendor ID) and will assign an ApplicationID to each Content App.", + + xref: { document: "cluster", section: "6.4.6.1" } + }, + + Field({ name: "entry", type: "uint16" }) + ), + + Attribute({ + name: "CurrentApp", id: 0x1, type: "ApplicationEPStruct", access: "R V", conformance: "O", + constraint: "desc", default: null, quality: "X", + details: "This attribute shall specify the current in-focus application, identified using an Application ID, " + + "catalog vendor ID and the corresponding endpoint number when the application is represented by a " + + "Content App endpoint. A null shall be used to indicate there is no current in-focus application.", + xref: { document: "cluster", section: "6.4.6.2" } + }), + + Command( + { + name: "LaunchApp", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "LauncherResponse", + + details: "Upon receipt of this command, the server shall launch the application with optional data. The " + + "application shall be either" + + "\n" + + " • the specified application, if the Application Platform feature is supported;" + + "\n" + + " • otherwise the application corresponding to the endpoint." + + "\n" + + "The endpoint shall launch and bring to foreground the requisite application if the application is " + + "not already launched and in foreground. The Status attribute shall be updated to ActiveVisibleFocus " + + "on the Application Basic cluster of the Endpoint corresponding to the launched application. The " + + "Status attribute shall be updated on any other application whose Status may have changed as a " + + "result of this command. The CurrentApp attribute, if supported, shall be updated to reflect the new " + + "application in the foreground." + + "\n" + + "This command returns a Launcher Response.", + + xref: { document: "cluster", section: "6.4.7.1" } + }, + + Field({ + name: "Application", id: 0x0, type: "ApplicationStruct", conformance: "AP", constraint: "desc", + details: "This field shall specify the Application to launch.", + xref: { document: "cluster", section: "6.4.7.1.1" } + }), + + Field({ + name: "Data", id: 0x1, type: "octstr", conformance: "O", + + details: "This field shall specify optional app-specific data to be sent to the app." + + "\n" + + "NOTE" + + "\n" + + "This format and meaning of this value is proprietary and outside the specification. It provides a " + + "transition path for device makers that use other protocols (like DIAL) which allow for proprietary " + + "data. Apps that are not yet Matter aware can be launched via Matter, while retaining the existing " + + "ability to launch with proprietary data.", + + xref: { document: "cluster", section: "6.4.7.1.2" } + }) + ), + + Command( + { + name: "StopApp", id: 0x1, access: "O", conformance: "M", direction: "request", + response: "LauncherResponse", + + details: "Upon receipt of this command, the server shall stop the application if it is running. The " + + "application shall be either" + + "\n" + + " • the specified application, if the Application Platform feature is supported;" + + "\n" + + " • otherwise the application corresponding to the endpoint." + + "\n" + + "The Status attribute shall be updated to Stopped on the Application Basic cluster of the Endpoint " + + "corresponding to the stopped application. The Status attribute shall be updated on any other " + + "application whose Status may have changed as a result of this command." + + "\n" + + "This command returns a Launcher Response.", + + xref: { document: "cluster", section: "6.4.7.2" } + }, + + Field({ + name: "Application", id: 0x0, type: "ApplicationStruct", conformance: "AP", constraint: "desc", + details: "This field shall specify the Application to stop.", + xref: { document: "cluster", section: "6.4.7.2.1" } + }) + ), + + Command( + { + name: "HideApp", id: 0x2, access: "O", conformance: "M", direction: "request", + response: "LauncherResponse", + + details: "Upon receipt of this command, the server shall hide the application. The application shall be either" + + "\n" + + " • the specified application, if the Application Platform feature is supported;" + + "\n" + + " • otherwise the application corresponding to the endpoint." + + "\n" + + "The endpoint may decide to stop the application based on manufacturer specific behavior or resource " + + "constraints if any. The Status attribute shall be updated to ActiveHidden or Stopped, depending on " + + "the action taken, on the Application Basic cluster of the Endpoint corresponding to the application " + + "on which the action was taken. The Status attribute shall be updated on any other application whose " + + "Status may have changed as a result of this command." + + "\n" + + "This command returns a Launcher Response.", + + xref: { document: "cluster", section: "6.4.7.3" } + }, + + Field({ + name: "Application", id: 0x0, type: "ApplicationStruct", conformance: "AP", constraint: "desc", + details: "This field shall specify the Application to hide.", + xref: { document: "cluster", section: "6.4.7.3.1" } + }) + ), + + Command( + { + name: "LauncherResponse", id: 0x3, conformance: "M", direction: "response", + details: "This command shall be generated in response to LaunchApp/StopApp/HideApp commands.", + xref: { document: "cluster", section: "6.4.7.4" } + }, + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", + details: "This field shall indicate the status of the command which resulted in this response.", + xref: { document: "cluster", section: "6.4.7.4.1" } + }), + Field({ + name: "Data", id: 0x1, type: "octstr", conformance: "O", + details: "This field shall specify Optional app-specific data.", + xref: { document: "cluster", section: "6.4.7.4.2" } + }) + ), + + Datatype( + { name: "StatusEnum", type: "enum8", xref: { document: "cluster", section: "6.4.5.1" } }, + Field({ name: "Success", id: 0x0, conformance: "M", description: "Command succeeded" }), + Field({ name: "AppNotAvailable", id: 0x1, conformance: "M", description: "Requested app is not available" }), + Field({ name: "SystemBusy", id: 0x2, conformance: "M", description: "Video platform unable to honor command" }), + Field({ + name: "PendingUserApproval", id: 0x3, conformance: "M", + description: "User approval for app download is pending" + }), + Field({ name: "Downloading", id: 0x4, conformance: "M", description: "Downloading the requested app" }), + Field({ name: "Installing", id: 0x5, conformance: "M", description: "Installing the requested app" }) + ), + + Datatype( + { + name: "ApplicationStruct", type: "struct", + details: "This indicates a global identifier for an Application given a catalog.", + xref: { document: "cluster", section: "6.4.5.2" } + }, + + Field({ + name: "CatalogVendorId", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall indicate the CSA-issued vendor ID for the catalog. The DIAL registry shall use " + + "value 0x0000." + + "\n" + + "Content App Platform providers will have their own catalog vendor ID (set to their own Vendor ID) " + + "and will assign an ApplicationID to each Content App.", + xref: { document: "cluster", section: "6.4.5.2.1" } + }), + + Field({ + name: "ApplicationId", id: 0x1, type: "string", conformance: "M", + details: "This field shall indicate the application identifier, expressed as a string, such as \"PruneVideo\" " + + "or \"Company X\". This field shall be unique within a catalog." + + "\n" + + "For the DIAL registry catalog, this value shall be the DIAL prefix (see [DIAL Registry]).", + xref: { document: "cluster", section: "6.4.5.2.2" } + }) + ), + + Datatype( + { + name: "ApplicationEPStruct", type: "struct", + details: "This specifies an app along with its corresponding endpoint.", + xref: { document: "cluster", section: "6.4.5.3" } + }, + Field({ name: "Application", id: 0x0, type: "ApplicationStruct", conformance: "M" }), + Field({ name: "Endpoint", id: 0x1, type: "endpoint-no", conformance: "O" }) + ) + ), + + Cluster( + { + name: "AudioOutput", id: 0x50b, classification: "application", pics: "AUDIOOUTPUT", + + details: "This cluster provides an interface for controlling the Output on a Video Player device such as a TV." + + "\n" + + "This cluster would be supported on a device with audio outputs like a Video Player device (Smart " + + "TV, TV Setup Top Box, Smart Speaker, etc)." + + "\n" + + "This cluster provides the list of available outputs and provides commands for selecting and " + + "renaming them." + + "\n" + + "The cluster server for Audio Output is implemented by a device that has configurable audio output.", + + xref: { document: "cluster", section: "6.5" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.5.4" } }, + Field({ name: "NU", constraint: "0", description: "NameUpdates", details: "Supports updates to output names" }) + ), + + Attribute( + { + name: "OutputList", id: 0x0, type: "list", access: "R V", conformance: "M", + details: "This attribute provides the list of outputs supported by the device.", + xref: { document: "cluster", section: "6.5.6.1" } + }, + Field({ name: "entry", type: "OutputInfoStruct" }) + ), + + Attribute({ + name: "CurrentOutput", id: 0x1, type: "uint8", access: "R V", conformance: "M", + details: "This attribute contains the value of the index field of the currently selected OutputInfoStruct.", + xref: { document: "cluster", section: "6.5.6.2" } + }), + + Command( + { + name: "SelectOutput", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "status", + + details: "Upon receipt, this shall change the output on the device to the output at a specific index in the " + + "Output List." + + "\n" + + "Note that when the current output is set to an output of type HDMI, adjustments to volume via a " + + "Speaker endpoint on the same node may cause HDMI volume up/down commands to be sent to the given " + + "HDMI output.", + + xref: { document: "cluster", section: "6.5.7.1" } + }, + + Field({ + name: "Index", id: 0x0, type: "uint8", conformance: "M", + details: "This shall indicate the index field of the OutputInfoStruct from the OutputList attribute in which " + + "to change to.", + xref: { document: "cluster", section: "6.5.7.1.1" } + }) + ), + + Command( + { + name: "RenameOutput", id: 0x1, access: "M", conformance: "NU", direction: "request", + response: "status", + details: "Upon receipt, this shall rename the output at a specific index in the Output List." + + "\n" + + "Updates to the output name shall appear in the device’s settings menus. Name updates may " + + "automatically be sent to the actual device to which the output connects.", + xref: { document: "cluster", section: "6.5.7.2" } + }, + + Field({ name: "Index", id: 0x0, type: "uint8", conformance: "M" }), + Field({ name: "Name", id: 0x1, type: "string", conformance: "M" }) + ), + + Datatype( + { + name: "OutputTypeEnum", type: "enum8", + details: "The type of output, expressed as an enum, with the following values:", + xref: { document: "cluster", section: "6.5.5.1" } + }, + Field({ name: "Hdmi", id: 0x0, conformance: "M", description: "HDMI" }), + Field({ name: "Bt", id: 0x1, conformance: "M" }), + Field({ name: "Optical", id: 0x2, conformance: "M" }), + Field({ name: "Headphone", id: 0x3, conformance: "M" }), + Field({ name: "Internal", id: 0x4, conformance: "M" }), + Field({ name: "Other", id: 0x5, conformance: "M" }) + ), + + Datatype( + { + name: "OutputInfoStruct", type: "struct", + details: "This contains information about an output.", + xref: { document: "cluster", section: "6.5.5.2" } + }, + Field({ + name: "Index", id: 0x0, type: "uint8", conformance: "M", + details: "This field shall indicate the unique index into the list of outputs.", + xref: { document: "cluster", section: "6.5.5.2.1" } + }), + Field({ + name: "OutputType", id: 0x1, type: "OutputTypeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the type of output.", + xref: { document: "cluster", section: "6.5.5.2.2" } + }), + + Field({ + name: "Name", id: 0x2, type: "string", conformance: "M", + details: "The device defined and user editable output name, such as “Soundbar”, “Speakers”. This field may be " + + "blank, but SHOULD be provided when known.", + xref: { document: "cluster", section: "6.5.5.2.3" } + }) + ) + ), + + Cluster( + { + name: "Channel", id: 0x504, classification: "application", pics: "CHANNEL", + + details: "This cluster provides an interface for controlling the current Channel on a device or endpoint." + + "\n" + + "This cluster server would be supported on Video Player devices or endpoints that allow Channel " + + "control such as a Content App. This cluster provides a list of available channels and provides " + + "commands for absolute and relative channel changes. Some of these commands and/or their responses " + + "may be large (see Large Message Quality under Data Model section in [MatterCore]), but they do not " + + "have the Large quality indicator (L) because they can also be transferred over MRP (see Message " + + "Reliability Protocol in [MatterCore]) in pages that fit within the MRP MTU limit. However, an " + + "implementation may leverage a transport like TCP that allows large payloads, if available, to " + + "minimize the number of messages required to transfer the corresponding payload." + + "\n" + + "The cluster server for Channel is implemented by an endpoint that controls the current Channel.", + + xref: { document: "cluster", section: "6.6" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.6.4" } }, + Field({ + name: "CL", constraint: "0", description: "ChannelList", + details: "Provides list of available channels." + }), + Field({ + name: "LI", constraint: "1", description: "LineupInfo", + details: "Provides lineup info, which is a reference to an external source of lineup information." + }), + Field({ + name: "EG", constraint: "2", description: "ElectronicGuide", + details: "Provides electronic program guide information." + }), + Field({ + name: "RP", constraint: "3", description: "RecordProgram", + details: "Provides ability to record program." + }) + ), + + Attribute( + { + name: "ChannelList", id: 0x0, type: "list", access: "R V", conformance: "CL", default: [], + details: "This attribute shall provide the list of supported channels.", + xref: { document: "cluster", section: "6.6.6.1" } + }, + Field({ name: "entry", type: "ChannelInfoStruct" }) + ), + + Attribute({ + name: "Lineup", id: 0x1, type: "LineupInfoStruct", access: "R V", conformance: "LI", + constraint: "desc", default: null, quality: "X", + details: "This attribute shall identify the channel lineup using external data sources.", + xref: { document: "cluster", section: "6.6.6.2" } + }), + + Attribute({ + name: "CurrentChannel", id: 0x2, type: "ChannelInfoStruct", access: "R V", conformance: "O", + constraint: "desc", default: null, quality: "X", + details: "This attribute shall contain the current channel. When supported but a channel is not currently " + + "tuned to (if a content application is in foreground), the value of the field shall be null.", + xref: { document: "cluster", section: "6.6.6.3" } + }), + + Command( + { + name: "ChangeChannel", id: 0x0, access: "O", conformance: "CL | LI", direction: "request", + response: "ChangeChannelResponse", + + details: "Change the channel to the channel case-insensitive exact matching the value passed as an argument." + + "\n" + + "The match priority order shall be: Identifier, AffiliateCallSign, CallSign, Name, Number. In the " + + "match string, the Channel number should be presented in the \"Major.Minor\" format, such as \"13.1\"." + + "\n" + + "Upon receipt, this shall generate a ChangeChannelResponse command." + + "\n" + + "Upon success, the CurrentChannel attribute, if supported, shall be updated to reflect the change.", + + xref: { document: "cluster", section: "6.6.7.1" } + }, + + Field({ + name: "Match", id: 0x0, type: "string", conformance: "M", + details: "This field shall contain a user-input string to match in order to identify the target channel.", + xref: { document: "cluster", section: "6.6.7.1.1" } + }) + ), + + Command( + { + name: "ChangeChannelResponse", id: 0x1, conformance: "CL | LI", direction: "response", + details: "This command shall be generated in response to a ChangeChannel command.", + xref: { document: "cluster", section: "6.6.7.2" } + }, + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the status of the command which resulted in this response.", + xref: { document: "cluster", section: "6.6.7.2.1" } + }), + Field({ + name: "Data", id: 0x1, type: "string", conformance: "O", constraint: "any", + details: "This field shall indicate Optional app-specific data.", + xref: { document: "cluster", section: "6.6.7.2.2" } + }) + ), + + Command( + { + name: "ChangeChannelByNumber", id: 0x2, access: "O", conformance: "M", direction: "request", + response: "status", + details: "Change the channel to the channel with the given Number in the ChannelList attribute.", + xref: { document: "cluster", section: "6.6.7.3" } + }, + + Field({ + name: "MajorNumber", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall indicate the channel major number value (ATSC format) to which the channel should " + + "change.", + xref: { document: "cluster", section: "6.6.7.3.1" } + }), + + Field({ + name: "MinorNumber", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall indicate the channel minor number value (ATSC format) to which the channel should " + + "change.", + xref: { document: "cluster", section: "6.6.7.3.2" } + }) + ), + + Command( + { + name: "SkipChannel", id: 0x3, access: "O", conformance: "M", direction: "request", + response: "status", + + details: "This command provides channel up and channel down functionality, but allows channel index jumps of " + + "size Count." + + "\n" + + "When the value of the increase or decrease is larger than the number of channels remaining in the " + + "given direction, then the behavior shall be to return to the beginning (or end) of the channel list " + + "and continue. For example, if the current channel is at index 0 and count value of -1 is given, " + + "then the current channel should change to the last channel.", + + xref: { document: "cluster", section: "6.6.7.4" } + }, + + Field({ + name: "Count", id: 0x0, type: "int16", conformance: "M", + details: "This field shall indicate the number of steps to increase (Count is positive) or decrease (Count is " + + "negative) the current channel.", + xref: { document: "cluster", section: "6.6.7.4.1" } + }) + ), + + Command( + { + name: "GetProgramGuide", id: 0x4, access: "O", conformance: "EG", direction: "request", + response: "ProgramGuideResponse", + details: "This command retrieves the program guide. It accepts several filter parameters to return specific " + + "schedule and program information from a content app. The command shall receive in response a " + + "ProgramGuideResponse. Standard error codes shall be used when arguments provided are not valid. For " + + "example, if StartTime is greater than EndTime, the status code INVALID_ACTION shall be returned.", + xref: { document: "cluster", section: "6.6.7.5" } + }, + + Field({ + name: "StartTime", id: 0x0, type: "epoch-s", conformance: "M", + details: "This field shall indicate the beginning of the time window for which program guide entries are to " + + "be retrieved, as a UTC time. Entries with a start time on or after this value will be included in " + + "the results.", + xref: { document: "cluster", section: "6.6.7.5.1" } + }), + + Field({ + name: "EndTime", id: 0x1, type: "epoch-s", conformance: "M", + details: "This field shall indicate the end of the time window for which program guide entries are to be " + + "retrieved, as a UTC time. Entries with an end time on or before this value will be included in the " + + "results. This field can represent a past or future value but shall be greater than the StartTime.", + xref: { document: "cluster", section: "6.6.7.5.2" } + }), + + Field( + { + name: "ChannelList", id: 0x2, type: "list", conformance: "O", constraint: "max 255", default: [], + details: "This field shall indicate the set of channels for which program guide entries should be fetched. By " + + "providing a list of channels in this field, the response will only include entries corresponding to " + + "the specified channels.", + xref: { document: "cluster", section: "6.6.7.5.3" } + }, + + Field({ name: "entry", type: "ChannelInfoStruct" }) + ), + + Field({ + name: "PageToken", id: 0x3, type: "PageTokenStruct", conformance: "O", default: null, quality: "X", + details: "This field shall indicate the pagination token used for managing pagination progression.", + xref: { document: "cluster", section: "6.6.7.5.4" } + }), + + Field({ + name: "RecordingFlag", id: 0x5, type: "RecordingFlagBitmap", conformance: "O", default: null, + quality: "X", + details: "This field shall indicate the flags of the programs for which entries should be fetched.", + xref: { document: "cluster", section: "6.6.7.5.5" } + }), + + Field( + { + name: "ExternalIdList", id: 0x6, type: "list", conformance: "O", constraint: "max 255", default: [], + details: "This field shall indicate the list of additional external content identifiers.", + xref: { document: "cluster", section: "6.6.7.5.6" } + }, + Field({ name: "entry", type: "ContentLauncher.AdditionalInfoStruct" }) + ), + + Field({ + name: "Data", id: 0x7, type: "octstr", conformance: "O", constraint: "max 8092", + details: "This field shall indicate Optional app-specific data.", + xref: { document: "cluster", section: "6.6.7.5.7" } + }) + ), + + Command( + { + name: "ProgramGuideResponse", id: 0x5, conformance: "EG", direction: "response", + details: "This command is a response to the GetProgramGuide command.", + xref: { document: "cluster", section: "6.6.7.6" } + }, + + Field({ + name: "Paging", id: 0x0, type: "ChannelPagingStruct", conformance: "M", + details: "This field shall indicate the necessary pagination attributes that define information for both the " + + "succeeding and preceding data pages.", + xref: { document: "cluster", section: "6.6.7.6.1" } + }), + + Field( + { + name: "ProgramList", id: 0x1, type: "list", conformance: "M", default: [], + details: "This field shall indicate the list of programs.", + xref: { document: "cluster", section: "6.6.7.6.2" } + }, + Field({ name: "entry", type: "ProgramStruct" }) + ) + ), + + Command( + { + name: "RecordProgram", id: 0x6, access: "O", conformance: "RP & EG", direction: "request", + response: "status", + details: "Record a specific program or series when it goes live. This functionality enables DVR recording " + + "features.", + xref: { document: "cluster", section: "6.6.7.7" } + }, + + Field({ + name: "ProgramIdentifier", id: 0x0, type: "string", conformance: "M", constraint: "max 255", + details: "This field shall indicate the program identifier for the program that should be recorded. This " + + "value is provided by the identifier field in ProgramStruct.", + xref: { document: "cluster", section: "6.6.7.7.1" } + }), + + Field({ + name: "ShouldRecordSeries", id: 0x1, type: "bool", conformance: "M", + details: "This field shall indicate whether the whole series associated to the program should be recorded. " + + "For example, invoking record program on an episode with that flag set to true, the target should " + + "schedule record the whole series.", + xref: { document: "cluster", section: "6.6.7.7.2" } + }), + + Field( + { + name: "ExternalIdList", id: 0x2, type: "list", conformance: "O", constraint: "max 255", default: [], + details: "This field, if present, shall indicate the list of additional external content identifiers.", + xref: { document: "cluster", section: "6.6.7.7.3" } + }, + Field({ name: "entry", type: "ContentLauncher.AdditionalInfoStruct" }) + ), + + Field({ + name: "Data", id: 0x3, type: "octstr", conformance: "O", constraint: "max 8092", + details: "This field, if present, shall indicate app-specific data.", + xref: { document: "cluster", section: "6.6.7.7.4" } + }) + ), + + Command( + { + name: "CancelRecordProgram", id: 0x7, access: "O", conformance: "RP & EG", direction: "request", + response: "status", + details: "Cancel recording for a specific program or series.", + xref: { document: "cluster", section: "6.6.7.8" } + }, + + Field({ + name: "ProgramIdentifier", id: 0x0, type: "string", conformance: "M", constraint: "max 255", + details: "This field shall indicate the program identifier for the program that should be cancelled from " + + "recording. This value is provided by the identifier field in ProgramStruct.", + xref: { document: "cluster", section: "6.6.7.8.1" } + }), + + Field({ + name: "ShouldRecordSeries", id: 0x1, type: "bool", conformance: "M", + details: "This field shall indicate whether the whole series associated to the program should be cancelled " + + "from recording. For example, invoking record program on an episode with that flag set to true, the " + + "target should schedule record the whole series.", + xref: { document: "cluster", section: "6.6.7.8.2" } + }), + + Field( + { + name: "ExternalIdList", id: 0x2, type: "list", conformance: "O", constraint: "max 255", default: [], + details: "This field, if present, shall indicate the list of additional external content identifiers.", + xref: { document: "cluster", section: "6.6.7.8.3" } + }, + Field({ name: "entry", type: "ContentLauncher.AdditionalInfoStruct" }) + ), + + Field({ + name: "Data", id: 0x3, type: "octstr", conformance: "O", constraint: "max 8092", + details: "This field, if present, shall indicate app-specific data.", + xref: { document: "cluster", section: "6.6.7.8.4" } + }) + ), + + Datatype( + { name: "RecordingFlagBitmap", type: "map8", xref: { document: "cluster", section: "6.6.5.1" } }, + Field({ name: "Scheduled", constraint: "0", description: "The program is scheduled for recording." }), + Field({ name: "RecordSeries", constraint: "1", description: "The program series is scheduled for recording." }), + Field({ name: "Recorded", constraint: "2", description: "The program is recorded and available to be played." }) + ), + + Datatype( + { name: "LineupInfoTypeEnum", type: "enum8", xref: { document: "cluster", section: "6.6.5.2" } }, + Field({ name: "Mso", id: 0x0, conformance: "M", description: "Multi System Operator" }) + ), + + Datatype( + { name: "StatusEnum", type: "enum8", xref: { document: "cluster", section: "6.6.5.3" } }, + Field({ name: "Success", id: 0x0, conformance: "M", description: "Command succeeded" }), + Field({ + name: "MultipleMatches", id: 0x1, conformance: "M", + description: "More than one equal match for the ChannelInfoStruct passed in." + }), + Field({ + name: "NoMatches", id: 0x2, conformance: "M", + description: "No matches for the ChannelInfoStruct passed in." + }) + ), + + Datatype( + { name: "ChannelTypeEnum", type: "enum8", xref: { document: "cluster", section: "6.6.5.4" } }, + Field({ + name: "Satellite", id: 0x0, conformance: "M", + description: "The channel is sourced from a satellite provider." + }), + Field({ name: "Cable", id: 0x1, conformance: "M", description: "The channel is sourced from a cable provider." }), + Field({ + name: "Terrestrial", id: 0x2, conformance: "M", + description: "The channel is sourced from a terrestrial provider." + }), + Field({ name: "Ott", id: 0x3, conformance: "M", description: "The channel is sourced from an OTT provider." }) + ), + + Datatype( + { + name: "ChannelInfoStruct", type: "struct", + details: "This indicates a channel in a channel lineup." + + "\n" + + "While the major and minor numbers in the ChannelInfoStruct support use of ATSC channel format, a " + + "lineup may use other formats which can map into these numeric values.", + xref: { document: "cluster", section: "6.6.5.5" } + }, + + Field({ + name: "MajorNumber", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall indicate the channel major number value (for example, using ATSC format). When the " + + "channel number is expressed as a string, such as \"13.1\" or \"256\", the major number would be 13 or " + + "256, respectively. This field is required but shall be set to 0 for channels such as over-the-top " + + "channels that are not represented by a major or minor number.", + xref: { document: "cluster", section: "6.6.5.5.1" } + }), + + Field({ + name: "MinorNumber", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall indicate the channel minor number value (for example, using ATSC format). When the " + + "channel number is expressed as a string, such as \"13.1\" or \"256\", the minor number would be 1 or 0, " + + "respectively. This field is required but shall be set to 0 for channels such as over-the-top " + + "channels that are not represented by a major or minor number.", + xref: { document: "cluster", section: "6.6.5.5.2" } + }), + + Field({ + name: "Name", id: 0x2, type: "string", conformance: "O", + details: "This field shall indicate the marketing name for the channel, such as “The CW\" or \"Comedy Central\". " + + "This field is optional, but SHOULD be provided when known.", + xref: { document: "cluster", section: "6.6.5.5.3" } + }), + + Field({ + name: "CallSign", id: 0x3, type: "string", conformance: "O", + details: "This field shall indicate the call sign of the channel, such as \"PBS\". This field is optional, but " + + "SHOULD be provided when known.", + xref: { document: "cluster", section: "6.6.5.5.4" } + }), + + Field({ + name: "AffiliateCallSign", id: 0x4, type: "string", conformance: "O", + details: "This field shall indicate the local affiliate call sign, such as \"KCTS\". This field is optional, " + + "but SHOULD be provided when known.", + xref: { document: "cluster", section: "6.6.5.5.5" } + }), + + Field({ + name: "Identifier", id: 0x5, type: "string", conformance: "O", + details: "This shall indicate the unique identifier for a specific channel. This field is optional, but " + + "SHOULD be provided when MajorNumber and MinorNumber are not available.", + xref: { document: "cluster", section: "6.6.5.5.6" } + }), + + Field({ + name: "Type", id: 0x6, type: "ChannelTypeEnum", conformance: "O", + details: "This shall indicate the type or grouping of a specific channel. This field is optional, but SHOULD " + + "be provided when known.", + xref: { document: "cluster", section: "6.6.5.5.7" } + }) + ), + + Datatype( + { + name: "LineupInfoStruct", type: "struct", + details: "The Lineup Info allows references to external lineup sources like Gracenote. The combination of " + + "OperatorName, LineupName, and PostalCode MUST uniquely identify a lineup.", + xref: { document: "cluster", section: "6.6.5.6" } + }, + + Field({ + name: "OperatorName", id: 0x0, type: "string", conformance: "M", + details: "This field shall indicate the name of the operator, for example “Comcast”.", + xref: { document: "cluster", section: "6.6.5.6.1" } + }), + + Field({ + name: "LineupName", id: 0x1, type: "string", conformance: "O", + details: "This field shall indicate the name of the provider lineup, for example \"Comcast King County\". This " + + "field is optional, but SHOULD be provided when known.", + xref: { document: "cluster", section: "6.6.5.6.2" } + }), + + Field({ + name: "PostalCode", id: 0x2, type: "string", conformance: "O", + details: "This field shall indicate the postal code (zip code) for the location of the device, such as " + + "\"98052\". This field is optional, but SHOULD be provided when known.", + xref: { document: "cluster", section: "6.6.5.6.3" } + }), + + Field({ + name: "LineupInfoType", id: 0x3, type: "LineupInfoTypeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the type of lineup. This field is optional, but SHOULD be provided when " + + "known.", + xref: { document: "cluster", section: "6.6.5.6.4" } + }) + ), + + Datatype( + { + name: "ProgramStruct", type: "struct", + details: "This indicates a program within an electronic program guide (EPG).", + xref: { document: "cluster", section: "6.6.5.7" } + }, + + Field({ + name: "Identifier", id: 0x0, type: "string", conformance: "M", constraint: "max 255", + details: "This field shall indicate a unique identifier for a program within an electronic program guide " + + "list. The identifier shall be unique across multiple channels.", + xref: { document: "cluster", section: "6.6.5.7.1" } + }), + + Field({ + name: "Channel", id: 0x1, type: "ChannelInfoStruct", conformance: "M", + details: "This field shall indicate the channel associated to the program.", + xref: { document: "cluster", section: "6.6.5.7.2" } + }), + + Field({ + name: "StartTime", id: 0x2, type: "epoch-s", conformance: "M", + details: "This field shall indicate an epoch time in seconds indicating the start time of a program, as a UTC " + + "time. This field can represent a past or future value.", + xref: { document: "cluster", section: "6.6.5.7.3" } + }), + + Field({ + name: "EndTime", id: 0x3, type: "epoch-s", conformance: "M", + details: "This field shall indicate an epoch time in seconds indicating the end time of a program, as a UTC " + + "time. This field can represent a past or future value but shall be greater than the StartTime.", + xref: { document: "cluster", section: "6.6.5.7.4" } + }), + + Field({ + name: "Title", id: 0x4, type: "string", conformance: "M", constraint: "max 255", + details: "This field shall indicate the title or name for the specific program. For example, “MCIS: Los " + + "Angeles”.", + xref: { document: "cluster", section: "6.6.5.7.5" } + }), + + Field({ + name: "Subtitle", id: 0x5, type: "string", conformance: "O", constraint: "max 255", + details: "This field shall indicate the subtitle for the specific program. For example, “Maybe Today\" which " + + "is an episode name for “MCIS: Los Angeles”. This field is optional but shall be provided if " + + "applicable and known.", + xref: { document: "cluster", section: "6.6.5.7.6" } + }), + + Field({ + name: "Description", id: 0x6, type: "string", conformance: "O", constraint: "max 8192", + details: "This field shall indicate the brief description for the specific program. For example, a " + + "description of an episode. This field is optional but shall be provided if known.", + xref: { document: "cluster", section: "6.6.5.7.7" } + }), + + Field( + { + name: "AudioLanguages", id: 0x7, type: "list", conformance: "O", constraint: "max 10[max 50]", + default: [], + details: "This field shall indicate the audio language for the specific program. The value is a string " + + "containing one of the standard Tags for Identifying Languages RFC 5646. This field is optional but " + + "shall be provided if known.", + xref: { document: "cluster", section: "6.6.5.7.8" } + }, + + Field({ name: "entry", type: "string" }) + ), + + Field( + { + name: "Ratings", id: 0x8, type: "list", conformance: "O", constraint: "max 255", default: [], + details: "This field shall be used for indicating the level of parental guidance recommended for of a " + + "particular program. This can be any rating system used in the country or region where the program " + + "is broadcast. For example, in the United States “TV-PG” may contain material that parents can find " + + "not suitable for younger children but can be accepted in general for older children. This field is " + + "optional but shall be provided if known.", + xref: { document: "cluster", section: "6.6.5.7.9" } + }, + + Field({ name: "entry", type: "string" }) + ), + + Field({ + name: "ThumbnailUrl", id: 0x9, type: "string", conformance: "O", constraint: "max 8192", + details: "This field shall represent a URL of a thumbnail that clients can use to render an image for the " + + "program. The syntax of this field shall follow the syntax as specified in RFC 1738 and shall use " + + "the https scheme.", + xref: { document: "cluster", section: "6.6.5.7.10" } + }), + + Field({ + name: "PosterArtUrl", id: 0xa, type: "string", conformance: "O", constraint: "max 8192", + details: "This field shall represent a URL of a poster that clients can use to render an image for the " + + "program on the detail view. The syntax of this field shall follow the syntax as specified in RFC " + + "1738 and shall use the https scheme.", + xref: { document: "cluster", section: "6.6.5.7.11" } + }), + + Field({ + name: "DvbiUrl", id: 0xb, type: "string", conformance: "O", constraint: "max 8192", + details: "This field shall represent the DVB-I URL associated to the program. The syntax of this field shall " + + "follow the syntax as specified in RFC 1738 and shall use the https scheme.", + xref: { document: "cluster", section: "6.6.5.7.12" } + }), + + Field({ + name: "ReleaseDate", id: 0xc, type: "string", conformance: "O", constraint: "max 30", + details: "This field shall be a string, in ISO 8601 format, representing the date on which the program was " + + "released. This field is optional but when provided, the year shall be provided as part of the " + + "string.", + xref: { document: "cluster", section: "6.6.5.7.13" } + }), + + Field({ + name: "ParentalGuidanceText", id: 0xd, type: "string", conformance: "O", constraint: "max 255", + details: "This field shall represent a string providing additional information on the parental guidance. This " + + "field is optional.", + xref: { document: "cluster", section: "6.6.5.7.14" } + }), + + Field({ + name: "RecordingFlag", id: 0xe, type: "RecordingFlagBitmap", conformance: "RP", + details: "This field shall represent the recording status of the program. This field is required if the " + + "RecordProgram feature is set.", + xref: { document: "cluster", section: "6.6.5.7.15" } + }), + + Field({ + name: "SeriesInfo", id: 0xf, type: "SeriesInfoStruct", conformance: "O", default: null, + quality: "X", + details: "This field shall represent the information of a series such as season and episode number. This " + + "field is optional but SHOULD be provided if the program represents a series and this information is " + + "available.", + xref: { document: "cluster", section: "6.6.5.7.16" } + }), + + Field( + { + name: "CategoryList", id: 0x10, type: "list", conformance: "O", constraint: "max 255", default: [], + details: "This field shall represent the category of a particular program. This field is optional but shall " + + "be provided if known.", + xref: { document: "cluster", section: "6.6.5.7.17" } + }, + + Field({ name: "entry", type: "ProgramCategoryStruct" }) + ), + + Field( + { + name: "CastList", id: 0x11, type: "list", conformance: "O", constraint: "max 255", default: [], + details: "This field shall represent a list of the cast or the crew on the program. A single cast member may " + + "have more than one role. This field is optional but shall be provided if known.", + xref: { document: "cluster", section: "6.6.5.7.18" } + }, + + Field({ name: "entry", type: "ProgramCastStruct" }) + ), + + Field( + { + name: "ExternalIdList", id: 0x12, type: "list", conformance: "O", constraint: "max 255", + default: [], + details: "This field shall indicate the list of additional external content identifiers.", + xref: { document: "cluster", section: "6.6.5.7.19" } + }, + + Field({ name: "entry", type: "ContentLauncher.AdditionalInfoStruct" }) + ) + ), + + Datatype( + { + name: "ProgramCategoryStruct", type: "struct", + details: "This object defines the category associated to a program.", + xref: { document: "cluster", section: "6.6.5.8" } + }, + Field({ + name: "Category", id: 0x0, type: "string", conformance: "M", constraint: "max 256", + details: "This field shall represent the category or genre of the program. Ex. News.", + xref: { document: "cluster", section: "6.6.5.8.1" } + }), + Field({ + name: "SubCategory", id: 0x1, type: "string", conformance: "O", constraint: "max 256", + details: "This field shall represent the sub-category or sub-genre of the program. Ex. Local.", + xref: { document: "cluster", section: "6.6.5.8.2" } + }) + ), + + Datatype( + { + name: "SeriesInfoStruct", type: "struct", + details: "This object provides the episode information related to a program.", + xref: { document: "cluster", section: "6.6.5.9" } + }, + Field({ + name: "Season", id: 0x0, type: "string", conformance: "M", constraint: "max 256", + details: "This field shall represent the season of the series associated to the program.", + xref: { document: "cluster", section: "6.6.5.9.1" } + }), + Field({ + name: "Episode", id: 0x1, type: "string", conformance: "M", constraint: "max 256", + details: "This field shall represent the episode of the program.", + xref: { document: "cluster", section: "6.6.5.9.2" } + }) + ), + + Datatype( + { + name: "ProgramCastStruct", type: "struct", + details: "This object provides the cast information related to a program.", + xref: { document: "cluster", section: "6.6.5.10" } + }, + Field({ + name: "Name", id: 0x0, type: "string", conformance: "M", constraint: "max 256", + details: "This field shall represent the name of the cast member.", + xref: { document: "cluster", section: "6.6.5.10.1" } + }), + Field({ + name: "Role", id: 0x1, type: "string", conformance: "M", constraint: "max 256", + details: "This field shall represent the role of the cast member. Ex. Actor, Director.", + xref: { document: "cluster", section: "6.6.5.10.2" } + }) + ), + + Datatype( + { + name: "PageTokenStruct", type: "struct", + details: "This object defines the pagination structure.", + xref: { document: "cluster", section: "6.6.5.11" } + }, + + Field({ + name: "Limit", id: 0x0, type: "uint16", conformance: "O", default: 0, + details: "This field shall indicate the maximum number of entries that should be retrieved from the program " + + "guide in a single response. It allows clients to specify the size of the paginated result set based " + + "on their needs.", + xref: { document: "cluster", section: "6.6.5.11.1" } + }), + + Field({ + name: "After", id: 0x1, type: "string", conformance: "O", constraint: "max 8192", + details: "This field shall indicate the cursor that pinpoints the start of the upcoming data page. In a " + + "Cursor- based pagination system, the field acts as a reference point, ensuring the set of results " + + "corresponds directly to the data following the specified cursor. In a Offset-based pagination " + + "system, the field, along with limit, indicate the offset from which entries in the program guide " + + "will be retrieved.", + xref: { document: "cluster", section: "6.6.5.11.2" } + }), + + Field({ + name: "Before", id: 0x2, type: "string", conformance: "O", constraint: "max 8192", + details: "This field shall indicate the cursor that pinpoints the end of the upcoming data page. In a Cursor- " + + "based pagination system, the field acts as a reference point, ensuring the set of results " + + "corresponds directly to the data preceding the specified cursor. In a Offset-based pagination " + + "system, the field, along with limit, indicate the offset from which entries in the program guide " + + "will be retrieved.", + xref: { document: "cluster", section: "6.6.5.11.3" } + }) + ), + + Datatype( + { + name: "ChannelPagingStruct", type: "struct", + details: "This object defines the paging structure that includes the previous and next pagination tokens.", + xref: { document: "cluster", section: "6.6.5.12" } + }, + + Field({ + name: "PreviousToken", id: 0x0, type: "PageTokenStruct", conformance: "O", default: null, + quality: "X", + details: "This field shall indicate the token to retrieve the preceding page. Absence of this field denotes " + + "the response as the initial page.", + xref: { document: "cluster", section: "6.6.5.12.1" } + }), + + Field({ + name: "NextToken", id: 0x1, type: "PageTokenStruct", conformance: "O", default: null, quality: "X", + details: "This field shall indicate the token to retrieve the next page. Absence of this field denotes the " + + "response as the last page.", + xref: { document: "cluster", section: "6.6.5.12.2" } + }) + ) + ), + + Cluster( + { + name: "ContentLauncher", id: 0x50a, classification: "application", pics: "CONTENTLAUNCHER", + + details: "This cluster provides an interface for launching content on a Video Player device such as a " + + "Streaming Media Player, Smart TV or Smart Screen." + + "\n" + + "This cluster would be supported on a Video Player device or devices that can playback content, such " + + "as a Streaming Media Player, Smart TV or Smart Screen. This cluster supports playing back content " + + "referenced by URL. It supports finding content by type and global identifier, and either playing " + + "the content or displaying the search results." + + "\n" + + "The cluster server for Content Launcher is implemented by an endpoint that can launch content, such " + + "as a Video Player, or an endpoint representing a Content App on such a device." + + "\n" + + "When this cluster is implemented for an Content App Endpoint (Endpoint with type “Content App” and " + + "having an Application Basic cluster), the Video Player device shall launch the application when a " + + "client invokes the LaunchContent or LaunchURL commands.", + + xref: { document: "cluster", section: "6.7" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.7.4" } }, + Field({ + name: "CS", constraint: "0", description: "ContentSearch", + details: "Device supports content search (non-app specific)" + }), + Field({ + name: "UP", constraint: "1", description: "UrlPlayback", + details: "Device supports basic URL-based file playback" + }), + Field({ + name: "AS", constraint: "2", description: "AdvancedSeek", + details: "Enables clients to implement more advanced media seeking behavior in their user interface, such as " + + "for example a \"seek bar\"." + }), + Field({ name: "TT", constraint: "3", description: "TextTracks", details: "Device or app supports Text Tracks." }), + Field({ + name: "AT", constraint: "4", description: "AudioTracks", + details: "Device or app supports Audio Tracks." + }) + ), + + Attribute( + { + name: "AcceptHeader", id: 0x0, type: "list", access: "R V", conformance: "UP", + constraint: "max 100[max 1024]", default: [], quality: "N", + details: "This attribute shall provide a list of content types supported by the Video Player or Content App" + + "\n" + + "in the form of entries in the HTTP \"Accept\" request header.", + xref: { document: "cluster", section: "6.7.6.1" } + }, + + Field({ name: "entry", type: "string" }) + ), + + Attribute({ + name: "SupportedStreamingProtocols", id: 0x1, type: "SupportedProtocolsBitmap", access: "R V", + conformance: "UP", default: 0, quality: "N", + details: "This attribute shall provide information about supported streaming protocols.", + xref: { document: "cluster", section: "6.7.6.2" } + }), + + Command( + { + name: "LaunchContent", id: 0x0, access: "O", conformance: "CS", direction: "request", + response: "LauncherResponse", + details: "Upon receipt, this shall launch the specified content with optional search criteria. This command " + + "returns a Launch Response.", + xref: { document: "cluster", section: "6.7.7.1" } + }, + + Field({ + name: "Search", id: 0x0, type: "ContentSearchStruct", conformance: "M", constraint: "desc", + details: "This field shall indicate the content to launch.", + xref: { document: "cluster", section: "6.7.7.1.1" } + }), + + Field({ + name: "AutoPlay", id: 0x1, type: "bool", conformance: "M", constraint: "desc", + details: "This field shall indicate whether to automatically start playing content, where:" + + "\n" + + " • TRUE means best match should start playing automatically." + + "\n" + + " • FALSE means matches should be displayed on screen for user selection.", + xref: { document: "cluster", section: "6.7.7.1.2" } + }), + + Field({ + name: "Data", id: 0x2, type: "string", conformance: "O", + details: "This field, if present, shall indicate app-specific data.", + xref: { document: "cluster", section: "6.7.7.1.3" } + }), + + Field({ + name: "PlaybackPreferences", id: 0x3, type: "PlaybackPreferencesStruct", conformance: "O", + + details: "This field, if present, shall indicate the user’s preferred Text/AudioTracks and playbackPosition " + + "for the media, sent from the client to the server. If the server does not find an available track " + + "for the title being played exactly matching a Track requested here, in the list of available " + + "tracks, it may default to picking another track that closely matches the requested track. " + + "Alternately, it may go with user preferences set on the server side (it will use this option if " + + "these PlaybackPreferences are not specified). In the case of text tracks, that may mean that the " + + "subtitle text is not displayed at all. In the cases where the preferred Text/AudioTracks are not " + + "available, the server shall return the TextTrackNotAvailable and/or AudioTrackNotAvailable " + + "Status(es) in the LauncherResponse.", + + xref: { document: "cluster", section: "6.7.7.1.4" } + }), + + Field({ + name: "UseCurrentContext", id: 0x4, type: "bool", conformance: "O", constraint: "desc", + default: true, + + details: "This field, if present, shall indicate whether to consider the context of current ongoing activity " + + "on the receiver to fulfill the request. For example if the request only includes data in " + + "ContentSearch that specifies an Episode number, and UseCurrentContent is set to TRUE, if there is a " + + "TV series on going, the request refers to the specific episode of the ongoing season of the TV " + + "series. TRUE means current activity context may be considered FALSE means current activity context " + + "shall NOT be considered", + + xref: { document: "cluster", section: "6.7.7.1.5" } + }) + ), + + Command( + { + name: "LaunchUrl", id: 0x1, access: "O", conformance: "UP", direction: "request", + response: "LauncherResponse", + + details: "Upon receipt, this shall launch content from the specified URL." + + "\n" + + "The content types supported include those identified in the AcceptHeader and " + + "SupportedStreamingProtocols attributes." + + "\n" + + "A check shall be made to ensure the URL is secure (uses HTTPS)." + + "\n" + + "When playing a video stream in response to this command, an indication (ex. visual) of the identity " + + "of the origin node of the video stream shall be provided. This could be in the form of a friendly " + + "name label which uniquely identifies the node to the user. This friendly name label is typically " + + "assigned by the Matter Admin (ex. TV) at the time of commissioning and, when it’s a device, is " + + "often editable by the user. It might be a combination of a company name and friendly name, for " + + "example, ”Acme” or “Acme Streaming Service on Alice’s Phone”." + + "\n" + + "This command returns a Launch Response.", + + xref: { document: "cluster", section: "6.7.7.2" } + }, + + Field({ + name: "ContentUrl", id: 0x0, type: "string", conformance: "M", constraint: "any", + details: "This field shall indicate the URL of content to launch. The syntax of this field shall follow the " + + "syntax as specified in RFC 1738 and shall use the https scheme.", + xref: { document: "cluster", section: "6.7.7.2.1" } + }), + + Field({ + name: "DisplayString", id: 0x1, type: "string", conformance: "O", constraint: "any", + details: "This field, if present, shall provide a string that may be used to describe the content being " + + "accessed at the given URL.", + xref: { document: "cluster", section: "6.7.7.2.2" } + }), + + Field({ + name: "BrandingInformation", id: 0x2, type: "BrandingInformationStruct", conformance: "O", + constraint: "any", + details: "This field, if present, shall indicate the branding information that may be displayed when playing " + + "back the given content.", + xref: { document: "cluster", section: "6.7.7.2.3" } + }), + + Field({ + name: "PlaybackPreferences", id: 0x3, type: "PlaybackPreferencesStruct", conformance: "O", + constraint: "any", + + details: "This field, if present, shall indicate the user’s preferred Text/AudioTracks and playbackPosition " + + "for the media, sent from the client to the server. If the server does not find an available track " + + "for the title being played exactly matching a Track requested here, in the list of available " + + "tracks, it may default to picking another track that closely matches the requested track. " + + "Alternately, it may go with user preferences set on the server side (it will use this option if " + + "these PlaybackPreferences are not specified). In the case of text tracks, that may mean that the " + + "subtitle text is not displayed at all. In the cases where the preferred Text/AudioTracks are not " + + "available, the server shall return the TextTrackNotAvailable and/or AudioTrackNotAvailable " + + "Status(es) in the LauncherResponse.", + + xref: { document: "cluster", section: "6.7.7.2.4" } + }) + ), + + Command( + { + name: "LauncherResponse", id: 0x2, conformance: "CS | UP", direction: "response", + details: "This command shall be generated in response to LaunchContent and LaunchURL commands.", + xref: { document: "cluster", section: "6.7.7.3" } + }, + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", + details: "This field shall indicate the status of the command which resulted in this response.", + xref: { document: "cluster", section: "6.7.7.3.1" } + }), + Field({ + name: "Data", id: 0x1, type: "string", conformance: "O", + details: "This field shall indicate Optional app-specific data.", + xref: { document: "cluster", section: "6.7.7.3.2" } + }) + ), + + Datatype( + { name: "SupportedProtocolsBitmap", type: "map32", xref: { document: "cluster", section: "6.7.5.1" } }, + Field({ + name: "Dash", constraint: "0", + description: "Device supports Dynamic Adaptive Streaming over HTTP (DASH)" + }), + Field({ name: "Hls", constraint: "1", description: "Device supports HTTP Live Streaming (HLS)" }) + ), + + Datatype( + { name: "StatusEnum", type: "enum8", xref: { document: "cluster", section: "6.7.5.2" } }, + Field({ name: "Success", id: 0x0, conformance: "M", description: "Command succeeded" }), + Field({ + name: "UrlNotAvailable", id: 0x1, conformance: "M", + description: "Requested URL could not be reached by device." + }), + Field({ name: "AuthFailed", id: 0x2, conformance: "M", description: "Requested URL returned 401 error code." }), + Field({ + name: "TextTrackNotAvailable", id: 0x3, conformance: "TT", + description: "Requested Text Track (in PlaybackPreferences) not available" + }), + Field({ + name: "AudioTrackNotAvailable", id: 0x4, conformance: "AT", + description: "Requested Audio Track (in PlaybackPreferences) not available" + }) + ), + + Datatype( + { name: "ParameterEnum", type: "enum8", xref: { document: "cluster", section: "6.7.5.3" } }, + Field({ + name: "Actor", id: 0x0, conformance: "M", + description: "Actor represents an actor credited in video media content; for example, “Gaby Hoffman”" + }), + Field({ + name: "Channel", id: 0x1, conformance: "M", + description: "Channel represents the identifying data for a television channel; for example, \"PBS\"" + }), + Field({ + name: "Character", id: 0x2, conformance: "M", + description: "A character represented in video media content; for example, “Snow White”" + }), + Field({ + name: "Director", id: 0x3, conformance: "M", + description: "A director of the video media content; for example, “Spike Lee”" + }), + Field({ + name: "Event", id: 0x4, conformance: "M", + description: "An event is a reference to a type of event; examples would include sports, music, or other types of events. For example, searching for \"Football games\" would search for a 'game' event entity and a 'football' sport entity." + }), + Field({ + name: "Franchise", id: 0x5, conformance: "M", + description: "A franchise is a video entity which can represent a number of video entities, like movies or TV shows. For example, take the fictional franchise \"Intergalactic Wars\" which represents a collection of movie trilogies, as well as animated and live action TV shows. This entity type was introduced to account for requests by customers such as \"Find Intergalactic Wars movies\", which would search for all 'Intergalactic Wars' programs of the MOVIE MediaType, rather than attempting to match to a single title." + }), + Field({ + name: "Genre", id: 0x6, conformance: "M", + description: "Genre represents the genre of video media content such as action, drama or comedy." + }), + Field({ + name: "League", id: 0x7, conformance: "M", + description: "League represents the categorical information for a sporting league; for example, \"NCAA\"" + }), + Field({ + name: "Popularity", id: 0x8, conformance: "M", + description: "Popularity indicates whether the user asks for popular content." + }), + Field({ + name: "Provider", id: 0x9, conformance: "M", + description: "The provider (MSP) the user wants this media to be played on; for example, \"Netflix\"." + }), + Field({ + name: "Sport", id: 0xa, conformance: "M", + description: "Sport represents the categorical information of a sport; for example, football" + }), + Field({ + name: "SportsTeam", id: 0xb, conformance: "M", + description: "SportsTeam represents the categorical information of a professional sports team; for example, \"University of Washington Huskies\"" + }), + Field({ + name: "Type", id: 0xc, conformance: "M", + description: "The type of content requested. Supported types are \"Movie\", \"MovieSeries\", \"TVSeries\", \"TVSeason\", \"TVEpisode\", \"Trailer\", \"SportsEvent\", \"LiveEvent\", and \"Video\"" + }), + Field({ + name: "Video", id: 0xd, conformance: "M", + description: "Video represents the identifying data for a specific piece of video content; for example, \"Manchester by the Sea\"." + }), + Field({ + name: "Season", id: 0xe, conformance: "O", + description: "Season represents the specific season number within a TV series." + }), + Field({ + name: "Episode", id: 0xf, conformance: "O", + description: "Episode represents a specific episode number within a Season in a TV series." + }), + Field({ + name: "Any", id: 0x10, conformance: "O", + description: "Represents a search text input across many parameter types or even outside of the defined param types." + }) + ), + + Datatype( + { name: "MetricTypeEnum", type: "enum8", xref: { document: "cluster", section: "6.7.5.4" } }, + Field({ + name: "Pixels", id: 0x0, conformance: "M", description: "Dimensions defined in a number of Pixels", + details: "This value is used for dimensions defined in a number of Pixels.", + xref: { document: "cluster", section: "6.7.5.4.1" } + }), + + Field({ + name: "Percentage", id: 0x1, conformance: "M", description: "Dimensions defined as a percentage", + details: "This value is for dimensions defined as a percentage of the overall display dimensions. For " + + "example, if using a Percentage Metric type for a Width measurement of 50.0, against a display width " + + "of 1920 pixels, then the resulting value used would be 960 pixels (50.0% of 1920) for that " + + "dimension. Whenever a measurement uses this Metric type, the resulting values shall be rounded " + + "(\"floored\") towards 0 if the measurement requires an integer final value.", + xref: { document: "cluster", section: "6.7.5.4.2" } + }) + ), + + Datatype( + { + name: "AdditionalInfoStruct", type: "struct", + details: "This object defines additional name=value pairs that can be used for identifying content.", + xref: { document: "cluster", section: "6.7.5.5" } + }, + Field({ + name: "Name", id: 0x0, type: "string", conformance: "M", constraint: "max 256", + details: "This field shall indicate the name of external id, ex. \"musicbrainz\".", + xref: { document: "cluster", section: "6.7.5.5.1" } + }), + Field({ + name: "Value", id: 0x1, type: "string", conformance: "M", constraint: "max 8192", + details: "This field shall indicate the value for external id, ex. \"ST0000000666661\".", + xref: { document: "cluster", section: "6.7.5.5.2" } + }) + ), + + Datatype( + { + name: "ParameterStruct", type: "struct", + details: "This object defines inputs to a search for content for display or playback.", + xref: { document: "cluster", section: "6.7.5.6" } + }, + Field({ + name: "Type", id: 0x0, type: "ParameterEnum", conformance: "M", + details: "This field shall indicate the entity type.", + xref: { document: "cluster", section: "6.7.5.6.1" } + }), + Field({ + name: "Value", id: 0x1, type: "string", conformance: "M", constraint: "max 1024", + details: "This field shall indicate the entity value, which is a search string, ex. “Manchester by the Sea”.", + xref: { document: "cluster", section: "6.7.5.6.2" } + }), + + Field( + { + name: "ExternalIdList", id: 0x2, type: "list", conformance: "O", default: [], + details: "This field shall indicate the list of additional external content identifiers.", + xref: { document: "cluster", section: "6.7.5.6.3" } + }, + Field({ name: "entry", type: "AdditionalInfoStruct" }) + ) + ), + + Datatype( + { + name: "ContentSearchStruct", type: "struct", + details: "This object defines inputs to a search for content for display or playback.", + xref: { document: "cluster", section: "6.7.5.7" } + }, + + Field( + { + name: "ParameterList", id: 0x0, type: "list", conformance: "M", + details: "This field shall indicate the list of parameters comprising the search. If multiple parameters are " + + "provided, the search parameters shall be joined with 'AND' logic. e.g. action movies with Tom " + + "Cruise will be represented as [{Actor: 'Tom Cruise'}, {Type: 'Movie'}, {Genre: 'Action'}]", + xref: { document: "cluster", section: "6.7.5.7.1" } + }, + + Field({ name: "entry", type: "ParameterStruct" }) + ) + ), + + Datatype( + { + name: "DimensionStruct", type: "struct", + details: "This object defines dimension which can be used for defining Size of background images.", + xref: { document: "cluster", section: "6.7.5.8" } + }, + Field({ + name: "Width", id: 0x0, type: "double", conformance: "M", + details: "This field shall indicate the width using the metric defined in Metric", + xref: { document: "cluster", section: "6.7.5.8.1" } + }), + Field({ + name: "Height", id: 0x1, type: "double", conformance: "M", + details: "This field shall indicate the height using the metric defined in Metric", + xref: { document: "cluster", section: "6.7.5.8.2" } + }), + Field({ + name: "Metric", id: 0x2, type: "MetricTypeEnum", conformance: "M", + details: "This field shall indicate metric used for defining Height/Width.", + xref: { document: "cluster", section: "6.7.5.8.3" } + }) + ), + + Datatype( + { + name: "StyleInformationStruct", type: "struct", + details: "This object defines style information which can be used by content providers to change the Media " + + "Player’s style related properties.", + xref: { document: "cluster", section: "6.7.5.9" } + }, + + Field({ + name: "ImageUrl", id: 0x0, type: "string", conformance: "O", constraint: "max 8192", + details: "This field shall indicate the URL of image used for Styling different Video Player sections like " + + "Logo, Watermark etc. The syntax of this field shall follow the syntax as specified in RFC 1738 and " + + "shall use the https scheme.", + xref: { document: "cluster", section: "6.7.5.9.1" } + }), + + Field( + { + name: "Color", id: 0x1, type: "string", conformance: "O", constraint: "7, 9", + + details: "This field shall indicate the color, in RGB or RGBA, used for styling different Video Player " + + "sections like Logo, Watermark, etc. The value shall conform to the 6-digit or 8-digit format " + + "defined for CSS sRGB hexadecimal color notation [https://www.w3.org/TR/css-color-4/#hex-notation]. " + + "Examples:" + + "\n" + + " • #76DE19 for R=0x76, G=0xDE, B=0x19, A absent" + + "\n" + + " • #76DE1980 for R=0x76, G=0xDE, B=0x19, A=0x80", + + xref: { document: "cluster", section: "6.7.5.9.2" } + } + ), + + Field({ + name: "Size", id: 0x2, type: "DimensionStruct", conformance: "O", + details: "This field shall indicate the size of the image used for Styling different Video Player sections " + + "like" + + "\n" + + "Logo, Watermark etc.", + xref: { document: "cluster", section: "6.7.5.9.3" } + }) + ), + + Datatype( + { + name: "BrandingInformationStruct", type: "struct", + details: "This object defines Branding Information which can be provided by the client in order to customize " + + "the skin of the Video Player during playback.", + xref: { document: "cluster", section: "6.7.5.10" } + }, + + Field({ + name: "ProviderName", id: 0x0, type: "string", conformance: "M", constraint: "max 256", + details: "This field shall indicate name of the provider for the given content.", + xref: { document: "cluster", section: "6.7.5.10.1" } + }), + + Field({ + name: "Background", id: 0x1, type: "StyleInformationStruct", conformance: "O", + details: "This field shall indicate background of the Video Player while content launch request is being " + + "processed by it. This background information may also be used by the Video Player when it is in " + + "idle state.", + xref: { document: "cluster", section: "6.7.5.10.2" } + }), + + Field({ + name: "Logo", id: 0x2, type: "StyleInformationStruct", conformance: "O", + details: "This field shall indicate the logo shown when the Video Player is launching. This is also used when " + + "the Video Player is in the idle state and Splash field is not available.", + xref: { document: "cluster", section: "6.7.5.10.3" } + }), + + Field({ + name: "ProgressBar", id: 0x3, type: "StyleInformationStruct", conformance: "O", + details: "This field shall indicate the style of progress bar for media playback.", + xref: { document: "cluster", section: "6.7.5.10.4" } + }), + + Field({ + name: "Splash", id: 0x4, type: "StyleInformationStruct", conformance: "O", + details: "This field shall indicate the screen shown when the Video Player is in an idle state. If this " + + "property is not populated, the Video Player shall default to logo or the provider name.", + xref: { document: "cluster", section: "6.7.5.10.5" } + }), + + Field({ + name: "WaterMark", id: 0x5, type: "StyleInformationStruct", conformance: "O", + details: "This field shall indicate watermark shown when the media is playing.", + xref: { document: "cluster", section: "6.7.5.10.6" } + }) + ), + + Datatype( + { + name: "PlaybackPreferencesStruct", type: "struct", + details: "PlaybackPreferencesStruct defines the preferences sent by the client to the receiver in the " + + "ContentLauncher LaunchURL or LaunchContent commands.", + xref: { document: "cluster", section: "6.7.5.11" } + }, + + Field({ + name: "PlaybackPosition", id: 0x0, type: "uint64", conformance: "AS", quality: "X", + + details: "This field shall indicate the preferred position (in milliseconds) in the media to launch playback " + + "from. In case the position falls in the middle of a frame, the server shall set the position to the " + + "beginning of that frame and set the SampledPosition attribute on the MediaPlayback cluster " + + "accordingly. A value of null shall indicate that playback position is not applicable for the " + + "current state of the media playback. (For example : Live media with no known duration and where " + + "seek is not supported).", + + xref: { document: "cluster", section: "6.7.5.11.1" } + }), + + Field({ + name: "TextTrack", id: 0x1, type: "TrackPreferenceStruct", conformance: "TT", quality: "X", + details: "This field shall indicate the user’s preferred Text Track. A value of null shall indicate that the " + + "user did not specify a preferred Text Track on the client. In such a case, the decision to display " + + "and select a Text Track is up to the server.", + xref: { document: "cluster", section: "6.7.5.11.2" } + }), + + Field( + { + name: "AudioTracks", id: 0x2, type: "list", conformance: "AT", quality: "X", + details: "This field shall indicate the list of the user’s preferred Audio Tracks. If the list contains " + + "multiple values, each AudioTrack must also specify a unique audioOutputIndex to play the track on. " + + "A value of null shall indicate that the user did not specify a preferred Audio Track on the client. " + + "In such a case, the decision to play and select an Audio Track is up to the server.", + xref: { document: "cluster", section: "6.7.5.11.3" } + }, + + Field({ name: "entry", type: "TrackPreferenceStruct" }) + ) + ), + + Datatype( + { + name: "TrackPreferenceStruct", type: "struct", + details: "This structure defines Text/Audio Track preferences.", + xref: { document: "cluster", section: "6.7.5.12" } + }, + + Field({ + name: "LanguageCode", id: 0x0, type: "string", conformance: "M", constraint: "max 32", + details: "This field shall contain one of the standard Tags for Identifying Languages RFC 5646, which " + + "identifies the primary language used in the Track.", + xref: { document: "cluster", section: "6.7.5.12.1" } + }), + + Field( + { + name: "Characteristics", id: 0x1, type: "list", conformance: "O", default: null, quality: "X", + details: "This field shall contain a list of enumerated CharacteristicEnum values that indicate a purpose, " + + "trait or feature associated with the Track. A value of null shall indicate that there are no " + + "Characteristics corresponding to the Track.", + xref: { document: "cluster", section: "6.7.5.12.2" } + }, + + Field({ name: "entry", type: "MediaPlayback.CharacteristicEnum" }) + ), + + Field({ + name: "AudioOutputIndex", id: 0x2, type: "uint8", conformance: "AT", quality: "X", + + details: "This field if present shall indicate the index of the OutputInfoStruct from the OutputList " + + "attribute (from the AudioOutput cluster) and indicates which audio output the Audio Track should be " + + "played on." + + "\n" + + "This field shall NOT be present if the track is not an audio track." + + "\n" + + "If the track is an audio track, this field MUST be present. A value of null shall indicate that the " + + "server can choose the audio output(s) to play the Audio Track on.", + + xref: { document: "cluster", section: "6.7.5.12.3" } + }) + ) + ), + + Cluster( + { + name: "KeypadInput", id: 0x509, classification: "application", pics: "KEYPADINPUT", + + details: "This cluster provides an interface for key code based input and control on a device like a Video " + + "Player or an endpoint like a Content App. This may include text or action commands such as UP, " + + "DOWN, and SELECT." + + "\n" + + "This cluster would be supported on Video Player devices as well as devices that support remote " + + "control input from a keypad or remote. This cluster provides the list of supported keypad inputs " + + "and provides a command for sending them." + + "\n" + + "The cluster server for Keypad Input is implemented by a device that can receive keypad input, such " + + "as a Video Player, or an endpoint that can receive keypad input, such as a Content App." + + "\n" + + "The key codes used are those defined in the HDMI CEC specification (see HDMI)." + + "\n" + + "Devices may understand a subset of these key codes. Feature flags are used to indicate a specific " + + "subset that is supported. Device may support additional codes beyond what is indicated in feature " + + "flags.", + + xref: { document: "cluster", section: "6.8" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.8.4" } }, + Field({ + name: "NV", constraint: "0", description: "NavigationKeyCodes", + details: "Supports UP, DOWN, LEFT, RIGHT, SELECT, BACK, EXIT, MENU" + }), + Field({ + name: "LK", constraint: "1", description: "LocationKeys", + details: "Supports CEC keys 0x0A (Settings) and 0x09 (Home)" + }), + Field({ name: "NK", constraint: "2", description: "NumberKeys", details: "Supports numeric input 0..9" }) + ), + + Command( + { + name: "SendKey", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "SendKeyResponse", + + details: "Upon receipt, this shall process a keycode as input to the media endpoint." + + "\n" + + "If a device has multiple media endpoints implementing this cluster, such as a casting video player " + + "endpoint with one or more content app endpoints, then only the endpoint receiving the command shall " + + "process the keycode as input. In other words, a specific content app endpoint shall NOT process a " + + "keycode received by a different content app endpoint." + + "\n" + + "If a second SendKey request with the same KeyCode value is received within 200 ms, then the " + + "endpoint will consider the first key press to be a press and hold. When such a repeat KeyCode value " + + "is not received within 200 ms, then the endpoint will consider the last key press to be a release.", + + xref: { document: "cluster", section: "6.8.6.1" } + }, + + Field({ + name: "KeyCode", id: 0x0, type: "CecKeyCodeEnum", conformance: "M", + details: "This field shall indicate the key code to process.", + xref: { document: "cluster", section: "6.8.6.1.1" } + }) + ), + + Command( + { + name: "SendKeyResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command shall be generated in response to a SendKey command. The data for this command shall " + + "be as follows:", + xref: { document: "cluster", section: "6.8.6.2" } + }, + + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", + details: "This field shall indicate the status of the request.", + xref: { document: "cluster", section: "6.8.6.2.1" } + }) + ), + + Datatype( + { name: "StatusEnum", type: "enum8", xref: { document: "cluster", section: "6.8.5.1" } }, + Field({ name: "Success", id: 0x0, conformance: "M", description: "Succeeded" }), + Field({ name: "UnsupportedKey", id: 0x1, conformance: "M", description: "Key code is not supported." }), + Field({ + name: "InvalidKeyInCurrentState", id: 0x2, conformance: "M", + description: "Requested key code is invalid in the context of the responder’s current state." + }) + ), + + Datatype( + { name: "CecKeyCodeEnum", type: "enum8", xref: { document: "cluster", section: "6.8.5.2" } }, + Field({ name: "Select", id: 0x0, conformance: "M" }), + Field({ name: "Up", id: 0x1, conformance: "M" }), + Field({ name: "Down", id: 0x2, conformance: "M" }), + Field({ name: "Left", id: 0x3, conformance: "M" }), + Field({ name: "Right", id: 0x4, conformance: "M" }), + Field({ name: "RightUp", id: 0x5, conformance: "M" }), + Field({ name: "RightDown", id: 0x6, conformance: "M" }), + Field({ name: "LeftUp", id: 0x7, conformance: "M" }), + Field({ name: "LeftDown", id: 0x8, conformance: "M" }), + Field({ name: "RootMenu", id: 0x9, conformance: "M" }), + Field({ name: "SetupMenu", id: 0xa, conformance: "M" }), + Field({ name: "ContentsMenu", id: 0xb, conformance: "M" }), + Field({ name: "FavoriteMenu", id: 0xc, conformance: "M" }), + Field({ name: "Exit", id: 0xd, conformance: "M" }), + Field({ name: "MediaTopMenu", id: 0x10, conformance: "M" }), + Field({ name: "MediaContextSensitiveMenu", id: 0x11, conformance: "M" }), + Field({ name: "NumberEntryMode", id: 0x1d, conformance: "M" }), + Field({ name: "Number11", id: 0x1e, conformance: "M" }), + Field({ name: "Number12", id: 0x1f, conformance: "M" }), + Field({ name: "Number0OrNumber10", id: 0x20, conformance: "M" }), + Field({ name: "Numbers1", id: 0x21, conformance: "M" }), + Field({ name: "Numbers2", id: 0x22, conformance: "M" }), + Field({ name: "Numbers3", id: 0x23, conformance: "M" }), + Field({ name: "Numbers4", id: 0x24, conformance: "M" }), + Field({ name: "Numbers5", id: 0x25, conformance: "M" }), + Field({ name: "Numbers6", id: 0x26, conformance: "M" }), + Field({ name: "Numbers7", id: 0x27, conformance: "M" }), + Field({ name: "Numbers8", id: 0x28, conformance: "M" }), + Field({ name: "Numbers9", id: 0x29, conformance: "M" }), + Field({ name: "Dot", id: 0x2a, conformance: "M" }), + Field({ name: "Enter", id: 0x2b, conformance: "M" }), + Field({ name: "Clear", id: 0x2c, conformance: "M" }), + Field({ name: "NextFavorite", id: 0x2f, conformance: "M" }), + Field({ name: "ChannelUp", id: 0x30, conformance: "M" }), + Field({ name: "ChannelDown", id: 0x31, conformance: "M" }), + Field({ name: "PreviousChannel", id: 0x32, conformance: "M" }), + Field({ name: "SoundSelect", id: 0x33, conformance: "M" }), + Field({ name: "InputSelect", id: 0x34, conformance: "M" }), + Field({ name: "DisplayInformation", id: 0x35, conformance: "M" }), + Field({ name: "Help", id: 0x36, conformance: "M" }), + Field({ name: "PageUp", id: 0x37, conformance: "M" }), + Field({ name: "PageDown", id: 0x38, conformance: "M" }), + Field({ name: "Power", id: 0x40, conformance: "M" }), + Field({ name: "VolumeUp", id: 0x41, conformance: "M" }), + Field({ name: "VolumeDown", id: 0x42, conformance: "M" }), + Field({ name: "Mute", id: 0x43, conformance: "M" }), + Field({ name: "Play", id: 0x44, conformance: "M" }), + Field({ name: "Stop", id: 0x45, conformance: "M" }), + Field({ name: "Pause", id: 0x46, conformance: "M" }), + Field({ name: "Record", id: 0x47, conformance: "M" }), + Field({ name: "Rewind", id: 0x48, conformance: "M" }), + Field({ name: "FastForward", id: 0x49, conformance: "M" }), + Field({ name: "Eject", id: 0x4a, conformance: "M" }), + Field({ name: "Forward", id: 0x4b, conformance: "M" }), + Field({ name: "Backward", id: 0x4c, conformance: "M" }), + Field({ name: "StopRecord", id: 0x4d, conformance: "M" }), + Field({ name: "PauseRecord", id: 0x4e, conformance: "M" }), + Field({ name: "Angle", id: 0x50, conformance: "M" }), + Field({ name: "SubPicture", id: 0x51, conformance: "M" }), + Field({ name: "VideoOnDemand", id: 0x52, conformance: "M" }), + Field({ name: "ElectronicProgramGuide", id: 0x53, conformance: "M" }), + Field({ name: "TimerProgramming", id: 0x54, conformance: "M" }), + Field({ name: "InitialConfiguration", id: 0x55, conformance: "M" }), + Field({ name: "SelectBroadcastType", id: 0x56, conformance: "M" }), + Field({ name: "SelectSoundPresentation", id: 0x57, conformance: "M" }), + Field({ name: "PlayFunction", id: 0x60, conformance: "M" }), + Field({ name: "PausePlayFunction", id: 0x61, conformance: "M" }), + Field({ name: "RecordFunction", id: 0x62, conformance: "M" }), + Field({ name: "PauseRecordFunction", id: 0x63, conformance: "M" }), + Field({ name: "StopFunction", id: 0x64, conformance: "M" }), + Field({ name: "MuteFunction", id: 0x65, conformance: "M" }), + Field({ name: "RestoreVolumeFunction", id: 0x66, conformance: "M" }), + Field({ name: "TuneFunction", id: 0x67, conformance: "M" }), + Field({ name: "SelectMediaFunction", id: 0x68, conformance: "M" }), + Field({ name: "SelectAvInputFunction", id: 0x69, conformance: "M" }), + Field({ name: "SelectAudioInputFunction", id: 0x6a, conformance: "M" }), + Field({ name: "PowerToggleFunction", id: 0x6b, conformance: "M" }), + Field({ name: "PowerOffFunction", id: 0x6c, conformance: "M" }), + Field({ name: "PowerOnFunction", id: 0x6d, conformance: "M" }), + Field({ name: "F1Blue", id: 0x71, conformance: "M" }), + Field({ name: "F2Red", id: 0x72, conformance: "M" }), + Field({ name: "F3Green", id: 0x73, conformance: "M" }), + Field({ name: "F4Yellow", id: 0x74, conformance: "M" }), + Field({ name: "F5", id: 0x75, conformance: "M" }), + Field({ name: "Data", id: 0x76, conformance: "M" }) + ) + ), + + Cluster( + { + name: "MediaInput", id: 0x507, classification: "application", pics: "MEDIAINPUT", + + details: "This cluster provides an interface for controlling the Input Selector on a media device such as a " + + "Video Player." + + "\n" + + "This cluster would be implemented on TV and other media streaming devices, as well as devices that " + + "provide input to or output from such devices." + + "\n" + + "This cluster provides the list of available inputs and provides commands for selecting and renaming " + + "them." + + "\n" + + "The cluster server for Media Input is implemented by a device that has selectable input, such as a " + + "Video Player device.", + + xref: { document: "cluster", section: "6.9" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.9.4" } }, + Field({ name: "NU", constraint: "0", description: "NameUpdates", details: "Supports updates to the input names" }) + ), + + Attribute( + { + name: "InputList", id: 0x0, type: "list", access: "R V", conformance: "M", + details: "This attribute shall provide a list of the media inputs supported by the device.", + xref: { document: "cluster", section: "6.9.6.1" } + }, + Field({ name: "entry", type: "InputInfoStruct" }) + ), + + Attribute({ + name: "CurrentInput", id: 0x1, type: "uint8", access: "R V", conformance: "M", + details: "This attribute shall contain the value of the index field of the currently selected InputInfoStruct.", + xref: { document: "cluster", section: "6.9.6.2" } + }), + + Command( + { + name: "SelectInput", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "status", + details: "Upon receipt, this command shall change the media input on the device to the input at a specific" + + "\n" + + "index in the Input List.", + xref: { document: "cluster", section: "6.9.7.1" } + }, + + Field({ + name: "Index", id: 0x0, type: "uint8", conformance: "M", + details: "This field shall indicate the index field of the InputInfoStruct from the InputList attribute in " + + "which to change to.", + xref: { document: "cluster", section: "6.9.7.1.1" } + }) + ), + + Command({ + name: "ShowInputStatus", id: 0x1, access: "O", conformance: "M", direction: "request", + response: "status", + details: "Upon receipt, this command shall display the active status of the input list on screen.", + xref: { document: "cluster", section: "6.9.7.2" } + }), + + Command({ + name: "HideInputStatus", id: 0x2, access: "O", conformance: "M", direction: "request", + response: "status", + details: "Upon receipt, this command shall hide the input list from the screen.", + xref: { document: "cluster", section: "6.9.7.3" } + }), + + Command( + { + name: "RenameInput", id: 0x3, access: "M", conformance: "NU", direction: "request", + response: "status", + details: "Upon receipt, this command shall rename the input at a specific index in the Input List. Updates to " + + "the input name shall appear in the device’s settings menus.", + xref: { document: "cluster", section: "6.9.7.4" } + }, + + Field({ name: "Index", id: 0x0, type: "uint8", conformance: "M" }), + Field({ name: "Name", id: 0x1, type: "string", conformance: "M" }) + ), + + Datatype( + { name: "InputTypeEnum", type: "enum8", xref: { document: "cluster", section: "6.9.5.1" } }, + Field({ + name: "Internal", id: 0x0, conformance: "M", + description: "Indicates content not coming from a physical input." + }), + Field({ name: "Aux", id: 0x1, conformance: "M" }), + Field({ name: "Coax", id: 0x2, conformance: "M" }), + Field({ name: "Composite", id: 0x3, conformance: "M" }), + Field({ name: "Hdmi", id: 0x4, conformance: "M" }), + Field({ name: "Input", id: 0x5, conformance: "M" }), + Field({ name: "Line", id: 0x6, conformance: "M" }), + Field({ name: "Optical", id: 0x7, conformance: "M" }), + Field({ name: "Video", id: 0x8, conformance: "M" }), + Field({ name: "Scart", id: 0x9, conformance: "M" }), + Field({ name: "Usb", id: 0xa, conformance: "M" }), + Field({ name: "Other", id: 0xb, conformance: "M" }) + ), + + Datatype( + { + name: "InputInfoStruct", type: "struct", + details: "This contains information about an input.", + xref: { document: "cluster", section: "6.9.5.2" } + }, + Field({ + name: "Index", id: 0x0, type: "uint8", conformance: "M", + details: "This field shall indicate the unique index into the list of Inputs.", + xref: { document: "cluster", section: "6.9.5.2.1" } + }), + Field({ + name: "InputType", id: 0x1, type: "InputTypeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the type of input", + xref: { document: "cluster", section: "6.9.5.2.2" } + }), + + Field({ + name: "Name", id: 0x2, type: "string", conformance: "M", + details: "This field shall indicate the input name, such as “HDMI 1”. This field may be blank, but SHOULD be " + + "provided when known.", + xref: { document: "cluster", section: "6.9.5.2.3" } + }), + + Field({ + name: "Description", id: 0x3, type: "string", conformance: "M", + details: "This field shall indicate the user editable input description, such as “Living room Playstation”. " + + "This field may be blank, but SHOULD be provided when known.", + xref: { document: "cluster", section: "6.9.5.2.4" } + }) + ) + ), + + Cluster( + { + name: "MediaPlayback", id: 0x506, classification: "application", pics: "MEDIAPLAYBACK", + details: "This cluster provides an interface for controlling Media Playback (PLAY, PAUSE, etc) on a media " + + "device such as a TV, Set-top Box, or Smart Speaker." + + "\n" + + "This cluster server would be supported on Video Player devices or endpoints that provide media " + + "playback, such as a Content App. This cluster provides an interface for controlling Media Playback.", + xref: { document: "cluster", section: "6.10" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.10.4" } }, + + Field({ + name: "AS", constraint: "0", description: "AdvancedSeek", + details: "This feature provides access to the time offset location within current playback media and allows " + + "for jumping to a specific location using time offsets. This enables clients to implement more " + + "advanced media seeking behavior in their user interface, for instance a \"seek bar\".", + xref: { document: "cluster", section: "6.10.4.1" } + }), + + Field({ + name: "VS", constraint: "1", description: "VariableSpeed", + details: "This feature is for a device which supports variable speed playback on media that supports it.", + xref: { document: "cluster", section: "6.10.4.2" } + }), + Field({ + name: "TT", constraint: "2", description: "TextTracks", + details: "This feature is for a device or app that supports Text Tracks.", + xref: { document: "cluster", section: "6.10.4.3" } + }), + Field({ + name: "AT", constraint: "3", description: "AudioTracks", + details: "This feature is for a device or app that supports Audio Tracks.", + xref: { document: "cluster", section: "6.10.4.4" } + }), + + Field({ + name: "AA", constraint: "4", description: "AudioAdvance", + + details: "This feature is for a device or app that supports playing audio during fast and slow advance and" + + "\n" + + "rewind (e.g., while playback speed is not 1). A device that supports this feature may only support " + + "playing audio during certain speeds." + + "\n" + + "A cluster implementing AA shall implement AS.", + + xref: { document: "cluster", section: "6.10.4.5" } + }) + ), + + Attribute({ + name: "CurrentState", id: 0x0, type: "PlaybackStateEnum", access: "R V", conformance: "M", + constraint: "desc", + details: "Indicates the current playback state of media." + + "\n" + + "During fast-forward, rewind, and other seek operations; this attribute shall be set to PLAYING.", + xref: { document: "cluster", section: "6.10.6.1" } + }), + + Attribute({ + name: "StartTime", id: 0x1, type: "epoch-us", access: "R V", conformance: "AS", constraint: "desc", + default: null, quality: "X", + details: "Indicates the start time of the media, in case the media has a fixed start time (for example, live " + + "stream or television broadcast), or null when start time does not apply to the current media (for " + + "example, video-on-demand). This time is a UTC time. The client needs to handle conversion to local " + + "time, as required, taking in account time zone and possible local DST offset.", + xref: { document: "cluster", section: "6.10.6.2" } + }), + + Attribute({ + name: "Duration", id: 0x2, type: "uint64", access: "R V", conformance: "AS", constraint: "desc", + default: null, quality: "X", + details: "Indicates the duration, in milliseconds, of the current media being played back" + + "\n" + + "or null when duration is not applicable (for example, in live streaming content with no known " + + "duration). This attribute shall never be 0.", + xref: { document: "cluster", section: "6.10.6.3" } + }), + + Attribute({ + name: "SampledPosition", id: 0x3, type: "PlaybackPositionStruct", access: "R V", conformance: "AS", + constraint: "desc", default: null, quality: "X", + + details: "Indicates the position of playback (Position field) at the time (UpdateAt field) specified in the " + + "attribute. The client may use the SampledPosition attribute to compute the current position within " + + "the media stream based on the PlaybackSpeed, PlaybackPositionStruct.UpdatedAt and " + + "PlaybackPositionStruct.Position fields. To enable this, the SampledPosition attribute shall be " + + "updated whenever a change in either the playback speed or the playback position is triggered " + + "outside the normal playback of the media. The events which may cause this to happen include:" + + "\n" + + " • Starting or resumption of playback" + + "\n" + + " • Seeking" + + "\n" + + " • Skipping forward or backward" + + "\n" + + " • Fast-forwarding or rewinding" + + "\n" + + " • Updating of playback speed as a result of explicit request, or as a result of buffering events", + + xref: { document: "cluster", section: "6.10.6.4" } + }), + + Attribute({ + name: "PlaybackSpeed", id: 0x4, type: "single", access: "R V", conformance: "AS", + constraint: "desc", default: 0, + + details: "Indicates the speed at which the current media is being played. The new PlaybackSpeed shall be " + + "reflected in this attribute whenever any of the following occurs:" + + "\n" + + " • Starting of playback" + + "\n" + + " • Resuming of playback" + + "\n" + + " • Fast-forwarding" + + "\n" + + " • Rewinding" + + "\n" + + "The PlaybackSpeed shall reflect the ratio of time elapsed in the media to the actual time taken for " + + "the playback assuming no changes to media playback (for example buffering events or requests to " + + "pause/rewind/forward)." + + "\n" + + " • A value for PlaybackSpeed of 1 shall indicate normal playback where, for example, playback for " + + " 1 second causes the media to advance by 1 second within the duration of the media." + + "\n" + + " • A value for PlaybackSpeed which is greater than 0 shall indicate that as playback is happening " + + " the media is currently advancing in time within the duration of the media." + + "\n" + + " • A value for PlaybackSpeed which is less than 0 shall indicate that as playback is happening the " + + " media is currently going back in time within the duration of the media." + + "\n" + + " • A value for PlaybackSpeed of 0 shall indicate that the media is currently not playing back. " + + " When the CurrentState attribute has the value of PAUSED, NOT_PLAYING or BUFFERING, the " + + " PlaybackSpeed shall be set to 0 to reflect that the media is not playing." + + "\n" + + "Following examples illustrate the PlaybackSpeed attribute values in various conditions.", + + xref: { document: "cluster", section: "6.10.6.5" } + }), + + Attribute({ + name: "SeekRangeEnd", id: 0x5, type: "uint64", access: "R V", conformance: "AS", constraint: "desc", + default: null, quality: "X", + + details: "Indicates the furthest forward valid position to which a client may seek forward, in milliseconds " + + "from the start of the media. When the media has an associated StartTime, a value of null shall " + + "indicate that a seek forward is valid only until the current time within the media, using a " + + "position computed from the difference between the current time offset and StartTime, in " + + "milliseconds from start of the media, truncating fractional milliseconds towards 0. A value of Nas " + + "when StartTime is not specified shall indicate that seeking forward is not allowed.", + + xref: { document: "cluster", section: "6.10.6.7" } + }), + + Attribute({ + name: "SeekRangeStart", id: 0x6, type: "uint64", access: "R V", conformance: "AS", + constraint: "desc", default: null, quality: "X", + details: "Indicates the earliest valid position to which a client may seek back, in milliseconds from start " + + "of the media. A value of Nas shall indicate that seeking backwards is not allowed.", + xref: { document: "cluster", section: "6.10.6.6" } + }), + + Attribute({ + name: "ActiveAudioTrack", id: 0x7, type: "TrackStruct", access: "R V", conformance: "AT", + constraint: "desc", default: null, quality: "X", + details: "ActiveTrack refers to the Audio track currently set and being used for the streaming media. A value " + + "of null shall indicate that no Audio Track corresponding to the current media is currently being " + + "played.", + xref: { document: "cluster", section: "6.10.6.8" } + }), + + Attribute( + { + name: "AvailableAudioTracks", id: 0x8, type: "list", access: "R V", conformance: "AT", + constraint: "desc", default: null, quality: "X", + details: "AvailableAudioTracks refers to the list of Audio tracks available for the current title being " + + "played. A value of null shall indicate that no Audio Tracks corresponding to the current media are " + + "selectable by the client.", + xref: { document: "cluster", section: "6.10.6.9" } + }, + + Field({ name: "entry", type: "TrackStruct" }) + ), + + Attribute({ + name: "ActiveTextTrack", id: 0x9, type: "TrackStruct", access: "R V", conformance: "TT", + constraint: "desc", default: null, quality: "X", + details: "ActiveTrack refers to the Text track currently set and being used for the streaming media. This can " + + "be nil. A value of null shall indicate that no Text Track corresponding to the current media is " + + "currently being displayed.", + xref: { document: "cluster", section: "6.10.6.10" } + }), + + Attribute( + { + name: "AvailableTextTracks", id: 0xa, type: "list", access: "R V", conformance: "TT", + constraint: "desc", default: null, quality: "X", + details: "AvailableTextTracks refers to the list of Text tracks available for the current title being played. " + + "This can be an empty list. A value of null shall indicate that no Text Tracks corresponding to the " + + "current media are selectable by the client.", + xref: { document: "cluster", section: "6.10.6.11" } + }, + + Field({ name: "entry", type: "TrackStruct" }) + ), + + Event( + { + name: "StateChanged", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "If supported, this event shall be generated when there is a change in any of the supported " + + "attributes of the Media Playback cluster.", + xref: { document: "cluster", section: "6.10.8.1" } + }, + + Field({ + name: "CurrentState", id: 0x0, type: "PlaybackStateEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the updated playback state as defined by the CurrentState attribute, and " + + "has the same constraint as that attribute.", + xref: { document: "cluster", section: "6.10.8.1.1" } + }), + + Field({ + name: "StartTime", id: 0x1, type: "epoch-us", conformance: "AS", constraint: "desc", + details: "This field shall indicate the updated start time as defined by the StartTime attribute, and has the " + + "same constraint as that attribute.", + xref: { document: "cluster", section: "6.10.8.1.2" } + }), + + Field({ + name: "Duration", id: 0x2, type: "uint64", conformance: "AS", constraint: "desc", + details: "This field shall indicate the updated duration as defined by the Duration attribute, and has the " + + "same constraint as that attribute.", + xref: { document: "cluster", section: "6.10.8.1.3" } + }), + + Field({ + name: "SampledPosition", id: 0x3, type: "PlaybackPositionStruct", conformance: "AS", + constraint: "desc", + details: "This field shall indicate the updated position of playback as defined by the SampledPosition " + + "attribute, and has the same constraint as that attribute.", + xref: { document: "cluster", section: "6.10.8.1.4" } + }), + + Field({ + name: "PlaybackSpeed", id: 0x4, type: "single", conformance: "AS", constraint: "desc", + details: "This field shall indicate the updated speed at which the current media is being played as defined " + + "by the PlaybackSpeed attribute, and has the same constraint as that attribute.", + xref: { document: "cluster", section: "6.10.8.1.5" } + }), + + Field({ + name: "SeekRangeEnd", id: 0x5, type: "uint64", conformance: "AS", constraint: "desc", + details: "This field shall indicate the updated start of the seek range end as defined by the SeekRangeEnd " + + "attribute, and has the same constraint as that attribute.", + xref: { document: "cluster", section: "6.10.8.1.7" } + }), + + Field({ + name: "SeekRangeStart", id: 0x6, type: "uint64", conformance: "AS", constraint: "desc", + details: "This field shall indicate the updated start of the seek range start as defined by the " + + "SeekRangeStart attribute, and has the same constraint as that attribute.", + xref: { document: "cluster", section: "6.10.8.1.6" } + }), + + Field({ + name: "Data", id: 0x7, type: "octstr", conformance: "O", constraint: "max 900", + details: "This field shall indicate Optional app-specific data.", + xref: { document: "cluster", section: "6.10.8.1.8" } + }), + + Field({ + name: "AudioAdvanceUnmuted", id: 0x8, type: "bool", conformance: "AA", constraint: "desc", + default: false, + + details: "This field shall indicate whether audio is unmuted by the player due to a FF or REW command. This " + + "field is only meaningful when the PlaybackSpeed is present and not equal to 0 (paused) or 1 (normal " + + "playback). Typically the value will be false (muted), however, some players will play audio during " + + "certain fast forward and rewind speeds, and in these cases, the value will be true (not muted)." + + "\n" + + "A value of true does not guarantee that audio can be heard by the user since the speaker may be " + + "muted, turned down to a low level and/or unplugged.", + + xref: { document: "cluster", section: "6.10.8.1.9" } + }) + ), + + Command({ + name: "Play", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall play media. If content is currently in a FastForward or Rewind state. Play " + + "shall return media to normal playback speed.", + xref: { document: "cluster", section: "6.10.7.1" } + }), + + Command({ + name: "Pause", id: 0x1, access: "O", conformance: "M", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall pause playback of the media.", + xref: { document: "cluster", section: "6.10.7.2" } + }), + + Command({ + name: "Stop", id: 0x2, access: "O", conformance: "M", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall stop playback of the media. User-visible outcome is context-specific. This " + + "may navigate the user back to the location from where the media was originally launched.", + xref: { document: "cluster", section: "6.10.7.3" } + }), + + Command({ + name: "StartOver", id: 0x3, access: "O", conformance: "O", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall Start Over with the current media playback item.", + xref: { document: "cluster", section: "6.10.7.4" } + }), + + Command({ + name: "Previous", id: 0x4, access: "O", conformance: "O", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall cause the handler to be invoked for \"Previous\". User experience is " + + "context-specific. This will often Go back to the previous media playback item.", + xref: { document: "cluster", section: "6.10.7.5" } + }), + + Command({ + name: "Next", id: 0x5, access: "O", conformance: "O", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall cause the handler to be invoked for \"Next\". User experience is context- " + + "specific. This will often Go forward to the next media playback item.", + xref: { document: "cluster", section: "6.10.7.6" } + }), + + Command( + { + name: "Rewind", id: 0x6, access: "O", conformance: "VS", direction: "request", + response: "PlaybackResponse", + + details: "Upon receipt, this shall start playback of the media backward in case the media is currently " + + "playing in the forward direction or is not playing. If the playback is already happening in the " + + "backwards direction receipt of this command shall increase the speed of the media playback " + + "backwards." + + "\n" + + "Different \"rewind\" speeds may be reflected on the media playback device based upon the number of " + + "sequential calls to this function and the capability of the device. This is to avoid needing to " + + "define every speed (multiple fast, slow motion, etc). If the PlaybackSpeed attribute is supported " + + "it shall be updated to reflect the new speed of playback. If the playback speed cannot be changed " + + "for the media being played(for example, in live streaming content not supporting seek), the status " + + "of NOT_ALLOWED shall be returned. If the playback speed has reached the maximum supported speed for " + + "media playing backwards, the status of SPEED_OUT_OF_RANGE shall be returned.", + + xref: { document: "cluster", section: "6.10.7.7" } + }, + + Field({ + name: "AudioAdvanceUnmuted", id: 0x0, type: "bool", conformance: "AA", default: false, + details: "This field shall indicate whether audio should be unmuted by the player during rewind." + + "\n" + + "A value of true does not guarantee that audio can be heard by the user since the speaker may be " + + "muted, turned down to a low level and/or unplugged.", + xref: { document: "cluster", section: "6.10.7.7.1" } + }) + ), + + Command( + { + name: "FastForward", id: 0x7, access: "O", conformance: "VS", direction: "request", + response: "PlaybackResponse", + + details: "Upon receipt, this shall start playback of the media in the forward direction in case the media is" + + "\n" + + "currently playing in the backward direction or is not playing. If the playback is already happening " + + "in the forward direction receipt of this command shall increase the speed of the media playback." + + "\n" + + "Different \"fast-forward\" speeds may be reflected on the media playback device based upon the number " + + "of sequential calls to this function and the capability of the device. This is to avoid needing to " + + "define every speed (multiple fast, slow motion, etc). If the PlaybackSpeed attribute is supported " + + "it shall be updated to reflect the new speed of playback. If the playback speed cannot be changed " + + "for the media being played(for example, in live streaming content not supporting seek), the status " + + "of NOT_ALLOWED shall be returned. If the playback speed has reached the maximum supported speed for " + + "media playing forward, the status of SPEED_OUT_OF_RANGE shall be returned.", + + xref: { document: "cluster", section: "6.10.7.8" } + }, + + Field({ + name: "AudioAdvanceUnmuted", id: 0x0, type: "bool", conformance: "AA", default: false, + details: "This field shall indicate whether audio should be unmuted by the player during fast forward." + + "\n" + + "A value of true does not guarantee that audio can be heard by the user since the speaker may be " + + "muted, turned down to a low level and/or unplugged.", + xref: { document: "cluster", section: "6.10.7.8.1" } + }) + ), + + Command( + { + name: "SkipForward", id: 0x8, access: "O", conformance: "O", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall Skip forward in the media by the given number of milliseconds.", + xref: { document: "cluster", section: "6.10.7.9" } + }, + + Field({ + name: "DeltaPositionMilliseconds", id: 0x0, type: "uint64", conformance: "M", + + details: "This field shall indicate the duration of the time span to skip forward in the media, in " + + "milliseconds. In case the resulting position falls in the middle of a frame, the server shall set " + + "the position to the beginning of that frame and set the SampledPosition attribute on the cluster " + + "accordingly. If the resultant position falls beyond the furthest valid position in the media the " + + "client may seek forward to, the position should be set to that furthest valid position. If the " + + "SampledPosition attribute is supported it shall be updated on the cluster accordingly.", + + xref: { document: "cluster", section: "6.10.7.9.1" } + }) + ), + + Command( + { + name: "SkipBackward", id: 0x9, access: "O", conformance: "O", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall Skip backward in the media by the given number of milliseconds.", + xref: { document: "cluster", section: "6.10.7.10" } + }, + + Field({ + name: "DeltaPositionMilliseconds", id: 0x0, type: "uint64", conformance: "M", + + details: "This field shall indicate the duration of the time span to skip backward in the media, in " + + "milliseconds. In case the resulting position falls in the middle of a frame, the server shall set " + + "the position to the beginning of that frame and set the SampledPosition attribute on the cluster " + + "accordingly. If the resultant position falls before the earliest valid position to which a client " + + "may seek back to, the position should be set to that earliest valid position. If the " + + "SampledPosition attribute is supported it shall be updated on the cluster accordingly.", + + xref: { document: "cluster", section: "6.10.7.10.1" } + }) + ), + + Command( + { + name: "PlaybackResponse", id: 0xa, conformance: "M", direction: "response", + details: "This command shall be generated in response to various Playback Commands.", + xref: { document: "cluster", section: "6.10.7.12" } + }, + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the status of the command which resulted in this response.", + xref: { document: "cluster", section: "6.10.7.12.1" } + }), + Field({ + name: "Data", id: 0x1, type: "string", conformance: "O", constraint: "any", + details: "This field shall indicate Optional app-specific data.", + xref: { document: "cluster", section: "6.10.7.12.2" } + }) + ), + + Command( + { + name: "Seek", id: 0xb, access: "O", conformance: "AS", direction: "request", + response: "PlaybackResponse", + details: "Upon receipt, this shall change the playback position in the media to the given position.", + xref: { document: "cluster", section: "6.10.7.11" } + }, + + Field({ + name: "Position", id: 0x0, type: "uint64", conformance: "M", + + details: "This field shall indicate the position (in milliseconds) in the media to seek to. In case the " + + "position falls in the middle of a frame, the server shall set the position to the beginning of that " + + "frame and set the SampledPosition attribute on the cluster accordingly. If the position falls " + + "before the earliest valid position or beyond the furthest valid position to which a client may seek " + + "back or forward to respectively, the status of SEEK_OUT_OF_RANGE shall be returned and no change " + + "shall be made to the position of the playback.", + + xref: { document: "cluster", section: "6.10.7.11.1" } + }) + ), + + Command( + { + name: "ActivateAudioTrack", id: 0xc, access: "O", conformance: "AT", direction: "request", + response: "status", + details: "Upon receipt, the server shall set the active Audio Track to the one identified by the TrackID in " + + "the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR " + + "does not correspond to the streaming media OR no media is being streamed at the time of receipt of " + + "this command, the server will return an error status of INVALID_ARGUMENT.", + xref: { document: "cluster", section: "6.10.7.13" } + }, + + Field({ + name: "TrackId", id: 0x0, type: "string", conformance: "M", constraint: "max 32", + details: "This field shall indicate the Audio Track to activate.", + xref: { document: "cluster", section: "6.10.7.13.1" } + }), + + Field({ + name: "AudioOutputIndex", id: 0x1, type: "uint8", conformance: "AT", quality: "X", + details: "This value is the index field of the OutputInfoStruct from the OutputList attribute (from the " + + "AudioOutput cluster) and indicates which audio output the Audio Track should be played on. This " + + "field is absent for Text Tracks and only present for Audio Tracks. A value of null shall indicate " + + "that the server can choose the audio output(s) to play the Audio Track on.", + xref: { document: "cluster", section: "6.10.7.13.2" } + }) + ), + + Command( + { + name: "ActivateTextTrack", id: 0xd, access: "O", conformance: "TT", direction: "request", + response: "status", + details: "Upon receipt, the server shall set the active Text Track to the one identified by the TrackID in " + + "the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR " + + "does not correspond to the streaming media OR no media is being streamed at the time of receipt of " + + "this command, the server shall return an error status of INVALID_ARGUMENT.", + xref: { document: "cluster", section: "6.10.7.14" } + }, + + Field({ + name: "TrackId", id: 0x0, type: "string", conformance: "M", constraint: "max 32", + details: "This field shall indicate the Text Track to activate.", + xref: { document: "cluster", section: "6.10.7.14.1" } + }) + ), + + Command({ + name: "DeactivateTextTrack", id: 0xe, access: "O", conformance: "TT", direction: "request", + response: "status", + details: "If a Text Track is active (i.e. being displayed), upon receipt of this command, the server shall " + + "stop displaying it.", + xref: { document: "cluster", section: "6.10.7.15" } + }), + + Datatype( + { name: "PlaybackStateEnum", type: "enum8", xref: { document: "cluster", section: "6.10.5.1" } }, + Field({ + name: "Playing", id: 0x0, conformance: "M", + description: "Media is currently playing (includes FF and REW)" + }), + Field({ name: "Paused", id: 0x1, conformance: "M", description: "Media is currently paused" }), + Field({ name: "NotPlaying", id: 0x2, conformance: "M", description: "Media is not currently playing" }), + Field({ + name: "Buffering", id: 0x3, conformance: "M", + description: "Media is not currently buffering and playback will start when buffer has been filled" + }) + ), + + Datatype( + { name: "StatusEnum", type: "enum8", xref: { document: "cluster", section: "6.10.5.2" } }, + Field({ name: "Success", id: 0x0, conformance: "M", description: "Succeeded" }), + Field({ + name: "InvalidStateForCommand", id: 0x1, conformance: "M", + description: "Requested playback command is invalid in the current playback state." + }), + Field({ + name: "NotAllowed", id: 0x2, conformance: "M", + description: "Requested playback command is not allowed in the current playback state. For example, attempting to fast-forward during a commercial might return NotAllowed." + }), + Field({ name: "NotActive", id: 0x3, conformance: "M", description: "This endpoint is not active for playback." }), + Field({ + name: "SpeedOutOfRange", id: 0x4, conformance: "VS", + description: "The FastForward or Rewind Command was issued but the media is already playing back at the fastest speed supported by the server in the respective direction." + }), + Field({ + name: "SeekOutOfRange", id: 0x5, conformance: "AS", + description: "The Seek Command was issued with a value of position outside of the allowed seek range of the media." + }) + ), + + Datatype( + { name: "CharacteristicEnum", type: "enum8", xref: { document: "cluster", section: "6.10.5.3" } }, + Field({ + name: "ForcedSubtitles", id: 0x0, conformance: "M", + description: "Textual information meant for display when no other text representation is selected. It is used to clarify dialogue, alternate languages, texted graphics or location/person IDs that are not otherwise covered in the dubbed/localized audio." + }), + Field({ + name: "DescribesVideo", id: 0x1, conformance: "M", + description: "Textual or audio media component containing a textual description (intended for audio synthesis) or an audio description describing a visual component" + }), + Field({ + name: "EasyToRead", id: 0x2, conformance: "M", + description: "Simplified or reduced captions as specified in [United States Code Title 47 CFR 79.103(c)(9)]." + }), + Field({ + name: "FrameBased", id: 0x3, conformance: "M", + description: "A media characteristic that indicates that a track selection option includes frame-based content." + }), + Field({ + name: "MainProgram", id: 0x4, conformance: "M", + description: "Main media component(s) which is/are intended for presentation if no other information is provided" + }), + Field({ + name: "OriginalContent", id: 0x5, conformance: "M", + description: "A media characteristic that indicates that a track or media selection option contains original content." + }), + Field({ + name: "VoiceOverTranslation", id: 0x6, conformance: "M", + description: "A media characteristic that indicates that a track or media selection option contains a language translation and verbal interpretation of spoken dialog." + }), + Field({ + name: "Caption", id: 0x7, conformance: "M", + description: "Textual media component containing transcriptions of spoken dialog and auditory cues such as sound effects and music for the hearing impaired." + }), + Field({ name: "Subtitle", id: 0x8, conformance: "M", description: "Textual transcriptions of spoken dialog." }), + Field({ + name: "Alternate", id: 0x9, conformance: "M", + description: "Textual media component containing transcriptions of spoken dialog and auditory cues such as sound effects and music for the hearing impaired." + }), + Field({ + name: "Supplementary", id: 0xa, conformance: "M", + description: "Media content component that is supplementary to a media content component of a different media component type." + }), + Field({ + name: "Commentary", id: 0xb, conformance: "M", + description: "Experience that contains a commentary (e.g. director’s commentary) (typically audio)" + }), + Field({ + name: "DubbedTranslation", id: 0xc, conformance: "M", + description: "Experience that contains an element that is presented in a different language from the original (e.g. dubbed audio, translated captions)" + }), + Field({ + name: "Description", id: 0xd, conformance: "M", + description: "Textual or audio media component containing a textual description (intended for audio synthesis) or an audio description describing a visual component" + }), + Field({ + name: "Metadata", id: 0xe, conformance: "M", + description: "Media component containing information intended to be processed by application specific elements." + }), + Field({ + name: "EnhancedAudioIntelligibility", id: 0xf, conformance: "M", + description: "Experience containing an element for improved intelligibility of the dialogue." + }), + Field({ + name: "Emergency", id: 0x10, conformance: "M", + description: "Experience that provides information, about a current emergency, that is intended to enable the protection of life, health, safety, and property, and may also include critical details regarding the emergency and how to respond to the emergency." + }), + Field({ + name: "Karaoke", id: 0x11, conformance: "M", + description: "Textual representation of a songs’ lyrics, usually in the same language as the associated song as specified in [SMPTE ST 2067-2]." + }) + ), + + Datatype( + { + name: "PlaybackPositionStruct", type: "struct", + details: "This structure defines a playback position within a media stream being played.", + xref: { document: "cluster", section: "6.10.5.4" } + }, + Field({ + name: "UpdatedAt", id: 0x0, type: "epoch-us", conformance: "M", + details: "This field shall indicate the time when the position was last updated.", + xref: { document: "cluster", section: "6.10.5.4.1" } + }), + + Field({ + name: "Position", id: 0x1, type: "uint64", conformance: "M", quality: "X", + + details: "This field shall indicate the associated discrete position within the media stream, in milliseconds " + + "from the beginning of the stream, being associated with the time indicated by the UpdatedAt field. " + + "The Position shall NOT be greater than the duration of the media if duration is specified. The " + + "Position shall NOT be greater than the time difference between current time and start time of the " + + "media when start time is specified." + + "\n" + + "A value of null shall indicate that playback position is not applicable for the current state of " + + "the media playback (For example : Live media with no known duration and where seek is not " + + "supported).", + + xref: { document: "cluster", section: "6.10.5.4.2" } + }) + ), + + Datatype( + { + name: "TrackStruct", type: "struct", + details: "This structure defines a uniquely identifiable Text Track or Audio Track.", + xref: { document: "cluster", section: "6.10.5.5" } + }, + + Field({ + name: "Id", id: 0x0, type: "string", conformance: "M", constraint: "max 32", + details: "This field shall indicate the Identifier for the Track which is unique within the Track catalog. " + + "The Track catalog contains all the Text/Audio tracks corresponding to the main media content.", + xref: { document: "cluster", section: "6.10.5.5.1" } + }), + + Field({ + name: "TrackAttributes", id: 0x1, type: "TrackAttributesStruct", conformance: "M", + details: "This field shall indicate the Attributes associated to the Track, like languageCode.", + xref: { document: "cluster", section: "6.10.5.5.2" } + }) + ), + + Datatype( + { + name: "TrackAttributesStruct", type: "struct", + details: "This structure includes the attributes associated with a Text/Audio Track", + xref: { document: "cluster", section: "6.10.5.6" } + }, + + Field({ + name: "LanguageCode", id: 0x0, type: "string", conformance: "M", constraint: "max 32", + details: "The value is a String containing one of the standard Tags for Identifying Languages RFC 5646, which " + + "identifies the primary language used in the Track.", + xref: { document: "cluster", section: "6.10.5.6.1" } + }), + + Field( + { + name: "Characteristics", id: 0x1, type: "list", conformance: "O", default: null, quality: "X", + details: "This is a list of enumerated CharacteristicEnum values that indicate a purpose, trait or feature " + + "associated with the Track. A value of null shall indicate that there are no Characteristics " + + "corresponding to the Track.", + xref: { document: "cluster", section: "6.10.5.6.2" } + }, + + Field({ name: "entry", type: "CharacteristicEnum" }) + ), + + Field({ + name: "DisplayName", id: 0x2, type: "string", conformance: "O", constraint: "max 256", + default: null, quality: "X", + details: "The value is a String containing a user displayable name for the Track. A value of null shall " + + "indicate that there is no DisplayName corresponding to the Track.", + xref: { document: "cluster", section: "6.10.5.6.3" } + }) + ) + ), + + Cluster( + { + name: "TargetNavigator", id: 0x505, classification: "application", pics: "TGTNAV", + + details: "This cluster provides an interface for UX navigation within a set of targets on a device or " + + "endpoint." + + "\n" + + "This cluster would be supported on Video Player devices or devices with navigable user interfaces. " + + "This cluster would also be supported on endpoints with navigable user interfaces such as a Content " + + "App. It supports listing a set of navigation targets, tracking and changing the current target." + + "\n" + + "The cluster server for Target Navigator is implemented by endpoints on a device that support UX " + + "navigation." + + "\n" + + "When this cluster is implemented for a Content App endpoint, the Video Player device containing the " + + "endpoint shall launch the Content App when a client invokes the NavigateTarget command.", + + xref: { document: "cluster", section: "6.11" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { + name: "TargetList", id: 0x0, type: "list", access: "R V", conformance: "M", + details: "Indicates a list of targets that can be navigated to within the experience presented to the user by " + + "the Endpoint (Video Player or Content App). The list shall NOT contain any entries with the same " + + "Identifier in the TargetInfoStruct object.", + xref: { document: "cluster", section: "6.11.5.1" } + }, + + Field({ name: "entry", type: "TargetInfoStruct" }) + ), + + Attribute({ + name: "CurrentTarget", id: 0x1, type: "uint8", access: "R V", conformance: "O", constraint: "desc", + default: 255, + details: "Indicates the Identifier for the target which is currently in foreground on the corresponding " + + "Endpoint (Video Player or Content App), or 0xFF to indicate that no target is in the foreground." + + "\n" + + "When not 0xFF, the CurrentTarget shall be an Identifier value contained within one of the " + + "TargetInfoStruct objects in the TargetList attribute.", + xref: { document: "cluster", section: "6.11.5.2" } + }), + + Event( + { + name: "TargetUpdated", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "This event shall be generated when there is a change in either the active target or the list of " + + "available targets or both.", + xref: { document: "cluster", section: "6.11.7.1" } + }, + + Field( + { name: "TargetList", id: 0x0, type: "list", conformance: "O" }, + Field({ name: "entry", type: "TargetInfoStruct" }) + ), + Field({ name: "CurrentTarget", id: 0x1, type: "uint8", conformance: "O", constraint: "desc", default: 255 }), + Field({ name: "Data", id: 0x2, type: "octstr", conformance: "O", constraint: "max 900" }) + ), + + Command( + { + name: "NavigateTarget", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "NavigateTargetResponse", + details: "Upon receipt, this shall navigation the UX to the target identified.", + xref: { document: "cluster", section: "6.11.6.1" } + }, + + Field({ + name: "Target", id: 0x0, type: "uint8", conformance: "M", + details: "This field shall indicate the Identifier for the target for UX navigation. The Target shall be an " + + "Identifier value contained within one of the TargetInfoStruct objects in the TargetList attribute.", + xref: { document: "cluster", section: "6.11.6.1.1" } + }), + + Field({ + name: "Data", id: 0x1, type: "string", conformance: "O", + details: "This field shall indicate Optional app-specific data.", + xref: { document: "cluster", section: "6.11.6.1.2" } + }) + ), + + Command( + { + name: "NavigateTargetResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command shall be generated in response to NavigateTarget command.", + xref: { document: "cluster", section: "6.11.6.2" } + }, + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", + details: "This field shall indicate the of the command.", + xref: { document: "cluster", section: "6.11.6.2.1" } + }), + Field({ + name: "Data", id: 0x1, type: "string", conformance: "O", constraint: "any", + details: "This field shall indicate Optional app-specific data.", + xref: { document: "cluster", section: "6.11.6.2.2" } + }) + ), + + Datatype( + { name: "StatusEnum", type: "enum8", xref: { document: "cluster", section: "6.11.4.1" } }, + Field({ name: "Success", id: 0x0, conformance: "M", description: "Command succeeded" }), + Field({ + name: "TargetNotFound", id: 0x1, conformance: "M", + description: "Requested target was not found in the TargetList" + }), + Field({ + name: "NotAllowed", id: 0x2, conformance: "M", + description: "Target request is not allowed in current state." + }) + ), + + Datatype( + { + name: "TargetInfoStruct", type: "struct", + details: "This indicates an object describing the navigable target.", + xref: { document: "cluster", section: "6.11.4.2" } + }, + Field({ + name: "Identifier", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall contain an unique id within the TargetList.", + xref: { document: "cluster", section: "6.11.4.2.1" } + }), + Field({ + name: "Name", id: 0x1, type: "string", conformance: "M", + details: "This field shall contain a name string for the TargetInfoStruct.", + xref: { document: "cluster", section: "6.11.4.2.2" } + }) + ) + ), + + Cluster( + { + name: "ContentAppObserver", id: 0x510, classification: "application", pics: "APPOBSERVER", + + details: "This cluster provides an interface for sending targeted commands to an Observer of a Content App on " + + "a Video Player device such as a Streaming Media Player, Smart TV or Smart Screen." + + "\n" + + "The cluster server for Content App Observer is implemented by an endpoint that communicates with a " + + "Content App, such as a Casting Video Client." + + "\n" + + "The cluster client for Content App Observer is implemented by a Content App endpoint." + + "\n" + + "A Content App is informed of the NodeId of an Observer when a binding is set on the Content App. " + + "For a Content App Platform, the binding is set by the platform when a CastingVideoClient is granted " + + "access to the Content App, and the CastingVideoClient supports the Content App Observer cluster. " + + "The Content App can then send the ContentAppMessage to the Observer (server cluster), and the " + + "Observer responds with a ContentAppMessageResponse." + + "\n" + + "The Data and EncodingHint fields of the ContentAppMessage and ContentAppMessageResponse contain " + + "content app-specific values, the format and interpretation of which is defined by the Content App " + + "vendor, analogous to the custom message features offered by other popular casting protocols. " + + "Standardized cluster and commands are used here rather than manufacturer-specific cluster and " + + "commands because of the role that the Content App Platform plays in creating the ACLs and Bindings " + + "on both sides of the communication between the Content App Observer endpoint and the Content App " + + "endpoint." + + "\n" + + "By using standard cluster and commands:" + + "\n" + + " 1. The Content App Platform is able to easily determine that a binding is needed on the Content " + + " App endpoint because it can recognize the Content App Observer cluster implemented by a client " + + " node." + + "\n" + + " 2. The Content App Platform is able to easily identify commands that are allowed to be sent by " + + " the Content App to a client node because those commands use the Content App Observer cluster." + + "\n" + + " 3. The Content App is able to easily determine that a node supports the Content App Observer " + + " cluster because it has received a binding which specifies the Content App Observer cluster." + + "\n" + + " 4. The Casting Video Client is able to support a single cluster for receiving commands from any " + + " Content App and does not need to explicitly list every Content App it understands." + + "\n" + + "A Content App Observer SHOULD ignore the Data and EncodingHint field values in commands from a " + + "Content App it does not recognize. A Content App SHOULD ignore the Data field values in responses " + + "when the EncodingHint value is blank or not recognized.", + + xref: { document: "cluster", section: "6.12" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Command( + { + name: "ContentAppMessage", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "ContentAppMessageResponse", + details: "Upon receipt, the data field may be parsed and interpreted. Message encoding is specific to the " + + "Content App. A Content App may when possible read attributes from the Basic Information Cluster on " + + "the Observer and use this to determine the Message encoding." + + "\n" + + "This command returns a ContentAppMessage Response.", + xref: { document: "cluster", section: "6.12.5.1" } + }, + + Field({ + name: "Data", id: 0x0, type: "string", conformance: "M", constraint: "max 500", + details: "This field shall indicate content app-specific data.", + xref: { document: "cluster", section: "6.12.5.1.1" } + }), + Field({ + name: "EncodingHint", id: 0x1, type: "string", conformance: "O", constraint: "max 100", + details: "This optional field shall indicate a content app-specific hint to the encoding of the data.", + xref: { document: "cluster", section: "6.12.5.1.2" } + }) + ), + + Command( + { + name: "ContentAppMessageResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command shall be generated in response to ContentAppMessage command.", + xref: { document: "cluster", section: "6.12.5.2" } + }, + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", + details: "This field shall indicate the status of the command which resulted in this response.", + xref: { document: "cluster", section: "6.12.5.2.1" } + }), + Field({ + name: "Data", id: 0x1, type: "string", conformance: "O", constraint: "max 500", + details: "This optional field shall indicate content app-specific data.", + xref: { document: "cluster", section: "6.12.5.2.2" } + }), + Field({ + name: "EncodingHint", id: 0x2, type: "string", conformance: "O", constraint: "max 100", + details: "This optional field shall indicate a content app-specific hint to the encoding of the data.", + xref: { document: "cluster", section: "6.12.5.2.3" } + }) + ), + + Datatype( + { name: "StatusEnum", type: "enum8", xref: { document: "cluster", section: "6.12.4.1" } }, + Field({ name: "Success", id: 0x0, conformance: "M", description: "Command succeeded" }), + Field({ + name: "UnexpectedData", id: 0x1, conformance: "M", + description: "Data field in command was not understood by the Observer" + }) + ) + ), + + Cluster( + { + name: "ContentControl", id: 0x50f, classification: "application", pics: "CONCON", + + details: "This cluster is used for managing the content control (including \"parental control\") settings on a" + + "\n" + + "media device such as a TV, or Set-top Box." + + "\n" + + "This cluster allows to configure content control settings by clients with the Management privilege. " + + "It is responsibility of the end product to enforce appropriate right access (for example, to " + + "prevent a child from disabling this feature)." + + "\n" + + "NOTE Support for Content Control cluster is provisional.", + + xref: { document: "cluster", section: "6.13" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.13.4" } }, + Field({ + name: "ST", constraint: "0", description: "ScreenTime", + details: "Supports managing screen time limits." + }), + Field({ + name: "PM", constraint: "1", description: "PinManagement", + details: "Supports managing a PIN code which is used for restricting access to configuration of this feature." + }), + Field({ + name: "BU", constraint: "2", description: "BlockUnrated", + details: "Supports managing content controls for unrated content." + }), + Field({ + name: "OCR", constraint: "3", description: "OnDemandContentRating", + details: "Supports managing content controls based upon rating threshold for on demand content." + }), + Field({ + name: "SCR", constraint: "4", description: "ScheduledContentRating", + details: "Supports managing content controls based upon rating threshold for scheduled content." + }), + Field({ + name: "BC", constraint: "5", description: "BlockChannels", + details: "Supports managing a set of channels that are prohibited." + }), + Field({ + name: "BA", constraint: "6", description: "BlockApplications", + details: "Supports managing a set of applications that are prohibited." + }), + Field({ + name: "BTW", constraint: "7", description: "BlockContentTimeWindow", + details: "Supports managing content controls based upon setting time window in which all contents and " + + "applications SHALL be blocked." + }) + ), + + Attribute({ + name: "Enabled", id: 0x0, type: "bool", access: "R V", conformance: "M", + details: "Indicates whether the Content Control feature implemented on a media device is turned off (FALSE) " + + "or turned on (TRUE).", + xref: { document: "cluster", section: "6.13.7.1" } + }), + + Attribute( + { + name: "OnDemandRatings", id: 0x1, type: "list", access: "R V", conformance: "OCR", + + details: "This attribute shall provide the collection of ratings that are currently valid for this media " + + "device. The items should honor the metadata of the on-demand content (e.g. Movie) rating system for " + + "one country or region where the media device has been provisioned. For example, for the MPAA " + + "system, RatingName may be one value out of \"G\", \"PG\", \"PG-13\", \"R\", \"NC-17\"." + + "\n" + + "The media device shall have a way to determine which rating system applies for the on-demand " + + "content and then populate this attribute. For example, it can do it through examining the Location " + + "attribute in the Basic Information cluster, and then determining which rating system applies." + + "\n" + + "The ratings in this collection shall be in order from a rating for the youngest viewers to the one " + + "for the oldest viewers. Each rating in the list shall be unique.", + + xref: { document: "cluster", section: "6.13.7.2" } + }, + + Field({ name: "entry", type: "RatingNameStruct" }) + ), + + Attribute({ + name: "OnDemandRatingThreshold", id: 0x2, type: "string", access: "R V", conformance: "OCR", + constraint: "max 8", + + details: "Indicates a threshold rating as a content filter which is compared with the rating for on-demand " + + "content. For example, if the on-demand content rating is greater than or equal to " + + "OnDemandRatingThreshold, for a rating system that is ordered from lower viewer age to higher viewer " + + "age, then on-demand content is not appropriate for the User and the Node shall prevent the playback " + + "of content." + + "\n" + + "This attribute shall be set to one of the values present in the OnDemandRatings attribute." + + "\n" + + "When this attribute changes, the device SHOULD make the user aware of any limits of this feature. " + + "For example, if the feature does not control content within apps, then the device should make this " + + "clear to the user when the attribute changes.", + + xref: { document: "cluster", section: "6.13.7.3" } + }), + + Attribute( + { + name: "ScheduledContentRatings", id: 0x3, type: "list", access: "R V", conformance: "SCR", + + details: "Indicates a collection of ratings which ScheduledContentRatingThreshold can be set to. The items " + + "should honor metadata of the scheduled content rating system for the country or region where the " + + "media device has been provisioned." + + "\n" + + "The media device shall have a way to determine which scheduled content rating system applies and " + + "then populate this attribute. For example, this can be done by examining the Location attribute in " + + "Basic Information cluster, and then determining which rating system applies." + + "\n" + + "The ratings in this collection shall be in order from a rating for the youngest viewers to the one " + + "for the oldest viewers. Each rating in the list shall be unique.", + + xref: { document: "cluster", section: "6.13.7.4" } + }, + + Field({ name: "entry", type: "RatingNameStruct" }) + ), + + Attribute({ + name: "ScheduledContentRatingThreshold", id: 0x4, type: "string", access: "R V", conformance: "SCR", + constraint: "max 8", + + details: "Indicates a threshold rating as a content filter which is used to compare with the rating for " + + "scheduled content. For example, if the scheduled content rating is greater than or equal to " + + "ScheduledContentRatingThreshold for a rating system that is ordered from lower viewer age to higher " + + "viewer age, then the scheduled content is not appropriate for the User and shall be blocked." + + "\n" + + "This attribute shall be set to one of the values present in the ScheduledContentRatings attribute." + + "\n" + + "When this attribute changes, the device SHOULD make the user aware of any limits of this feature. " + + "For example, if the feature does not control content within apps, then the device should make this " + + "clear to the user when the attribute changes.", + + xref: { document: "cluster", section: "6.13.7.5" } + }), + + Attribute({ + name: "ScreenDailyTime", id: 0x5, type: "elapsed-s", access: "R V", conformance: "ST", + constraint: "max 86400", + details: "Indicates the amount of time (in seconds) which the User is allowed to spend watching TV within one " + + "day when the Content Control feature is activated.", + xref: { document: "cluster", section: "6.13.7.6" } + }), + + Attribute({ + name: "RemainingScreenTime", id: 0x6, type: "elapsed-s", access: "R V", conformance: "ST", + constraint: "max 86400", + + details: "Indicates the remaining screen time (in seconds) which the User is allowed to spend watching TV for " + + "the current day when the Content Control feature is activated. When this value equals 0, the media " + + "device shall terminate the playback of content." + + "\n" + + "This attribute shall be updated when the AddBonusTime command is received and processed " + + "successfully (with the correct PIN).", + + xref: { document: "cluster", section: "6.13.7.7" } + }), + + Attribute({ + name: "BlockUnrated", id: 0x7, type: "bool", access: "R V", conformance: "BU", + + details: "Indicates whether the playback of unrated content is allowed when the Content Control feature is " + + "activated. If this attribute equals FALSE, then playback of unrated content shall be permitted. " + + "Otherwise, the media device shall prevent the playback of unrated content." + + "\n" + + "When this attribute changes, the device SHOULD make the user aware of any limits of this feature. " + + "For example, if the feature does not control content within apps, then the device should make this " + + "clear to the user when the attribute changes.", + + xref: { document: "cluster", section: "6.13.7.8" } + }), + + Attribute( + { + name: "BlockChannelList", id: 0x8, type: "list", access: "R V", conformance: "BC", + details: "Indicates a set of channels that shall be blocked when the Content Control feature is activated.", + xref: { document: "cluster", section: "6.13.7.9" } + }, + Field({ name: "entry", type: "BlockChannelStruct" }) + ), + + Attribute( + { + name: "BlockApplicationList", id: 0x9, type: "list", access: "R V", conformance: "BA", + details: "Indicates a set of applications that shall be blocked when the Content Control feature is activated.", + xref: { document: "cluster", section: "6.13.7.10" } + }, + Field({ name: "entry", type: "AppInfoStruct" }) + ), + + Attribute( + { + name: "BlockContentTimeWindow", id: 0xa, type: "list", access: "R V", conformance: "BTW", + constraint: "max 7", + + details: "Indicates a set of periods during which the playback of content on media device shall be blocked " + + "when the Content Control feature is activated. The media device shall reject any request to play " + + "content during one period of this attribute. If it is entering any one period of this attribute, " + + "the media device shall block content which is playing and generate an event " + + "EnteringBlockContentTimeWindow. There shall NOT be multiple entries in this attribute list for the " + + "same day of week.", + + xref: { document: "cluster", section: "6.13.7.11" } + }, + + Field({ name: "entry", type: "TimeWindowStruct" }) + ), + + Event({ + name: "RemainingScreenTimeExpired", id: 0x0, access: "V", conformance: "ST", priority: "info", + details: "This event shall be generated when the RemainingScreenTime equals 0.", + xref: { document: "cluster", section: "6.13.9.1" } + }), + + Event({ + name: "EnteringBlockContentTimeWindow", id: 0x1, access: "V", conformance: "BTW", priority: "info", + details: "This event shall be generated when entering a period of blocked content as configured in the " + + "BlockContentTimeWindow attribute.", + xref: { document: "cluster", section: "6.13.9.2" } + }), + + Command( + { + name: "UpdatePin", id: 0x0, access: "M T", conformance: "PM", direction: "request", + response: "status", + + details: "The purpose of this command is to update the PIN used for protecting configuration of the content " + + "control settings. Upon success, the old PIN shall no longer work." + + "\n" + + "The PIN is used to ensure that only the Node (or User) with the PIN code can make changes to the " + + "Content Control settings, for example, turn off Content Controls or modify the ScreenDailyTime. The " + + "PIN is composed of a numeric string of up to 6 human readable characters (displayable) ." + + "\n" + + "Upon receipt of this command, the media device shall check if the OldPIN field of this command is " + + "the same as the current PIN. If the PINs are the same, then the PIN code shall be set to NewPIN. " + + "Otherwise a response with InvalidPINCode error status shall be returned." + + "\n" + + "The media device may provide a default PIN to the User via an out of band mechanism. For security " + + "reasons, it is recommended that a client encourage the user to update the PIN from its default " + + "value when performing configuration of the Content Control settings exposed by this cluster. The " + + "ResetPIN command can also be used to obtain the default PIN.", + + xref: { document: "cluster", section: "6.13.8.1" } + }, + + Field({ + name: "OldPin", id: 0x0, type: "string", conformance: "M", constraint: "max 6", + details: "This field shall specify the original PIN. Once the UpdatePIN command is performed successfully, it " + + "shall be invalid.", + xref: { document: "cluster", section: "6.13.8.1.1" } + }), + + Field({ + name: "NewPin", id: 0x1, type: "string", conformance: "M", constraint: "max 6", + details: "This field shall indicate a new PIN for the Content Control feature.", + xref: { document: "cluster", section: "6.13.8.1.2" } + }) + ), + + Command({ + name: "ResetPin", id: 0x1, access: "A T", conformance: "PM", direction: "request", + response: "ResetPinResponse", + details: "The purpose of this command is to reset the PIN." + + "\n" + + "If this command is executed successfully, a ResetPINResponse command with a new PIN shall be " + + "returned.", + xref: { document: "cluster", section: "6.13.8.2" } + }), + + Command( + { + name: "ResetPinResponse", id: 0x2, conformance: "PM", direction: "response", + details: "This command shall be generated in response to a ResetPIN command.", + xref: { document: "cluster", section: "6.13.8.3" } + }, + Field({ + name: "PinCode", id: 0x0, type: "string", conformance: "M", constraint: "max 6", + details: "This field shall indicate a new PIN of the Content Control feature.", + xref: { document: "cluster", section: "6.13.8.3.1" } + }) + ), + + Command({ + name: "Enable", id: 0x3, access: "M T", conformance: "M", direction: "request", response: "status", + details: "The purpose of this command is to turn on the Content Control feature on a media device." + + "\n" + + "Upon receipt of the Enable command, the media device shall set the Enabled attribute to TRUE.", + xref: { document: "cluster", section: "6.13.8.4" } + }), + + Command({ + name: "Disable", id: 0x4, access: "M T", conformance: "M", direction: "request", response: "status", + details: "The purpose of this command is to turn off the Content Control feature on a media device." + + "\n" + + "On receipt of the Disable command, the media device shall set the Enabled attribute to FALSE.", + xref: { document: "cluster", section: "6.13.8.5" } + }), + + Command( + { + name: "AddBonusTime", id: 0x5, access: "O", conformance: "ST", direction: "request", + response: "status", + + details: "The purpose of this command is to add the extra screen time for the user." + + "\n" + + "If a client with Operate privilege invokes this command, the media device shall check whether the " + + "PINCode passed in the command matches the current PINCode value. If these match, then the " + + "RemainingScreenTime attribute shall be increased by the specified BonusTime value." + + "\n" + + "If the PINs do not match, then a response with InvalidPINCode error status shall be returned, and " + + "no changes shall be made to RemainingScreenTime." + + "\n" + + "If a client with Manage privilege or greater invokes this command, the media device shall ignore " + + "the PINCode field and directly increase the RemainingScreenTime attribute by the specified " + + "BonusTime value." + + "\n" + + "A server that does not support the PM feature shall respond with InvalidPINCode to clients that " + + "only have Operate privilege unless:" + + "\n" + + " • It has been provided with the PIN value to expect via an out of band mechanism, and" + + "\n" + + " • The client has provided a PINCode that matches the expected PIN value.", + + xref: { document: "cluster", section: "6.13.8.6" } + }, + + Field({ + name: "PinCode", id: 0x0, type: "string", conformance: "O", constraint: "max 6", + + details: "This field shall indicate the PIN." + + "\n" + + "This field shall be optional for clients with Manage or greater privilege but shall be mandatory " + + "for clients with Operate privilege. The PIN provided in this field shall be used to guarantee that " + + "a client with Operate permission is allowed to invoke this command only if the PIN passed in this " + + "command is equal to the current PIN value.", + + xref: { document: "cluster", section: "6.13.8.6.1" } + }), + + Field({ + name: "BonusTime", id: 0x1, type: "elapsed-s", conformance: "M", constraint: "desc", default: 300, + details: "This field shall indicate the amount of extra time (in seconds) to increase RemainingScreenTime. " + + "This field shall NOT exceed the remaining time of this day.", + xref: { document: "cluster", section: "6.13.8.6.2" } + }) + ), + + Command( + { + name: "SetScreenDailyTime", id: 0x6, access: "M", conformance: "ST", direction: "request", + response: "status", + details: "The purpose of this command is to set the ScreenDailyTime attribute." + + "\n" + + "Upon receipt of the SetScreenDailyTime command, the media device shall set the ScreenDailyTime " + + "attribute to the ScreenTime value.", + xref: { document: "cluster", section: "6.13.8.7" } + }, + + Field({ + name: "ScreenTime", id: 0x0, type: "elapsed-s", conformance: "M", constraint: "max 86400", + details: "This field shall indicate the time (in seconds) which the User is allowed to spend watching TV on " + + "this media device within one day.", + xref: { document: "cluster", section: "6.13.8.7.1" } + }) + ), + + Command({ + name: "BlockUnratedContent", id: 0x7, access: "M", conformance: "BU", direction: "request", + response: "status", + details: "The purpose of this command is to specify whether programs with no Content rating must be blocked " + + "by this media device." + + "\n" + + "Upon receipt of the BlockUnratedContent command, the media device shall set the BlockUnrated " + + "attribute to TRUE.", + xref: { document: "cluster", section: "6.13.8.8" } + }), + + Command({ + name: "UnblockUnratedContent", id: 0x8, access: "M", conformance: "BU", direction: "request", + response: "status", + details: "The purpose of this command is to specify whether programs with no Content rating must be blocked " + + "by this media device." + + "\n" + + "Upon receipt of the UnblockUnratedContent command, the media device shall set the BlockUnrated " + + "attribute to FALSE.", + xref: { document: "cluster", section: "6.13.8.9" } + }), + + Command( + { + name: "SetOnDemandRatingThreshold", id: 0x9, access: "M", conformance: "OCR", direction: "request", + response: "status", + details: "The purpose of this command is to set the OnDemandRatingThreshold attribute." + + "\n" + + "Upon receipt of the SetOnDemandRatingThreshold command, the media device shall check if the Rating " + + "field is one of values present in the OnDemandRatings attribute. If not, then a response with " + + "InvalidRating error status shall be returned.", + xref: { document: "cluster", section: "6.13.8.10" } + }, + + Field({ + name: "Rating", id: 0x0, type: "string", conformance: "M", constraint: "max 8", + details: "This field indicates a threshold rating for filtering on-demand content. This field shall be set to " + + "one of the values present in the OnDemandRatings attribute", + xref: { document: "cluster", section: "6.13.8.10.1" } + }) + ), + + Command( + { + name: "SetScheduledContentRatingThreshold", id: 0xa, access: "M", conformance: "SCR", + direction: "request", response: "status", + details: "The purpose of this command is to set ScheduledContentRatingThreshold attribute." + + "\n" + + "Upon receipt of the SetScheduledContentRatingThreshold command, the media device shall check if the " + + "Rating field is one of values present in the ScheduledContentRatings attribute. If not, then a " + + "response with InvalidRating error status shall be returned.", + xref: { document: "cluster", section: "6.13.8.11" } + }, + + Field({ + name: "Rating", id: 0x0, type: "string", conformance: "M", constraint: "max 8", + details: "This field indicates a threshold rating for filtering scheduled content. This field shall be set to " + + "one of the values present in the ScheduledContentRatings attribute.", + xref: { document: "cluster", section: "6.13.8.11.1" } + }) + ), + + Command( + { + name: "AddBlockChannels", id: 0xb, access: "M", conformance: "BC", direction: "request", + response: "status", + + details: "The purpose of this command is to set BlockChannelList attribute." + + "\n" + + "Upon receipt of the AddBlockChannels command, the media device shall check if the channels" + + "\n" + + "passed in this command are valid. If the channel is invalid, then a response with InvalidChannel " + + "error Status shall be returned." + + "\n" + + "If there is at least one channel in Channels field which is not in the BlockChannelList attribute, " + + "the media device shall process the request by adding these new channels into the BlockChannelList " + + "attribute and return a successful Status Response. During this process, the media device shall " + + "assign one unique index to BlockChannelIndex field for every channel passed in this command." + + "\n" + + "If all channels in Channel field already exist in the BlockChannelList attribute, then a response " + + "with ChannelAlreadyExist error Status shall be returned.", + + xref: { document: "cluster", section: "6.13.8.12" } + }, + + Field( + { + name: "Channels", id: 0x0, type: "list", conformance: "M", + details: "This field indicates a set of channels that shall be blocked when the Content Control feature is " + + "activated. This field shall be set to values present in ChannelList attribute in the Channel " + + "cluster. The BlockChannelIndex field passed in this command shall be NULL.", + xref: { document: "cluster", section: "6.13.8.12.1" } + }, + + Field({ name: "entry", type: "BlockChannelStruct" }) + ) + ), + + Command( + { + name: "RemoveBlockChannels", id: 0xc, access: "M", conformance: "BC", direction: "request", + response: "status", + + details: "The purpose of this command is to remove channels from the BlockChannelList attribute." + + "\n" + + "Upon receipt of the RemoveBlockChannels command, the media device shall check if the channels " + + "indicated by ChannelIndexes passed in this command are present in BlockChannelList attribute. If " + + "one or more channels indicated by ChannelIndexes passed in this command field are not present in " + + "the BlockChannelList attribute, then a response with ChannelNotExist error Status shall be returned.", + + xref: { document: "cluster", section: "6.13.8.13" } + }, + + Field( + { + name: "ChannelIndexes", id: 0x0, type: "list", conformance: "M", + details: "This field shall specify a set of indexes indicating Which channels shall be removed from the " + + "BlockChannelList attribute.", + xref: { document: "cluster", section: "6.13.8.13.1" } + }, + + Field({ name: "entry", type: "uint16" }) + ) + ), + + Command( + { + name: "AddBlockApplications", id: 0xd, access: "M", conformance: "BA", direction: "request", + response: "status", + + details: "The purpose of this command is to set applications to the BlockApplicationList attribute." + + "\n" + + "Upon receipt of the AddBlockApplications command, the media device shall check if the Applications " + + "passed in this command are installed. If there is an application in Applications field which is not " + + "identified by media device, then a response with UnidentifiableApplication error Status may be" + + "\n" + + "returned." + + "\n" + + "If there is one or more applications which are not present in BlockApplicationList attribute, the " + + "media device shall process the request by adding the new application to the BlockApplicationList " + + "attribute and return a successful Status Response." + + "\n" + + "If all applications in Applications field are already present in BlockApplicationList attribute, " + + "then a response with ApplicationAlreadyExist error Status shall be returned.", + + xref: { document: "cluster", section: "6.13.8.14" } + }, + + Field( + { + name: "Applications", id: 0x0, type: "list", conformance: "M", + details: "This field indicates a set of applications that shall be blocked when the Content Control feature " + + "is activated.", + xref: { document: "cluster", section: "6.13.8.14.1" } + }, + + Field({ name: "entry", type: "AppInfoStruct" }) + ) + ), + + Command( + { + name: "RemoveBlockApplications", id: 0xe, access: "M", conformance: "BA", direction: "request", + response: "status", + + details: "The purpose of this command is to remove applications from the BlockApplicationList attribute." + + "\n" + + "Upon receipt of the RemoveBlockApplications command, the media device shall check if the " + + "applications passed in this command present in the BlockApplicationList attribute. If one or more " + + "applications in Applications field which are not present in the BlockApplicationList attribute, " + + "then a response with ApplicationNotExist error Status shall be returned.", + + xref: { document: "cluster", section: "6.13.8.15" } + }, + + Field( + { + name: "Applications", id: 0x0, type: "list", conformance: "M", + details: "This field indicates a set of applications which shall be removed from BlockApplicationList " + + "attribute.", + xref: { document: "cluster", section: "6.13.8.15.1" } + }, + + Field({ name: "entry", type: "AppInfoStruct" }) + ) + ), + + Command( + { + name: "SetBlockContentTimeWindow", id: 0xf, access: "M", conformance: "BTW", direction: "request", + response: "status", + + details: "The purpose of this command is to set the BlockContentTimeWindow attribute." + + "\n" + + "Upon receipt of the SetBlockContentTimeWindow command, the media device shall check if the " + + "TimeWindowIndex field passed in this command is NULL. If the TimeWindowIndex field is NULL, the " + + "media device shall check if there is an entry in the BlockContentTimeWindow attribute which matches " + + "with the TimePeriod and DayOfWeek fields passed in this command. * If Yes, then a response with " + + "TimeWindowAlreadyExist error status shall be returned. * If No, then the media device shall assign " + + "one unique index for this time window and add it into the BlockContentTimeWindow list attribute." + + "\n" + + "If the TimeWindowIndex field is not NULL and presents in the BlockContentTimeWindow attribute, the " + + "media device shall replace the original time window with the new time window passed in this command.", + + xref: { document: "cluster", section: "6.13.8.16" } + }, + + Field({ + name: "TimeWindow", id: 0x0, type: "TimeWindowStruct", conformance: "M", + details: "This field shall indicate a time window requested to set to the BlockContentTimeWindow attribute.", + xref: { document: "cluster", section: "6.13.8.16.1" } + }) + ), + + Command( + { + name: "RemoveBlockContentTimeWindow", id: 0x10, access: "M", conformance: "BTW", + direction: "request", response: "status", + + details: "The purpose of this command is to remove the selected time windows from the BlockContentTimeWindow " + + "attribute." + + "\n" + + "Upon receipt of the RemoveBlockContentTimeWindow command, the media device shall check if the time " + + "window index passed in this command presents in the BlockContentTimeWindow attribute." + + "\n" + + "If one or more time window indexes passed in this command are not present in BlockContentTimeWindow " + + "attribute, then a response with TimeWindowNotExist error status shall be returned.", + + xref: { document: "cluster", section: "6.13.8.17" } + }, + + Field( + { + name: "TimeWindowIndexes", id: 0x0, type: "list", conformance: "M", + details: "This field shall specify a set of time window indexes indicating which time windows will be removed " + + "from the BlockContentTimeWindow attribute.", + xref: { document: "cluster", section: "6.13.8.17.1" } + }, + + Field({ name: "entry", type: "uint16" }) + ) + ), + + Datatype( + { name: "DayOfWeekBitmap", type: "map8", xref: { document: "cluster", section: "6.13.5.1" } }, + Field({ name: "Sunday", constraint: "0", description: "Sunday" }), + Field({ name: "Monday", constraint: "1", description: "Monday" }), + Field({ name: "Tuesday", constraint: "2", description: "Tuesday" }), + Field({ name: "Wednesday", constraint: "3", description: "Wednesday" }), + Field({ name: "Thursday", constraint: "4", description: "Thursday" }), + Field({ name: "Friday", constraint: "5", description: "Friday" }), + Field({ name: "Saturday", constraint: "6", description: "Saturday" }) + ), + + Datatype( + { name: "RatingNameStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.2" } }, + + Field({ + name: "RatingName", id: 0x0, type: "string", conformance: "M", constraint: "max 8", + details: "This field shall indicate the name of the rating level of the applied rating system. The applied " + + "rating system is dependent upon the region or country where the Node has been provisioned, and may " + + "vary from one country to another.", + xref: { document: "cluster", section: "6.13.5.2.1" } + }), + + Field({ + name: "RatingNameDesc", id: 0x1, type: "string", conformance: "O", constraint: "max 64", + details: "This field shall specify a human readable (displayable) description for RatingName.", + xref: { document: "cluster", section: "6.13.5.2.2" } + }) + ), + + Datatype( + { name: "BlockChannelStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.3" } }, + + Field({ + name: "BlockChannelIndex", id: 0x0, type: "uint16", conformance: "M", quality: "X", + details: "This field shall indicate a unique index value for a blocked channel. This value may be used to " + + "indicate one selected channel which will be removed from BlockChannelList attribute.", + xref: { document: "cluster", section: "6.13.5.3.1" } + }), + + Field({ + name: "MajorNumber", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall indicate the channel major number value (for example, using ATSC format). When the " + + "channel number is expressed as a string, such as \"13.1\" or \"256\", the major number would be 13 or " + + "256, respectively. This field is required but shall be set to 0 for channels such as over-the-top " + + "channels that are not represented by a major or minor number.", + xref: { document: "cluster", section: "6.13.5.3.2" } + }), + + Field({ + name: "MinorNumber", id: 0x2, type: "uint16", conformance: "M", + details: "This field shall indicate the channel minor number value (for example, using ATSC format). When the " + + "channel number is expressed as a string, such as \"13.1\" or \"256\", the minor number would be 1 or 0, " + + "respectively. This field is required but shall be set to 0 for channels such as over-the-top " + + "channels that are not represented by a major or minor number.", + xref: { document: "cluster", section: "6.13.5.3.3" } + }), + + Field({ + name: "Identifier", id: 0x3, type: "string", conformance: "O", + details: "This field shall indicate the unique identifier for a specific channel. This field is optional, but " + + "SHOULD be provided when MajorNumber and MinorNumber are not available.", + xref: { document: "cluster", section: "6.13.5.3.4" } + }) + ), + + Datatype( + { name: "AppInfoStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.4" } }, + + Field({ + name: "CatalogVendorId", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall indicate the CSA-issued vendor ID for the catalog. The DIAL registry shall use " + + "value 0x0000." + + "\n" + + "Content App Platform providers will have their own catalog vendor ID (set to their own Vendor ID) " + + "and will assign an ApplicationID to each Content App.", + xref: { document: "cluster", section: "6.13.5.4.1" } + }), + + Field({ + name: "ApplicationId", id: 0x1, type: "string", conformance: "M", + details: "This field shall indicate the application identifier, expressed as a string, such as \"PruneVideo\" " + + "or \"Company X\". This field shall be unique within a catalog.", + xref: { document: "cluster", section: "6.13.5.4.2" } + }) + ), + + Datatype( + { name: "TimeWindowStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.5" } }, + + Field({ + name: "TimeWindowIndex", id: 0x0, type: "uint16", conformance: "M", quality: "X", + details: "This field shall indicate a unique index of a specific time window. This value may be used to " + + "indicate a selected time window which will be removed from the BlockContentTimeWindow attribute.", + xref: { document: "cluster", section: "6.13.5.5.1" } + }), + + Field({ + name: "DayOfWeek", id: 0x1, type: "DayOfWeekBitmap", conformance: "M", constraint: "desc", + details: "This field shall indicate a day of week.", + xref: { document: "cluster", section: "6.13.5.5.2" } + }), + + Field( + { + name: "TimePeriod", id: 0x2, type: "list", conformance: "M", constraint: "desc", + details: "This field shall indicate one or more discrete time periods.", + xref: { document: "cluster", section: "6.13.5.5.3" } + }, + Field({ name: "entry", type: "TimePeriodStruct" }) + ) + ), + + Datatype( + { name: "TimePeriodStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.6" } }, + Field({ + name: "StartHour", id: 0x0, type: "uint8", conformance: "M", constraint: "0 to 23", + details: "This field shall indicate the starting hour.", + xref: { document: "cluster", section: "6.13.5.6.1" } + }), + Field({ + name: "StartMinute", id: 0x1, type: "uint8", conformance: "M", constraint: "0 to 59", + details: "This field shall indicate the starting minute.", + xref: { document: "cluster", section: "6.13.5.6.2" } + }), + Field({ + name: "EndHour", id: 0x2, type: "uint8", conformance: "M", constraint: "0 to 23", + details: "This field shall indicate the ending hour. EndHour shall be equal to or greater than StartHour", + xref: { document: "cluster", section: "6.13.5.6.3" } + }), + + Field({ + name: "EndMinute", id: 0x3, type: "uint8", conformance: "M", constraint: "0 to 59", + details: "This field shall indicate the ending minute. If EndHour is equal to StartHour then EndMinute shall " + + "be greater than StartMinute. If the EndHour is equal to 23 and the EndMinute is equal to 59, all " + + "contents shall be blocked until 23:59:59.", + xref: { document: "cluster", section: "6.13.5.6.4" } + }) + ), + + Datatype( + { name: "StatusCodeEnum", type: "enum8", xref: { document: "cluster", section: "6.13.6.1" } }, + Field({ name: "InvalidPinCode", id: 0x2, description: "Provided PIN Code does not match the current PIN code." }), + Field({ + name: "InvalidRating", id: 0x3, + description: "Provided Rating is out of scope of the corresponding Rating list." + }), + Field({ name: "InvalidChannel", id: 0x4, description: "Provided Channel(s) is invalid." }), + Field({ name: "ChannelAlreadyExist", id: 0x5, description: "Provided Channel(s) already exists." }), + Field({ + name: "ChannelNotExist", id: 0x6, + description: "Provided Channel(s) doesn’t exist in BlockChannelList attribute." + }), + Field({ name: "UnidentifiableApplication", id: 0x7, description: "Provided Application(s) is not identified." }), + Field({ name: "ApplicationAlreadyExist", id: 0x8, description: "Provided Application(s) already exists." }), + Field({ + name: "ApplicationNotExist", id: 0x9, + description: "Provided Application(s) doesn’t exist in BlockApplicationList attribute." + }), + Field({ + name: "TimeWindowAlreadyExist", id: 0xa, + description: "Provided time Window already exists in BlockContentTimeWindow attribute." + }), + Field({ + name: "TimeWindowNotExist", id: 0xb, + description: "Provided time window doesn’t exist in BlockContentTimeWindow attribute." + }) + ) + ), + + Cluster( + { + name: "RvcRunMode", id: 0x54, type: "ModeBase", classification: "application", pics: "RVCRUNM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for the running modes of robotic vacuum cleaner devices.", + xref: { document: "cluster", section: "7.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "7.2.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + + details: "At least one entry in the SupportedModes attribute shall include the Idle mode tag in the ModeTags " + + "field." + + "\n" + + "At least one entry in the SupportedModes attribute (different from the one above) shall include the " + + "Cleaning mode tag in the ModeTags field." + + "\n" + + "The Mapping, Cleaning, and Idle mode tags are mutually exclusive and shall NOT be used together in " + + "a mode’s ModeTags.", + + xref: { document: "cluster", section: "7.2.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "7.2.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "7.2.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "7.2.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "7.2.5.1" } + }), + + Datatype( + { name: "ModeChangeStatus", type: "enum8" }, + Field({ name: "Stuck", id: 0x41, xref: { document: "cluster", section: "7.2.7.1" } }), + Field({ name: "DustBinMissing", id: 0x42, xref: { document: "cluster", section: "7.2.7.1" } }), + Field({ name: "DustBinFull", id: 0x43, xref: { document: "cluster", section: "7.2.7.1" } }), + Field({ name: "WaterTankEmpty", id: 0x44, xref: { document: "cluster", section: "7.2.7.1" } }), + Field({ name: "WaterTankMissing", id: 0x45, xref: { document: "cluster", section: "7.2.7.1" } }), + Field({ name: "WaterTankLidOpen", id: 0x46, xref: { document: "cluster", section: "7.2.7.1" } }), + Field({ name: "MopCleaningPadMissing", id: 0x47, xref: { document: "cluster", section: "7.2.7.1" } }), + Field({ name: "BatteryLow", id: 0x48, xref: { document: "cluster", section: "7.2.7.1" } }) + ), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "7.2.7.2" } }), + + Field({ + name: "Idle", id: 0x4000, + details: "The device is not performing any of the main operations of the other modes. However, auxiliary " + + "actions, such as seeking the charger or charging, may occur." + + "\n" + + "For example, the device has completed cleaning, successfully or not, on its own or due to a " + + "command, or has not been asked to clean after a restart.", + xref: { document: "cluster", section: "7.2.7.2.1" } + }), + + Field({ + name: "Cleaning", id: 0x4001, + details: "The device was asked to clean so it may be actively running, or paused due to an error, due to a " + + "pause command, or for recharging etc. If currently paused and the device can resume it will " + + "continue to clean.", + xref: { document: "cluster", section: "7.2.7.2.2" } + }), + + Field({ + name: "Mapping", id: 0x4002, + + details: "The device was asked to create a map of the space it is located in, so it may be actively running, " + + "or paused due to an error, due to a pause command, or for recharging etc. If currently paused and " + + "the device can resume, it will continue to map." + + "\n" + + "NOTE" + + "\n" + + "this mode is intended to be used so the current space can be mapped by the device if the robot has " + + "not previously done that, or if the layout has substantially changed, for an optimal subsequent " + + "cleaning experience.", + + xref: { document: "cluster", section: "7.2.7.2.3" } + }) + ) + ), + + Cluster( + { + name: "RvcCleanMode", id: 0x55, type: "ModeBase", classification: "application", pics: "RVCCLEANM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for the cleaning type of robotic vacuum cleaner devices.", + xref: { document: "cluster", section: "7.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "7.3.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + details: "At least one entry in the SupportedModes attribute shall include the Vacuum and/or the Mop mode tag " + + "in the ModeTags field list.", + xref: { document: "cluster", section: "7.3.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "7.3.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "7.3.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "7.3.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "7.3.5.1" } + }), + + Datatype( + { name: "ModeChangeStatus", type: "enum8" }, + Field({ name: "CleaningInProgress", id: 0x40, xref: { document: "cluster", section: "7.3.7.1" } }) + ), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "DeepClean", id: 0x4000, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ + name: "Vacuum", id: 0x4001, + details: "The device’s vacuuming feature is enabled in this mode.", + xref: { document: "cluster", section: "7.3.7.2.2" } + }), + Field({ + name: "Mop", id: 0x4002, + details: "The device’s mopping feature is enabled in this mode.", + xref: { document: "cluster", section: "7.3.7.2.3" } + }) + ) + ), + + Cluster( + { + name: "RvcOperationalState", id: 0x61, type: "OperationalState", classification: "application", + pics: "RVCOPSTATE", + details: "This cluster is derived from the Operational State cluster and provides an interface for monitoring " + + "the operational state of a robotic vacuum cleaner.", + xref: { document: "cluster", section: "7.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + Command({ name: "Pause", id: 0x0, xref: { document: "cluster", section: "7.4.5" } }), + Command({ name: "Stop", id: 0x1, conformance: "X", xref: { document: "cluster", section: "7.4.5" } }), + Command({ name: "Start", id: 0x2, conformance: "X", xref: { document: "cluster", section: "7.4.5" } }), + Command({ name: "Resume", id: 0x3, xref: { document: "cluster", section: "7.4.5" } }), + Command({ name: "OperationalCommandResponse", id: 0x4, xref: { document: "cluster", section: "7.4.5" } }), + + Command({ + name: "GoHome", id: 0x80, access: "O", conformance: "O", direction: "request", + response: "OperationalCommandResponse", + + details: "On receipt of this command, the device shall start seeking the charging dock, if possible in the " + + "current state of the device." + + "\n" + + "If this command is received when already in the SeekingCharger state the device shall respond with " + + "an OperationalCommandResponse command with an ErrorStateID of NoError but the command shall have no " + + "other effect." + + "\n" + + "A device that receives this command in any state which does not allow seeking the charger, such as " + + "Charging or Docked, shall respond with an OperationalCommandResponse command with an ErrorStateID " + + "of CommandInvalidInState and shall have no other effect." + + "\n" + + "Otherwise, on success:" + + "\n" + + " • The OperationalState attribute shall be set to SeekingCharger." + + "\n" + + " • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of " + + " NoError.", + + xref: { document: "cluster", section: "7.4.5.1" } + }), + + Datatype( + { + name: "OperationalStateEnum", type: "enum8", + + details: "The values defined herein are applicable to this derived cluster of Operational State only and are " + + "additional to the set of values defined in Operational State itself." + + "\n" + + "RVC Pause Compatibility defines the compatibility of the states this cluster defines with the Pause " + + "command." + + "\n" + + "### Table 13. RVC Pause Compatibility" + + "\n" + + "RVC Resume Compatibility defines the compatibility of the states this cluster defines with the " + + "Resume command." + + "\n" + + "### Table 14. RVC Resume Compatibility" + + "\n" + + "While in the Charging or Docked states, the device shall NOT attempt to resume unless it " + + "transitioned to those states while operating and can resume, such as, for example, if it is " + + "recharging while in a cleaning cycle. Else, if the operational state is Charging or Docked but " + + "there’s no operation to resume or the operation can’t be resumed, the device shall respond with an " + + "OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState but take no " + + "further action.", + + xref: { document: "cluster", section: "7.4.4.1" } + }, + + Field({ name: "Stopped", id: 0x0, conformance: "M", description: "The device is stopped" }), + Field({ name: "Running", id: 0x1, conformance: "M", description: "The device is operating" }), + Field({ name: "Paused", id: 0x2, conformance: "M", description: "The device is paused during an operation" }), + Field({ name: "Error", id: 0x3, conformance: "M", description: "The device is in an error state" }), + Field({ + name: "SeekingCharger", id: 0x40, conformance: "M", + description: "The device is en route to the charging dock" + }), + Field({ name: "Charging", id: 0x41, conformance: "M", description: "The device is charging" }), + Field({ name: "Docked", id: 0x42, conformance: "M", description: "The device is on the dock, not charging" }) + ), + + Datatype( + { + name: "ErrorStateEnum", type: "enum8", + details: "The values defined herein are applicable to this derived cluster of Operational State only and are " + + "additional to the set of values defined in Operational State itself.", + xref: { document: "cluster", section: "7.4.4.2" } + }, + + Field({ name: "NoError", id: 0x0, conformance: "M", description: "The device is not in an error state" }), + Field({ + name: "UnableToStartOrResume", id: 0x1, conformance: "M", + description: "The device is unable to start or resume operation" + }), + Field({ + name: "UnableToCompleteOperation", id: 0x2, conformance: "M", + description: "The device was unable to complete the current operation" + }), + Field({ + name: "CommandInvalidInState", id: 0x3, conformance: "M", + description: "The device cannot process the command in its current state" + }), + Field({ + name: "FailedToFindChargingDock", id: 0x40, conformance: "M", + description: "The device has failed to find or reach the charging dock" + }), + Field({ + name: "Stuck", id: 0x41, conformance: "M", + description: "The device is stuck and requires manual intervention" + }), + Field({ + name: "DustBinMissing", id: 0x42, conformance: "M", + description: "The device has detected that its dust bin is missing" + }), + Field({ + name: "DustBinFull", id: 0x43, conformance: "M", + description: "The device has detected that its dust bin is full" + }), + Field({ + name: "WaterTankEmpty", id: 0x44, conformance: "M", + description: "The device has detected that its water tank is empty" + }), + Field({ + name: "WaterTankMissing", id: 0x45, conformance: "M", + description: "The device has detected that its water tank is missing" + }), + Field({ + name: "WaterTankLidOpen", id: 0x46, conformance: "M", + description: "The device has detected that its water tank lid is open" + }), + Field({ + name: "MopCleaningPadMissing", id: 0x47, conformance: "M", + description: "The device has detected that its cleaning pad is missing" + }) + ) + ), + + Cluster( + { + name: "TemperatureControl", id: 0x56, classification: "application", pics: "TCTL", + + details: "This cluster provides an interface to the setpoint temperature on devices such as washers, " + + "refrigerators, and water heaters. The setpoint temperature is the temperature to which a device " + + "using this cluster would attempt to control to. This cluster does not provide access to the actual " + + "or physical temperature associated with any device using this cluster. Access to the physical " + + "temperature associated with a device using this cluster would be provided by other clusters as part " + + "of that devices device type definition." + + "\n" + + "The values and constraints of the attributes communicated to clients SHOULD match the controls on " + + "any physical interface on a device implementing this server. For example, the value of the Step " + + "attribute SHOULD match the incremental value by which the temperature setpoint can be changed on " + + "the physical device.", + + xref: { document: "cluster", section: "8.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.2.4" } }, + + Field({ + name: "TN", conformance: "O.a", constraint: "0", description: "TemperatureNumber", + details: "For devices that use an actual temperature value for the temperature setpoint, such as some water " + + "heaters, the feature TN shall be used. Note that this cluster provides and supports temperatures in " + + "degrees Celsius via the temperature data type.", + xref: { document: "cluster", section: "8.2.4.1" } + }), + + Field({ + name: "TL", conformance: "O.a", constraint: "1", description: "TemperatureLevel", + details: "For devices that use vendor-specific temperature levels for the temperature setpoint, such as some " + + "washers, the feature TL shall be used.", + xref: { document: "cluster", section: "8.2.4.2" } + }), + + Field({ + name: "STEP", conformance: "[TN]", constraint: "2", description: "TemperatureStep", + details: "For devices that support discrete temperature setpoints that are larger than the temperature " + + "resolution imposed via the temperature data type, the Step feature may be used.", + xref: { document: "cluster", section: "8.2.4.3" } + }) + ), + + Attribute({ + name: "TemperatureSetpoint", id: 0x0, type: "temperature", access: "R V", conformance: "TN", + constraint: "minTemperature to maxTemperature", + details: "Indicates the desired Temperature Setpoint on the device.", + xref: { document: "cluster", section: "8.2.5.1" } + }), + + Attribute({ + name: "MinTemperature", id: 0x1, type: "temperature", access: "R V", conformance: "TN", + constraint: "max maxTemperature - 1", quality: "F", + details: "Indicates the minimum temperature to which the TemperatureSetpoint attribute may be set.", + xref: { document: "cluster", section: "8.2.5.2" } + }), + + Attribute( + { + name: "MaxTemperature", id: 0x2, type: "temperature", access: "R V", conformance: "TN", + constraint: "desc", quality: "F", + details: "Indicates the maximum temperature to which the TemperatureSetpoint attribute may be set." + + "\n" + + "If the Step attribute is supported, this attribute shall be such that MaxTemperature = " + + "MinTemperature + Step * n, where n is an integer and n > 0. If the Step attribute is not supported, " + + "this attribute shall be such that MaxTemperature > MinTemperature.", + xref: { document: "cluster", section: "8.2.5.3" } + } + ), + + Attribute({ + name: "Step", id: 0x3, type: "temperature", access: "R V", conformance: "STEP", + constraint: "max maxTemperature - minTemperature", quality: "F", + + details: "Indicates the discrete value by which the TemperatureSetpoint attribute can be changed via the " + + "SetTemperature command." + + "\n" + + "For example, if the value of MinTemperature is 25.00C (2500) and the Step value is 0.50C (50), " + + "valid values of the TargetTemperature field of the SetTemperature command would be 25.50C (2550), " + + "26.00C (2600), 26.50C (2650), etc.", + + xref: { document: "cluster", section: "8.2.5.4" } + }), + + Attribute({ + name: "SelectedTemperatureLevel", id: 0x4, type: "uint8", access: "R V", conformance: "TL", + constraint: "max 31", + details: "Indicates the currently selected temperature level setting of the server. This attribute shall be " + + "the positional index of the list item in the SupportedTemperatureLevels list that represents the " + + "currently selected temperature level setting of the server.", + xref: { document: "cluster", section: "8.2.5.5" } + }), + + Attribute( + { + name: "SupportedTemperatureLevels", id: 0x5, type: "list", access: "R V", conformance: "TL", + constraint: "max 32[max 16]", + + details: "Indicates the list of supported temperature level settings that may be selected via the " + + "TargetTemperatureLevel field in the SetTemperature command. Each string is readable text that " + + "describes each temperature level setting in a way that can be easily understood by humans. For " + + "example, a washing machine can have temperature levels like \"Cold\", \"Warm\", and \"Hot\". Each string " + + "is specified by the manufacturer." + + "\n" + + "Each item in this list shall represent a unique temperature level. Each entry in this list shall " + + "have a unique value. The entries in this list shall appear in order of increasing temperature level " + + "with list item 0 being the setting with the lowest temperature level.", + + xref: { document: "cluster", section: "8.2.5.6" } + }, + + Field({ name: "entry", type: "string" }) + ), + + Command( + { + name: "SetTemperature", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "status", + xref: { document: "cluster", section: "8.2.6.1" } + }, + + Field({ + name: "TargetTemperature", id: 0x0, type: "temperature", conformance: "TN", constraint: "desc", + details: "This field shall specify the desired temperature setpoint that the server is to be set to." + + "\n" + + "The TargetTemperature shall be from MinTemperature to MaxTemperature inclusive. If the Step " + + "attribute is supported, TargetTemperature shall be such that (TargetTemperature - MinTemperature) % " + + "Step == 0.", + xref: { document: "cluster", section: "8.2.6.1.1" } + }), + + Field({ + name: "TargetTemperatureLevel", id: 0x1, type: "uint8", conformance: "TL", constraint: "desc", + details: "This field shall specify the index of the list item in the SupportedTemperatureLevels list that " + + "represents the desired temperature level setting of the server. The value of this field shall be " + + "between 0 and the length of the SupportedTemperatureLevels list -1.", + xref: { document: "cluster", section: "8.2.6.1.2" } + }) + ) + ), + + Cluster( + { + name: "DishwasherMode", id: 0x59, type: "ModeBase", classification: "application", pics: "DISHM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for dishwasher devices.", + xref: { document: "cluster", section: "8.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.3.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, conformance: "M", + details: "At least one entry in the SupportedModes attribute shall include the Normal mode tag in the " + + "ModeTags field list.", + xref: { document: "cluster", section: "8.3.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.3.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.3.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.3.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "8.3.5.1" } + }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ + name: "Normal", id: 0x4000, + details: "The normal regime of operation.", + xref: { document: "cluster", section: "8.3.7.1.1" } + }), + Field({ + name: "Heavy", id: 0x4001, + details: "Mode optimized for washing heavily-soiled dishes.", + xref: { document: "cluster", section: "8.3.7.1.2" } + }), + Field({ + name: "Light", id: 0x4002, + details: "Mode optimized for light washing.", + xref: { document: "cluster", section: "8.3.7.1.3" } + }) + ) + ), + + Cluster( + { + name: "DishwasherAlarm", id: 0x5d, type: "AlarmBase", classification: "application", + pics: "DISHALM", + details: "This cluster is a derived cluster of the Alarm Base cluster and provides the alarm definition " + + "related to dishwasher devices.", + xref: { document: "cluster", section: "8.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Datatype( + { name: "AlarmBitmap", type: "map32", xref: { document: "cluster", section: "8.4.4.1" } }, + Field({ name: "InflowError", constraint: "0", description: "Water inflow is abnormal" }), + Field({ name: "DrainError", constraint: "1", description: "Water draining is abnormal" }), + Field({ name: "DoorError", constraint: "2", description: "Door or door lock is abnormal" }), + Field({ name: "TempTooLow", constraint: "3", description: "Unable to reach normal temperature" }), + Field({ name: "TempTooHigh", constraint: "4", description: "Temperature is too high" }), + Field({ name: "WaterLevelError", constraint: "5", description: "Water level is abnormal" }) + ) + ), + + Cluster( + { + name: "LaundryWasherMode", id: 0x51, type: "ModeBase", classification: "application", pics: "LWM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for laundry washer as well as laundry dryer devices.", + xref: { document: "cluster", section: "8.5" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.5.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, conformance: "M", + details: "At least one entry in the SupportedModes attribute shall include the Normal mode tag in the " + + "ModeTags field list.", + xref: { document: "cluster", section: "8.5.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.5.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.5.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.5.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "8.5.5.1" } + }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ + name: "Normal", id: 0x4000, + details: "The normal regime of operation.", + xref: { document: "cluster", section: "8.5.7.1.1" } + }), + Field({ + name: "Delicate", id: 0x4001, + details: "Mode optimized for washing delicate garments.", + xref: { document: "cluster", section: "8.5.7.1.2" } + }), + Field({ + name: "Heavy", id: 0x4002, + details: "Mode optimized for heavy washing.", + xref: { document: "cluster", section: "8.5.7.1.3" } + }), + Field({ + name: "Whites", id: 0x4003, + details: "Mode optimized for stain removal on white fabrics.", + xref: { document: "cluster", section: "8.5.7.1.4" } + }) + ) + ), + + Cluster( + { + name: "LaundryWasherControls", id: 0x53, classification: "application", pics: "WASHERCTRL", + details: "This cluster provides a way to access options associated with the operation of a laundry washer " + + "device type.", + xref: { document: "cluster", section: "8.6" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.6.4" } }, + + Field({ + name: "SPIN", conformance: "O.a+", constraint: "0", description: "Spin", + details: "This feature indicates multiple spin speeds are supported in at least one supported mode. Note that " + + "some modes may not support multiple spin speeds even if this feature is supported.", + xref: { document: "cluster", section: "8.6.4.1" } + }), + + Field({ + name: "RINSE", conformance: "O.a+", constraint: "1", description: "Rinse", + details: "This feature indicates multiple rinse cycles are supported in at least one supported mode. Note " + + "that some modes may not support selection of the number of rinse cycles even if this feature is " + + "supported.", + xref: { document: "cluster", section: "8.6.4.2" } + }) + ), + + Attribute( + { + name: "SpinSpeeds", id: 0x0, type: "list", access: "R V", conformance: "SPIN", + constraint: "max 16[max 64]", + details: "Indicates the list of spin speeds available to the appliance in the currently selected mode. The " + + "spin speed values are determined by the manufacturer. At least one spin speed value shall be " + + "provided in the SpinSpeeds list. The list of spin speeds may change depending on the currently " + + "selected Laundry Washer mode. For example, Quick mode might have a completely different list of " + + "SpinSpeeds than Delicates mode.", + xref: { document: "cluster", section: "8.6.6.1" } + }, + + Field({ name: "entry", type: "string" }) + ), + + Attribute({ + name: "SpinSpeedCurrent", id: 0x1, type: "uint8", access: "RW VO", conformance: "SPIN", + constraint: "max 15", quality: "X", + + details: "Indicates the currently selected spin speed. It is the index into the SpinSpeeds list of the " + + "selected spin speed, as such, this attribute can be an integer between 0 and the number of entries " + + "in SpinSpeeds - 1. If a value is received that is outside of the defined constraints, a " + + "CONSTRAINT_ERROR shall be sent as the response. If a value is attempted to be written that doesn’t " + + "match a valid index (e.g. an index of 5 when the list has 4 values), a CONSTRAINT_ERROR shall be " + + "sent as the response. If null is written to this attribute, there will be no spin speed for the " + + "selected cycle. If the value is null, there will be no spin speed on the current mode.", + + xref: { document: "cluster", section: "8.6.6.2" } + }), + + Attribute({ + name: "NumberOfRinses", id: 0x2, type: "NumberOfRinsesEnum", access: "RW VO", conformance: "RINSE", + constraint: "desc", default: 1, + + details: "Indicates how many times a rinse cycle shall be performed on a device for the current mode of " + + "operation. A value of None shall indicate that no rinse cycle will be performed. This value may be " + + "set by the client to adjust the number of rinses that are performed for" + + "\n" + + "the current mode of operation. If the device is not in a compatible state to accept the provided " + + "value, an INVALID_IN_STATE error shall be sent as the response.", + + xref: { document: "cluster", section: "8.6.6.3" } + }), + + Attribute( + { + name: "SupportedRinses", id: 0x3, type: "list", access: "R V", conformance: "RINSE", + constraint: "max 4", + details: "Indicates the amount of rinses allowed for a specific mode. Each entry shall indicate a " + + "NumberOfRinsesEnum value that is possible in the selected mode on the device. The value of this " + + "attribute may change at runtime based on the currently selected mode. Each entry shall be distinct.", + xref: { document: "cluster", section: "8.6.6.4" } + }, + + Field({ name: "entry", type: "NumberOfRinsesEnum" }) + ), + + Datatype( + { + name: "NumberOfRinsesEnum", type: "enum8", + details: "The NumberOfRinsesEnum provides a representation of the number of rinses that will be performed for " + + "a selected mode. NumberOfRinsesEnum is derived from enum8. It is up to the device manufacturer to " + + "determine the mapping between the enum values and the corresponding numbers of rinses.", + xref: { document: "cluster", section: "8.6.5.1" } + }, + + Field({ + name: "None", id: 0x0, conformance: "RINSE", + description: "This laundry washer mode does not perform rinse cycles" + }), + Field({ + name: "Normal", id: 0x1, conformance: "RINSE", + description: "This laundry washer mode performs normal rinse cycles determined by the manufacturer" + }), + Field({ + name: "Extra", id: 0x2, conformance: "RINSE", + description: "This laundry washer mode performs an extra rinse cycle" + }), + Field({ + name: "Max", id: 0x3, conformance: "RINSE", + description: "This laundry washer mode performs the maximum number of rinse cycles determined by the manufacturer" + }) + ) + ), + + Cluster( + { + name: "RefrigeratorAndTemperatureControlledCabinetMode", id: 0x52, type: "ModeBase", + classification: "application", pics: "TCCM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for refrigerator and temperature controlled cabinet devices.", + xref: { document: "cluster", section: "8.7" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.7.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, conformance: "M", + details: "At least one entry in the SupportedModes attribute shall include the Auto mode tag in the ModeTags " + + "field list.", + xref: { document: "cluster", section: "8.7.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.7.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.7.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.7.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "8.7.5.1" } + }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ + name: "RapidCool", id: 0x4000, + details: "This mode reduces the temperature rapidly, typically above freezing grade.", + xref: { document: "cluster", section: "8.7.7.1.1" } + }), + Field({ + name: "RapidFreeze", id: 0x4001, + details: "This mode reduces the temperature rapidly, below freezing grade.", + xref: { document: "cluster", section: "8.7.7.1.2" } + }) + ) + ), + + Cluster( + { + name: "RefrigeratorAlarm", id: 0x57, type: "AlarmBase", classification: "application", + pics: "REFALM", + details: "This cluster is a derived cluster of Alarm Base cluster and provides the alarm definition related " + + "to refrigerator and temperature controlled cabinet devices.", + xref: { document: "cluster", section: "8.8" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.8.4" } }, + Field({ + name: "RESET", conformance: "X", constraint: "0", description: "Reset", + details: "Supports the ability to reset alarms" + }) + ), + + Command( + { name: "ModifyEnabledAlarms", id: 0x1, conformance: "X", xref: { document: "cluster", section: "8.8.7" } } + ), + + Datatype( + { name: "AlarmBitmap", type: "map32", xref: { document: "cluster", section: "8.8.5.1" } }, + Field({ + name: "DoorOpen", constraint: "0", + description: "The cabinet’s door has been open for a vendor defined amount of time." + }) + ) + ), + + Cluster( + { + name: "LaundryDryerControls", id: 0x4a, classification: "application", pics: "DRYERCTRL", + details: "This cluster provides a way to access options associated with the operation of a laundry dryer " + + "device type.", + xref: { document: "cluster", section: "8.9" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "SupportedDrynessLevels", id: 0x0, type: "list", access: "R V", conformance: "M", + constraint: "1 to 4", + details: "Indicates the list of supported dryness levels available to the appliance in the currently selected " + + "mode. The dryness level values are determined by the manufacturer. At least one dryness level value " + + "shall be provided in the SupportedDrynessLevels list. The list of dryness levels may change " + + "depending on the currently-selected Laundry Dryer mode.", + xref: { document: "cluster", section: "8.9.5.1" } + }, + + Field({ name: "entry", type: "DrynessLevelEnum" }) + ), + + Attribute({ + name: "SelectedDrynessLevel", id: 0x1, type: "DrynessLevelEnum", access: "RW VO", conformance: "M", + constraint: "desc", quality: "X", + + details: "Indicates the currently-selected dryness level and it shall be the index into the " + + "SupportedDrynessLevels list of the selected dryness level." + + "\n" + + "If an attempt is made to write this attribute with a value other than null or a value contained in " + + "SupportedDrynessLevels, a CONSTRAINT_ERROR response shall be sent as the response. If an attempt is " + + "made to write this attribute while the device is not in a state that supports modifying the dryness " + + "level, an INVALID_IN_STATE error shall be sent as the response. A value of null shall indicate that " + + "there will be no dryness level setting for the current mode.", + + xref: { document: "cluster", section: "8.9.5.2" } + }), + + Datatype( + { + name: "DrynessLevelEnum", type: "enum8", + details: "This enum provides a representation of the level of dryness that will be used while drying in a " + + "selected mode." + + "\n" + + "It is up to the device manufacturer to determine the mapping between the enum values and the " + + "corresponding temperature level.", + xref: { document: "cluster", section: "8.9.4.1" } + }, + + Field({ + name: "Low", id: 0x0, conformance: "M", + description: "Provides a low dryness level for the selected mode" + }), + Field({ + name: "Normal", id: 0x1, conformance: "M", + description: "Provides the normal level of dryness for the selected mode" + }), + Field({ + name: "Extra", id: 0x2, conformance: "M", + description: "Provides an extra dryness level for the selected mode" + }), + Field({ + name: "Max", id: 0x3, conformance: "M", + description: "Provides the max dryness level for the selected mode" + }) + ) + ), + + Cluster( + { + name: "OvenCavityOperationalState", id: 0x48, type: "OperationalState", + classification: "application", pics: "OVENOPSTATE", + details: "This cluster is derived from the Operational State cluster and provides an interface for monitoring " + + "the operational state of an oven.", + xref: { document: "cluster", section: "8.10" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + Command({ name: "Pause", id: 0x0, conformance: "X", xref: { document: "cluster", section: "8.10.5" } }), + Command({ name: "Stop", id: 0x1, xref: { document: "cluster", section: "8.10.5" } }), + Command({ name: "Start", id: 0x2, xref: { document: "cluster", section: "8.10.5" } }), + Command({ name: "Resume", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.10.5" } }), + Command({ name: "OperationalCommandResponse", id: 0x4, xref: { document: "cluster", section: "8.10.5" } }) + ), + + Cluster( + { + name: "OvenMode", id: 0x49, type: "ModeBase", classification: "application", pics: "OTCCM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for oven devices.", + xref: { document: "cluster", section: "8.11" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.11.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + details: "At least one entry in the SupportedModes attribute shall include the Bake mode tag in the ModeTags " + + "field list.", + xref: { document: "cluster", section: "8.11.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "8.11.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.11.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.11.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "8.11.5.1" } + }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ + name: "Bake", id: 0x4000, + details: "This mode sets the device into baking mode for baking food items.", + xref: { document: "cluster", section: "8.11.7.1.1" } + }), + + Field({ + name: "Convection", id: 0x4001, + details: "This mode sets the device into convection mode which creates an airflow within the device during " + + "the cooking duration.", + xref: { document: "cluster", section: "8.11.7.1.2" } + }), + + Field({ + name: "Grill", id: 0x4002, + details: "This mode sets the device into grill mode for grilling food items. This is the same as Broil for " + + "many regions.", + xref: { document: "cluster", section: "8.11.7.1.3" } + }), + + Field({ + name: "Roast", id: 0x4003, + details: "This mode sets the device into roast mode for roasting food items.", + xref: { document: "cluster", section: "8.11.7.1.4" } + }), + Field({ + name: "Clean", id: 0x4004, + details: "This mode sets the device into cleaning mode to clean the internal components of the appliance.", + xref: { document: "cluster", section: "8.11.7.1.5" } + }), + Field({ name: "ConvectionBake", id: 0x4005, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "ConvectionRoast", id: 0x4006, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ + name: "Warming", id: 0x4007, + details: "This mode sets the device into a warming mode which begins warming the cavity.", + xref: { document: "cluster", section: "8.11.7.1.8" } + }), + Field({ + name: "Proofing", id: 0x4008, + details: "This mode sets the device into proofing mode which creates an environment ready for proofing.", + xref: { document: "cluster", section: "8.11.7.1.9" } + }), + Field({ name: "Steam", id: 0x4009, xref: { document: "cluster", section: "8.11.7.1" } }) + ) + ), + + Cluster( + { + name: "MicrowaveOvenMode", id: 0x5e, type: "ModeBase", classification: "application", pics: "MWOM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for microwave oven devices.", + xref: { document: "cluster", section: "8.12" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.12.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + details: "Exactly one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags " + + "field." + + "\n" + + "The Normal and Defrost mode tags are mutually exclusive and shall NOT both be used together in a " + + "mode’s ModeTags.", + xref: { document: "cluster", section: "8.12.5.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "8.12.5" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.12.5" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.12.5" } }), + Command({ name: "ChangeToMode", id: 0x0, conformance: "X", xref: { document: "cluster", section: "8.12.6" } }), + Command({ name: "ChangeToModeResponse", id: 0x1, conformance: "X", xref: { document: "cluster", section: "8.12.6" } }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ + name: "Normal", id: 0x4000, + details: "This is the normal mode of operation for general cooking of food.", + xref: { document: "cluster", section: "8.12.7.1.1" } + }), + Field({ + name: "Defrost", id: 0x4001, + details: "This is a mode optimized for defrosting food.", + xref: { document: "cluster", section: "8.12.7.1.2" } + }) + ) + ), + + Cluster( + { + name: "MicrowaveOvenControl", id: 0x5f, classification: "application", pics: "MWOCTRL", + details: "This cluster defines the requirements for the Microwave Oven Control cluster." + + "\n" + + "This cluster has dependencies with the Operational State and Microwave Oven Mode clusters. The " + + "Operational State cluster and the Microwave Oven Mode clusters, or derivatives of those clusters " + + "shall appear on the same endpoint as this cluster.", + xref: { document: "cluster", section: "8.13" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.13.4" } }, + Field({ + name: "PWRNUM", conformance: "O.a", constraint: "0", description: "PowerAsNumber", + details: "Power is specified as a unitless number or a percentage" + }), + Field({ + name: "WATTS", conformance: "P, O.a", constraint: "1", description: "PowerInWatts", + details: "Power is specified in Watts" + }), + Field({ + name: "PWRLMTS", conformance: "[PWRNUM]", constraint: "2", description: "PowerNumberLimits", + details: "Supports the limit attributes used with the PWRNUM feature" + }) + ), + + Attribute({ + name: "CookTime", id: 0x0, type: "elapsed-s", access: "R V", conformance: "M", + constraint: "1 to maxCookTime", default: 30, + details: "Indicates the total cook time associated with the operation of the device." + + "\n" + + "This attribute shall remain unchanged during the operation of the oven unless the value is changed " + + "via a command or out-of-band action.", + xref: { document: "cluster", section: "8.13.5.1" } + }), + + Attribute({ + name: "MaxCookTime", id: 0x1, type: "elapsed-s", access: "R V", conformance: "M", + constraint: "1 to 86400", quality: "F", + details: "Indicates the maximum value to which the CookTime attribute can be set.", + xref: { document: "cluster", section: "8.13.5.2" } + }), + + Attribute({ + name: "PowerSetting", id: 0x2, type: "uint8", access: "R V", conformance: "PWRNUM", + constraint: "desc", + + details: "Indicates the power level associated with the operation of the device. If the MinPower, MaxPower, " + + "and PowerStep attributes are not supported:" + + "\n" + + " • The minimum value of this attribute shall be 10," + + "\n" + + " • The maximum value of this attribute shall be 100," + + "\n" + + " • The value shall be in even multiples of 10," + + "\n" + + " • The default value shall be 100." + + "\n" + + "If the MinPower, MaxPower, and PowerStep attributes are supported:" + + "\n" + + " • The value of this attribute shall be between MinPower and MaxPower inclusive." + + "\n" + + " • The value of this attribute shall be such that (PowerSetting - MinPower) % PowerStep == 0", + + xref: { document: "cluster", section: "8.13.5.3" } + }), + + Attribute({ + name: "MinPower", id: 0x3, type: "uint8", access: "R V", conformance: "PWRLMTS", + constraint: "1 to 99", default: 10, quality: "F", + details: "Indicates the minimum value to which the PowerSetting attribute that can be set on the server.", + xref: { document: "cluster", section: "8.13.5.4" } + }), + + Attribute({ + name: "MaxPower", id: 0x4, type: "uint8", access: "R V", conformance: "PWRLMTS", + constraint: "minPower + 1 to 100", default: 100, quality: "F", + details: "Indicates the maximum value to which the PowerSetting attribute that can be set on the server.", + xref: { document: "cluster", section: "8.13.5.5" } + }), + + Attribute({ + name: "PowerStep", id: 0x5, type: "uint8", access: "R V", conformance: "PWRLMTS", + constraint: "desc", default: 10, quality: "F", + + details: "Indicates the increment of power that can be set on the server. The value of this attribute shall " + + "be between 1 and MaxPower inclusive." + + "\n" + + "The value of this attribute shall be such that (MaxPower - MinPower) % PowerStep == 0" + + "\n" + + "For example, if MinPower is 1, MaxPower is 10, and PowerSetting can be set to any integer between " + + "MinPower and MaxPower, PowerStep would be set to 1.", + + xref: { document: "cluster", section: "8.13.5.6" } + }), + + Attribute( + { + name: "SupportedWatts", id: 0x6, type: "list", access: "R V", conformance: "P, WATTS", + constraint: "1 to 10", quality: "F", + details: "Indicates the list of power levels (in W) supported by the server.", + xref: { document: "cluster", section: "8.13.5.7" } + }, + + Field({ name: "entry", type: "uint16" }) + ), + + Attribute({ + name: "SelectedWattIndex", id: 0x7, type: "uint8", access: "R V", conformance: "P, WATTS", + constraint: "desc", + details: "Indicates the index into the list of SupportedWatts of the currently selected power setting." + + "\n" + + "The index shall be a valid index into the SupportedWatts list.", + xref: { document: "cluster", section: "8.13.5.8" } + }), + + Attribute({ + name: "WattRating", id: 0x8, type: "uint16", access: "R V", conformance: "O", quality: "F", + details: "Indicates the rating, in Watts, of the microwave power of the oven." + + "\n" + + "Supporting this attribute can assist clients in suggesting cooking settings for various foods and " + + "beverages.", + xref: { document: "cluster", section: "8.13.5.9" } + }), + + Command( + { + name: "SetCookingParameters", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "status", + details: "This command is used to set the cooking parameters associated with the operation of the device. " + + "This command supports the following fields:", + xref: { document: "cluster", section: "8.13.6.2" } + }, + + Field({ + name: "CookMode", id: 0x0, type: "uint8", conformance: "O.b+", constraint: "desc", + + details: "This field shall indicate the value to which the CurrentMode attribute of the Microwave Oven Mode " + + "cluster should be set. The value of this field shall be one from the list of SupportedModes from " + + "the Microwave Oven Mode cluster." + + "\n" + + "If this field is missing, the CurrentMode attribute shall be set to a mode having the Normal mode " + + "tag.", + + xref: { document: "cluster", section: "8.13.6.2.1" } + }), + + Field({ + name: "CookTime", id: 0x1, type: "elapsed-s", conformance: "O.b+", constraint: "1 to maxCookTime", + default: 30, + details: "This field shall indicate the CookTime associated with the operation of the device. The value of " + + "this field shall be subject to the constraints of the CookTime attribute of this cluster." + + "\n" + + "If this field is missing, the CookTime attribute shall be set to 30 seconds by the server.", + xref: { document: "cluster", section: "8.13.6.2.2" } + }), + + Field({ + name: "PowerSetting", id: 0x2, type: "uint8", conformance: "[PWRNUM].b+", + constraint: "minPower to maxPower", default: { type: "reference", name: "MaxPower" }, + + details: "This field shall indicate the PowerSetting associated with the operation of the device. The value " + + "of this field shall be subject to the constraints of the PowerSetting attribute of this cluster. If " + + "the PowerSetting field does not conform to the constraints of the PowerSetting attribute, the " + + "server shall return a CONSTRAINT_ERROR status." + + "\n" + + "If this field is missing, the PowerSetting attribute shall be set to 100 if MaxPower is not " + + "supported by the server, otherwise it shall be set to MaxPower if the MaxPower attribute is " + + "supported by the server.", + + xref: { document: "cluster", section: "8.13.6.2.3" } + }), + + Field({ + name: "WattSettingIndex", id: 0x3, type: "uint8", conformance: "[WATTS].b+", constraint: "desc", + + details: "This field shall indicate the value to which the SelectedWattIndex attribute is set. If the value " + + "of this field is greater than or equal to the length of the SupportedWatts attribute list, the " + + "server shall return a CONSTRAINT_ERROR status and the value of the SelectedWattIndex attribute " + + "shall be unchanged." + + "\n" + + "If this field is missing, the SelectedWattIndex attribute shall be set by the server to the index " + + "associated with the highest Watt setting for the selected CookMode.", + + xref: { document: "cluster", section: "8.13.6.2.4" } + }), + + Field({ + name: "StartAfterSetting", id: 0x4, type: "bool", conformance: "O", default: false, + details: "This field shall indicate whether or not oven operation shall be started when the command is " + + "received.", + xref: { document: "cluster", section: "8.13.6.2.5" } + }) + ), + + Command( + { + name: "AddMoreTime", id: 0x1, access: "O", conformance: "O", direction: "request", + response: "status", + details: "This command is used to add more time to the CookTime attribute of the server. This command " + + "supports these fields:", + xref: { document: "cluster", section: "8.13.6.3" } + }, + + Field({ + name: "TimeToAdd", id: 0x0, type: "elapsed-s", conformance: "M", constraint: "1 to maxCookTime", + details: "This field shall indicate the number of seconds to be added to the CookTime attribute.", + xref: { document: "cluster", section: "8.13.6.3.1" } + }) + ) + ), + + Cluster( + { + name: "DeviceEnergyManagement", id: 0x98, classification: "application", pics: "DEM", + + details: "This cluster allows a client to manage the power draw of a device. An example of such a client could" + + "\n" + + "be an Energy Management System (EMS) which controls an Energy Smart Appliance (ESA)." + + "\n" + + "In most deployments the EMS will be the client, and the ESA will host the Device Energy Management " + + "Cluster server." + + "\n" + + "Figure 17. Example of the how an EMS is a client of multiple ESAs Device Energy Management clusters." + + "\n" + + "This cluster is intended to be generic in nature and could apply to any electrical load or " + + "generator (e.g. a Battery Electric Storage System - BESS, solar PV inverter, EVSE, HVAC, heat pump, " + + "hot water heater, white goods appliances etc)." + + "\n" + + "It consists of the following areas which shall be supported by all devices implementing this " + + "cluster:" + + "\n" + + " • Description of ESA and its capabilities & power limits (sometimes referred to as a nameplate)" + + "\n" + + " • Current state of operation (including user opt-out, safety limitations / alarms) There are some " + + " optional capabilities that some ESAs may be able to offer:" + + "\n" + + " • Ability to control the load or generation" + + "\n" + + " • Forecast data, including when it can be flexible (i.e. modify the power or time period)" + + "\n" + + " • The ability to have their power profile adjusted by an EMS, and to provide an updated Forecast " + + " back to the EMS." + + "\n" + + "This allows the EMS to manage multiple home loads and where ESAs can be flexible, continuously " + + "optimizing the home energy to minimize cost, reduce CO2 impact, maximize self-consumption of solar " + + "PV and provide Demand Side Response (DSR) Grid services." + + "\n" + + "It is likely that the ESA may also use the Pricing Cluster to obtain incentive signals such as " + + "'grid carbon intensity', 'time of use' or 'type of use' tariffs to schedule its operation to run at " + + "the cheapest and greenest times." + + "\n" + + "Figure 18. Example of the how an HVAC may use multiple clusters" + + "\n" + + "NOTE" + + "\n" + + "Grid Services are market dependent and will use other protocols ([OpenADR] / [IEEE2030.5]) to " + + "communicate grid events to the EMS. These are outside the scope of Matter." + + "\n" + + "NOTE" + + "\n" + + "Different markets may follow different approaches, but the UK [PAS1878] and [EUCodeOfConduct] give " + + "examples of how ESAs may be mandated to support these features in the future.", + + xref: { document: "cluster", section: "9.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.2.4" } }, + + Field({ + name: "PA", conformance: "O", constraint: "0", description: "PowerAdjustment", + + details: "For Energy Smart Appliances (ESA) the definition of being 'smart' mandates that they can report " + + "their current power adjustment capability and have an EMS request a temporary adjustment. This may " + + "typically be to curtail power requirements during peak periods, but can also be used to turn on an " + + "ESA if there is excess renewable or local generation (Solar PV)." + + "\n" + + "For example, a home may have solar PV which often produces more power than the home requires, " + + "resulting in the excess power flowing into the grid. This excess power naturally fluctuates when " + + "clouds pass overhead and other loads in the home are switched on and off." + + "\n" + + "EVSE Example: An EMS may therefore be able to turn on the EVSE (if the vehicle is plugged in) and " + + "can start charging the vehicle, and periodically modify the charging power depending on PV " + + "generation and other home loads, so as to minimize import and export to the grid. An EMS may also " + + "use this feature to control the discharging (and re-charging) of the vehicle if the EVSE and " + + "vehicle support the V2X feature of the EVSE cluster of the associated EVSE device.", + + xref: { document: "cluster", section: "9.2.4.1" } + }), + + Field({ + name: "PFR", conformance: "[!PA].a, STA | PAU | FA | CON, O", constraint: "1", + description: "PowerForecastReporting", + + details: "For Energy Smart Appliances (ESA) the definition of being 'smart' implies that they can report " + + "their indicative forecast power demands or generation, to a greater or lesser extent. For some ESAs " + + "this is highly predictable (in terms of both power and time), in other appliances this is more " + + "challenging and only a basic level of forecast is possible." + + "\n" + + "Forecasts are defined from a current time, using a slot format, where the slot is akin to a " + + "relatively constant operating mode." + + "\n" + + "Washing machine example: a washing machine may have stages of a washing cycle: heating, tumbling, " + + "rinse and spin stages. At each stage, the approximate minimum and maximum power consumption may be " + + "known, as well as the duration of that stage." + + "\n" + + "In some circumstances the ESA may allow the stage to be delayed or paused (subject to safety and " + + "manufacturer’s discretion and user preferences)." + + "\n" + + "Typically, appliances with a heating element cannot have their power consumption adjusted and can " + + "only be paused or delayed." + + "\n" + + "Some ESAs may not be flexible other than a delayed cycle start (for example, once the washing cycle " + + "has been started then they run continuously until the cycle completes)." + + "\n" + + "Appliances that only support the PowerForecastReporting and not any of the adjustment features may " + + "indicate that they are not flexible in the forecast slot format." + + "\n" + + "The PowerForecastReporting and the adjustment features aim to align to the [SAREF4ENER] ontology." + + "\n" + + "Inverter driven ESAs: some inverter driven ESAs can consume or generate a variable amount of power." + + "\n" + + "For example, a single phase EVSE can be adjusted in the range of 6-32Amps in 0.6 Amp steps in EU or " + + "on a hardwired 120V supply in the range of 6-15 Amps in US." + + "\n" + + "For example, a home battery may be adjusted to charge or discharge in steps of 1W." + + "\n" + + "For example, a heat pump may be able to modulate its compressor inverter between 20-100% of its " + + "rated power." + + "\n" + + "The ESA indicates its power adjustment range and its nominal power consumption as part of its " + + "Forecast.", + + xref: { document: "cluster", section: "9.2.4.2" } + }), + + Field({ + name: "SFR", conformance: "[!PA].a", constraint: "2", description: "StateForecastReporting", + + details: "Some ESAs do not know their actual power consumption, but do know the state of operation. Like the " + + "PowerForecastingReporting feature, this uses the same slot structure mechanism to indicate a change " + + "in state vs time." + + "\n" + + "An external observing EMS may have access to real-time meter readings, and could learn the typical " + + "power consumption based on the advertised internal state of the ESA." + + "\n" + + "To enable this capability, the ESA shall report its internal operational state using an " + + "manufacturer specific value." + + "\n" + + "Once the EMS has built a model of the state vs observed power consumption, it may request a " + + "forecast adjustment for particular times of the day, encouraging the ESA to use power at " + + "alternative times.", + + xref: { document: "cluster", section: "9.2.4.3" } + }), + + Field({ + name: "STA", conformance: "O", constraint: "3", description: "StartTimeAdjustment", + + details: "ESAs which support the Start Time Adjustment feature, allow an EMS to recommend a change to the " + + "start time of the energy transfer that the ESA has previously suggested it would use." + + "\n" + + "Washing machine example: A Washing Machine may have been set to start a wash cycle at 9pm when the " + + "variable tariff normally reduces." + + "\n" + + "However, the EMS is aware that a grid event has occurred, making it cheaper to run the cycle at a " + + "later time, but the washing machine is not aware of this." + + "\n" + + "The EMS first requests the Forecast data from each of its registered ESAs. It determines that the " + + "washing machine has a power profile suggesting it will start the wash cycle at 9pm, but the EMS now " + + "knows that the grid event means it will be cheaper to delay the start until 11pm." + + "\n" + + "The EMS can then optimize the cost by asking the washing machine to delay starting the wash cycle " + + "until 11pm." + + "\n" + + "It does this by sending a StartTimeAdjustRequest to the washing machine to request delaying the " + + "start of the washing cycle.", + + xref: { document: "cluster", section: "9.2.4.4" } + }), + + Field({ + name: "PAU", conformance: "O", constraint: "4", description: "Pausable", + + details: "ESAs which support the Pausable feature, allow an EMS to recommend a pause in the middle of a" + + "\n" + + "forecast power profile that the ESA is currently using." + + "\n" + + "Washing machine example: A Washing Machine is in operation, and starting its water heating step." + + "\n" + + "However, the EMS becomes aware from the smart meter that the total home load on the grid is close " + + "to exceeding its allowed total grid load." + + "\n" + + "The EMS first requests the Forecast data from each of its registered ESAs. It determines that the " + + "washing machine has a power profile suggesting its current step in the wash cycle is using power to " + + "heat the water, but that this step can be paused." + + "\n" + + "The EMS can then reduce the grid load by asking the washing machine to pause the wash cycle for a " + + "short duration." + + "\n" + + "It does this by sending a PauseRequest to the washing machine to request pausing the current step " + + "of the forecast power usage for a period to allow other home loads to finish before resuming the " + + "washing cycle.", + + xref: { document: "cluster", section: "9.2.4.5" } + }), + + Field({ + name: "FA", conformance: "O", constraint: "5", description: "ForecastAdjustment", + + details: "ESAs which support the Forecast adjustment feature, allow an EMS to recommend a change to the " + + "start, duration and/or power level limits of the steps of the power profile that the ESA has " + + "previously suggested it would use." + + "\n" + + "Heat pump and Solar PV example: A heat pump may have the ability to heat hot water as well as " + + "heating the home. The heat pump scheduling system may have determined that the home will be " + + "unoccupied during the day, or that the indoor temperature is above the set-point and so it knows " + + "that it will not need to heat the home." + + "\n" + + "However, the hot water tank is likely to need to be reheated before the homeowner comes home in the " + + "evening. The heat pump is not aware that the property also has a solar PV inverter which is also an " + + "ESA that is communicating with the EMS." + + "\n" + + "The EMS first requests the Forecast data from each of its registered ESAs. It determines that the " + + "heat pump has a power profile suggesting it needs to heat hot water around 6pm. The solar PV " + + "inverter has forecast that it will generate 3.6kW of power during the middle of the day and into " + + "the afternoon before the sun goes down." + + "\n" + + "The EMS can then optimize the home considering other non-ESA loads and can ask the heat pump to " + + "heat the hot water around 3pm when it has forecast that excess solar power will be available." + + "\n" + + "It does this by sending a ModifyForecastRequest to the heat pump and asks the heat pump to expect " + + "to run at a lower power consumption (within the solar excess power) which requires the heat pump to " + + "run for a longer duration to achieve its required energy demand.", + + xref: { document: "cluster", section: "9.2.4.6" } + }), + + Field({ + name: "CON", conformance: "O", constraint: "6", description: "ConstraintBasedAdjustment", + + details: "ESAs which support the Constraint-Based Adjustment feature allow an EMS to inform the ESA of " + + "periods during which power usage should be modified (for example when the EMS has been made aware " + + "that the grid supplier has requested reduced energy usage due to overall peak grid demand)" + + "\n" + + "and may cause the ESA to modify the intended power profile has previously suggested it would use." + + "\n" + + "EVSE example: An EVSE scheduling system may have determined that the vehicle would be charged " + + "starting at a moderate rate at 1am, so that it has enough charge by the time it is needed later " + + "that morning." + + "\n" + + "However, the DSR service provider has informed the EMS that due to high forecast winds it is now " + + "forecast that there will be very cheap energy available from wind generation between 2am and 3am." + + "\n" + + "The EMS first requests the Forecast data from each of its registered ESAs. It determines that the " + + "EVSE has a power profile suggesting it plans to start charging the vehicle at 1am." + + "\n" + + "The EMS can then try to reduce the cost of charging the EV by informing the EVSE of the desire to " + + "increase the charging between scheduled times." + + "\n" + + "It does this by sending a RequestConstraintBasedForecast to the EVSE and asks it to run at a higher " + + "NominalPower consumption during the constraint period, which may require it to decrease its charge " + + "rate outside the constraint period to achieve its required energy demand.", + + xref: { document: "cluster", section: "9.2.4.7" } + }) + ), + + Attribute({ + name: "EsaType", id: 0x0, type: "ESATypeEnum", access: "R V", conformance: "M", default: 255, + quality: "F", + + details: "Indicates the type of ESA." + + "\n" + + "This attribute enables an EMS to understand some of the basic properties about how the energy may " + + "be consumed, generated, and stored by the ESA." + + "\n" + + "For example, the heat energy converted by a heat pump will naturally be lost through the building " + + "to the outdoor environment relatively quickly, compared to storing heat in a well-insulated hot " + + "water tank. Similarly, battery storage and EVs can store electrical energy for much longer " + + "durations." + + "\n" + + "This attribute can also help the EMS display information to a user and to make basic assumptions " + + "about typical best use of energy. For example, an EVSE may not always have an EV plugged in, so " + + "knowing the type of ESA that is being controlled can allow advanced energy management strategies.", + + xref: { document: "cluster", section: "9.2.8.1" } + }), + + Attribute( + { + name: "EsaCanGenerate", id: 0x1, type: "bool", access: "R V", conformance: "M", default: false, + quality: "F", + + details: "Indicates whether the ESA is classed as a generator or load. This allows an EMS to understand " + + "whether the power values reported by the ESA need to have their sign inverted when dealing with " + + "forecasts and adjustments." + + "\n" + + "For example, a solar PV inverter (being a generator) may produce negative values to indicate " + + "generation (since power is flowing out of the node into the home), however a display showing the " + + "power to the consumers may need to present a positive solar production value to the consumer." + + "\n" + + "For example, a home battery storage system (BESS) which needs to charge the battery and then " + + "discharge to the home loads, would be classed as a generator. These types of devices shall have " + + "this field set to true. When generating its forecast or advertising its PowerAdjustmentCapability, " + + "the power values shall be negative to indicate discharging to the loads in the home, and positive " + + "to indicate when it is charging its battery." + + "\n" + + "GRID meter = Σ LoadPowers + Σ GeneratorPowers" + + "\n" + + "Example:", + + xref: { document: "cluster", section: "9.2.8.2" } + } + ), + + Attribute({ + name: "EsaState", id: 0x2, type: "ESAStateEnum", access: "R V", conformance: "M", + constraint: "desc", default: 0, + + details: "Indicates the current state of the ESA." + + "\n" + + "If the ESA is in the Offline or Fault state it cannot be controlled by an EMS, and may not be able " + + "to report its Forecast information. An EMS may subscribe to the ESAState to get notified about " + + "changes in operational state." + + "\n" + + "The ESA may have a local user interface to allow a service technician to put the ESA into Offline " + + "mode, for example to avoid the EMS accidentally starting or stopping the appliance when it is being " + + "serviced or tested.", + + xref: { document: "cluster", section: "9.2.8.3" } + }), + + Attribute({ + name: "AbsMinPower", id: 0x3, type: "power-mW", access: "R V", conformance: "M", default: 0, + + details: "Indicates the minimum electrical power that the ESA can consume when switched on. This does not " + + "include when in power save or standby modes." + + "\n" + + "NOTE" + + "\n" + + "For Generator ESAs that can discharge an internal battery (such as a battery storage inverter) to " + + "loads in the home, the AbsMinPower will be a negative number representing the maximum power that " + + "the ESA can discharge its internal battery.", + + xref: { document: "cluster", section: "9.2.8.4" } + }), + + Attribute({ + name: "AbsMaxPower", id: 0x4, type: "power-mW", access: "R V", conformance: "M", + constraint: "min absMinPower", default: 0, + + details: "Indicates the maximum electrical power that the ESA can consume when switched on." + + "\n" + + "Note that for Generator ESAs that can charge a battery by importing power into the node (such as a " + + "battery storage inverter), the AbsMaxPower will be a positive number representing the maximum power " + + "at which the ESA can charge its internal battery." + + "\n" + + "For example, a battery storage inverter that can charge its battery at a maximum power of 2000W and " + + "can discharge the battery at a maximum power of 3000W, would have a AbsMinPower: -3000, " + + "AbsMaxPower: 2000W.", + + xref: { document: "cluster", section: "9.2.8.5" } + }), + + Attribute({ + name: "PowerAdjustmentCapability", id: 0x5, type: "PowerAdjustCapabilityStruct", access: "R V", + conformance: "PA", default: null, quality: "X Q", + + details: "Indicates how the ESA can be adjusted at the current time, and the state of any active adjustment." + + "\n" + + "A null value indicates that no power adjustment is currently possible, and nor is any adjustment " + + "currently active." + + "\n" + + "This attribute SHOULD be updated periodically by ESAs to reflect any changes in internal state, for " + + "example temperature or stored energy, which would affect the power or duration limits." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds on changes, or" + + "\n" + + " • When it changes from null to any other value and vice versa.", + + xref: { document: "cluster", section: "9.2.8.6" } + }), + + Attribute({ + name: "Forecast", id: 0x6, type: "ForecastStruct", access: "R V", conformance: "PFR | SFR", + default: null, quality: "X Q", + + details: "This attribute allows an ESA to share its intended forecast with a client (such as an Energy " + + "Management System)." + + "\n" + + "A null value indicates that there is no forecast currently available (for example, a program has " + + "not yet been selected by the user)." + + "\n" + + "A server may reset this value attribute to null on a reboot, and it does not need to persist any " + + "previous forecasts." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds on changes, or" + + "\n" + + " • When it changes from null to any other value and vice versa, or" + + "\n" + + " • As a result of a command which causes the forecast to be updated, or" + + "\n" + + " • As a result of a change in the opt-out status which in turn may cause the ESA to recalculate " + + " its forecast.", + + xref: { document: "cluster", section: "9.2.8.7" } + }), + + Attribute({ + name: "OptOutState", id: 0x7, type: "OptOutStateEnum", access: "R V", + conformance: "PA | STA | PAU | FA | CON", constraint: "desc", default: 0, + + details: "Indicates the current Opt-Out state of the ESA. The ESA may have a local user interface to allow " + + "the user to control this OptOutState. An EMS may subscribe to the OptOutState to get notified about " + + "changes in operational state." + + "\n" + + "If the ESA is in the LocalOptOut or OptOut states, so it cannot be controlled by an EMS for local " + + "optimization reasons, it shall reject any commands which have the AdjustmentCauseEnum value " + + "LocalOptimization. If the ESA is in the GridOptOut or OptOut states, so it cannot be controlled by " + + "an EMS for grid optimization reasons, it shall reject any commands which have the " + + "AdjustmentCauseEnum value GridOptimization." + + "\n" + + "If the user changes the Opt-Out state of the ESA which is currently operating with a Forecast that " + + "is due to a previous StartTimeAdjustRequest, ModifyForecastRequest or " + + "RequestConstraintBasedForecast command that would now not be permitted due to the new Opt-out state" + + "\n" + + "attribute ForecastUpdateReason field currently contains a reason which is now opted out), the ESA " + + "shall behave as if it had received a CancelRequest command." + + "\n" + + "If the user changes the Opt-Out state of the ESA which currently has the ESAStateEnum with value " + + "Paused due to a previous PauseRequest command that would now not be permitted due to the new " + + "Opt-out state, and the ESA supports the PFR or SFR features (i.e. the Forecast attribute " + + "ForecastUpdateReason field currently contains a reason which is now opted out), the ESA shall " + + "behave as if it had received a ResumeRequest command." + + "\n" + + "If the user changes the Opt-Out state of the ESA which currently has the ESAStateEnum with value " + + "PowerAdjustActive due to a previous PowerAdjustRequest command that would now not be permitted due " + + "to the new Opt-out state (i.e. the Forecast attribute ForecastUpdateReason field currently contains " + + "a reason which is now opted out), the ESA shall behave as if it had received a " + + "CancelPowerAdjustRequest command." + + "\n" + + "If the ESA is in the LocalOptOut, GridOptOut, or NoOptOut states, the device is still permitted to " + + "optimize its own energy usage, for example, using tariff information it may obtain.", + + xref: { document: "cluster", section: "9.2.8.8" } + }), + + Event({ + name: "PowerAdjustStart", id: 0x0, access: "V", conformance: "PA", priority: "info", + details: "This event shall be generated when the Power Adjustment session is started.", + xref: { document: "cluster", section: "9.2.10.1" } + }), + + Event( + { + name: "PowerAdjustEnd", id: 0x1, access: "V", conformance: "PA", priority: "info", + details: "This event shall be generated when the Power Adjustment session ends.", + xref: { document: "cluster", section: "9.2.10.2" } + }, + Field({ + name: "Cause", id: 0x0, type: "CauseEnum", conformance: "M", default: 0, + details: "This field shall indicate the reason why the power adjustment session ended.", + xref: { document: "cluster", section: "9.2.10.2.1" } + }), + + Field({ + name: "Duration", id: 0x1, type: "elapsed-s", conformance: "M", + details: "This field shall indicate the number of seconds that the power adjustment session lasted before " + + "ending.", + xref: { document: "cluster", section: "9.2.10.2.2" } + }), + + Field({ + name: "EnergyUse", id: 0x2, type: "energy-mWh", conformance: "M", + details: "This field shall indicate the approximate energy used by the ESA during the session." + + "\n" + + "For example, if the ESA was on and was adjusted to be switched off, then this shall be 0 mWh. If " + + "this was a battery inverter that was requested to discharge it would have a negative EnergyUse " + + "value. If this was a normal load that was turned on, then it will have positive value.", + xref: { document: "cluster", section: "9.2.10.2.3" } + }) + ), + + Event({ + name: "Paused", id: 0x2, access: "V", conformance: "PAU", priority: "info", + details: "This event shall be generated when the ESA enters the Paused state. There is no data for this event.", + xref: { document: "cluster", section: "9.2.10.3" } + }), + + Event( + { + name: "Resumed", id: 0x3, access: "V", conformance: "PAU", priority: "info", + details: "This event shall be generated when the ESA leaves the Paused state and resumes operation.", + xref: { document: "cluster", section: "9.2.10.4" } + }, + Field({ + name: "Cause", id: 0x0, type: "CauseEnum", conformance: "M", default: 0, + details: "This field shall indicate the reason why the pause ended.", + xref: { document: "cluster", section: "9.2.10.4.1" } + }) + ), + + Command( + { + name: "PowerAdjustRequest", id: 0x0, access: "O", conformance: "PA", direction: "request", + response: "status", + details: "Allows a client to request an adjustment in the power consumption of an ESA for a specified " + + "duration.", + xref: { document: "cluster", section: "9.2.9.1" } + }, + + Field({ + name: "Power", id: 0x0, type: "power-mW", conformance: "M", constraint: "desc", + details: "This field shall indicate the power that the ESA shall use during the adjustment period." + + "\n" + + "This value shall be between the MinPower and MaxPower fields of the PowerAdjustStruct in the " + + "PowerAdjustmentCapability attribute.", + xref: { document: "cluster", section: "9.2.9.1.1" } + }), + + Field({ + name: "Duration", id: 0x1, type: "elapsed-s", conformance: "M", constraint: "desc", + details: "This field shall indicate the duration that the ESA shall maintain the requested power for." + + "\n" + + "This value shall be between the MinDuration and MaxDuration fields of the PowerAdjustStruct in the " + + "PowerAdjustmentCapability attribute.", + xref: { document: "cluster", section: "9.2.9.1.2" } + }), + + Field({ + name: "Cause", id: 0x2, type: "AdjustmentCauseEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the cause of the request from the EMS.", + xref: { document: "cluster", section: "9.2.9.1.3" } + }) + ), + + Command({ + name: "CancelPowerAdjustRequest", id: 0x1, access: "O", conformance: "PA", direction: "request", + response: "status", + details: "Allows a client to cancel an ongoing PowerAdjustmentRequest operation.", + xref: { document: "cluster", section: "9.2.9.2" } + }), + + Command( + { + name: "StartTimeAdjustRequest", id: 0x2, access: "O", conformance: "STA", direction: "request", + response: "status", + details: "Allows a client to adjust the start time of a Forecast sequence that has not yet started operation " + + "(i.e. where the current Forecast StartTime is in the future).", + xref: { document: "cluster", section: "9.2.9.3" } + }, + + Field({ + name: "RequestedStartTime", id: 0x0, type: "epoch-s", conformance: "M", constraint: "desc", + + details: "This field shall indicate the requested start time, in UTC, that the client would like the " + + "appliance to shift its Forecast to. This value MUST be in the future." + + "\n" + + "A client can estimate the entire Forecast sequence duration by computing the EndTime - StartTime " + + "fields from the Forecast attribute, and therefore avoid scheduling the start time too late." + + "\n" + + "This value shall be after the EarliestStartTime in the Forecast attribute. The new EndTime, that " + + "can be computed from the RequestedStartTime and the Forecast sequence duration, shall be before the " + + "LatestEndTime.", + + xref: { document: "cluster", section: "9.2.9.3.1" } + }), + + Field({ + name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", + details: "This field shall indicate the cause of the request from the EMS.", + xref: { document: "cluster", section: "9.2.9.3.2" } + }) + ), + + Command( + { + name: "PauseRequest", id: 0x3, access: "O", conformance: "PAU", direction: "request", + response: "status", + details: "Allows a client to temporarily pause an operation and reduce the ESAs energy demand.", + xref: { document: "cluster", section: "9.2.9.4" } + }, + + Field({ + name: "Duration", id: 0x0, type: "elapsed-s", conformance: "M", constraint: "desc", + details: "This field shall indicate the duration that the ESA shall be paused for. This value shall be " + + "between the MinPauseDuration and MaxPauseDuration indicated in the ActiveSlotNumber index in the " + + "Slots list in the Forecast.", + xref: { document: "cluster", section: "9.2.9.4.1" } + }), + + Field({ + name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", + details: "This field shall indicate the cause of the request from the EMS.", + xref: { document: "cluster", section: "9.2.9.4.2" } + }) + ), + + Command({ + name: "ResumeRequest", id: 0x4, access: "O", conformance: "PAU", direction: "request", + response: "status", + details: "Allows a client to cancel the PauseRequest command and enable earlier resumption of operation.", + xref: { document: "cluster", section: "9.2.9.5" } + }), + + Command( + { + name: "ModifyForecastRequest", id: 0x5, access: "O", conformance: "FA", direction: "request", + response: "status", + details: "Allows a client to modify a Forecast within the limits allowed by the ESA.", + xref: { document: "cluster", section: "9.2.9.6" } + }, + + Field({ + name: "ForecastId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall indicate the ForecastID that is to be modified.", + xref: { document: "cluster", section: "9.2.9.6.1" } + }), + + Field( + { + name: "SlotAdjustments", id: 0x1, type: "list", conformance: "M", constraint: "max 10", + details: "This field shall contain a list of SlotAdjustment parameters that should be modified in the " + + "corresponding Forecast with matching ForecastID.", + xref: { document: "cluster", section: "9.2.9.6.2" } + }, + + Field({ name: "entry", type: "SlotAdjustmentStruct" }) + ), + + Field({ + name: "Cause", id: 0x2, type: "AdjustmentCauseEnum", conformance: "M", + details: "This field shall indicate the cause of the request from the EMS.", + xref: { document: "cluster", section: "9.2.9.6.3" } + }) + ), + + Command( + { + name: "RequestConstraintBasedForecast", id: 0x6, access: "O", conformance: "CON", + direction: "request", response: "status", + details: "Allows a client to ask the ESA to recompute its Forecast based on power and time constraints.", + xref: { document: "cluster", section: "9.2.9.7" } + }, + + Field( + { + name: "Constraints", id: 0x0, type: "list", conformance: "M", constraint: "max 10", + + details: "This field shall indicate the series of turn up or turn down power requests that the ESA is being " + + "asked to constrain its operation within. These requests shall be in the future, shall be in " + + "chronological order, starting with the earliest start time, and shall NOT overlap in time." + + "\n" + + "For example, a grid event which requires devices to reduce power (turn down) between 4pm and 6pm " + + "and due to excess power on the grid overnight, may request ESAs to increase their power demand " + + "(turn up) between midnight and 6am." + + "\n" + + "If this ESA supports PFR this would have 2 entries in the list as follows:" + + "\n" + + "If this ESA supports SFR where it does not know the actual power, but has an understanding of the " + + "functions that use more energy, it could be requested to use more or less energy using the LoadCon" + + "\n" + + "trol field as follows:", + + xref: { document: "cluster", section: "9.2.9.7.1" } + }, + + Field({ name: "entry", type: "ConstraintsStruct" }) + ), + + Field({ + name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", + details: "This field shall indicate the cause of the request from the EMS.", + xref: { document: "cluster", section: "9.2.9.7.2" } + }) + ), + + Command({ + name: "CancelRequest", id: 0x7, access: "O", conformance: "STA | FA | CON", direction: "request", + response: "status", + details: "Allows a client to request cancellation of a previous adjustment request in a " + + "StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command.", + xref: { document: "cluster", section: "9.2.9.8" } + }), + + Datatype( + { name: "CostTypeEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.1" } }, + Field({ + name: "Financial", id: 0x0, conformance: "M", description: "Financial cost", + details: "This value shall indicate that the cost is related to the financial cost to provide the energy.", + xref: { document: "cluster", section: "9.2.7.1.1" } + }), + Field({ + name: "GhgEmissions", id: 0x1, conformance: "M", description: "Grid CO2e grams cost", + details: "This value shall indicate that the cost is related to greenhouse gas emissions (in grams of CO2e).", + xref: { document: "cluster", section: "9.2.7.1.2" } + }), + + Field({ + name: "Comfort", id: 0x2, conformance: "M", description: "Consumer comfort impact cost", + details: "This value shall indicate that the cost is related to some abstract sense of comfort expressed by " + + "the consumer; a higher value indicates more discomfort. For example, a consumer may be more " + + "comfortable knowing that their EV is charged earlier in the day in case there is a sudden need to " + + "depart and drive to the hospital. Or the consumer may feel inconvenienced by the fact that they " + + "need to wait for the washing machine to finish its load so that they can use it again.", + xref: { document: "cluster", section: "9.2.7.1.3" } + }), + + Field({ + name: "Temperature", id: 0x3, conformance: "M", description: "Temperature impact cost", + details: "This value shall indicate that the cost is related to the temperature of the home or water being at " + + "its setpoint. Some consumers may be more sensitive to being too hot or too cold." + + "\n" + + "This is expressed in degrees Celsius.", + xref: { document: "cluster", section: "9.2.7.1.4" } + }) + ), + + Datatype( + { name: "ESATypeEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.2" } }, + Field({ name: "Evse", id: 0x0, conformance: "O", description: "EV Supply Equipment" }), + Field({ name: "SpaceHeating", id: 0x1, conformance: "O", description: "Space heating appliance" }), + Field({ name: "WaterHeating", id: 0x2, conformance: "O", description: "Water heating appliance" }), + Field({ name: "SpaceCooling", id: 0x3, conformance: "O", description: "Space cooling appliance" }), + Field({ + name: "SpaceHeatingCooling", id: 0x4, conformance: "O", + description: "Space heating and cooling appliance" + }), + Field({ name: "BatteryStorage", id: 0x5, conformance: "O", description: "Battery Electric Storage System" }), + Field({ name: "SolarPv", id: 0x6, conformance: "O", description: "Solar PV inverter" }), + Field({ name: "FridgeFreezer", id: 0x7, conformance: "O", description: "Fridge / Freezer" }), + Field({ name: "WashingMachine", id: 0x8, conformance: "O", description: "Washing Machine" }), + Field({ name: "Dishwasher", id: 0x9, conformance: "O", description: "Dishwasher" }), + Field({ name: "Cooking", id: 0xa, conformance: "O", description: "Cooking appliance" }), + Field({ name: "HomeWaterPump", id: 0xb, conformance: "O", description: "Home water pump (e.g. drinking well)" }), + Field({ name: "IrrigationWaterPump", id: 0xc, conformance: "O", description: "Irrigation water pump" }), + Field({ name: "PoolPump", id: 0xd, conformance: "O", description: "Pool pump" }), + Field({ name: "Other", id: 0xff, conformance: "O", description: "Other appliance type" }) + ), + + Datatype( + { name: "ESAStateEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.3" } }, + Field({ + name: "Offline", id: 0x0, conformance: "M", + description: "The ESA is not available to the EMS (e.g. start- up, maintenance mode)" + }), + Field({ + name: "Online", id: 0x1, conformance: "M", + description: "The ESA is working normally and can be controlled by the EMS" + }), + Field({ + name: "Fault", id: 0x2, conformance: "M", + description: "The ESA has developed a fault and cannot provide service" + }), + Field({ + name: "PowerAdjustActive", id: 0x3, conformance: "PA", + description: "The ESA is in the middle of a power adjustment event" + }), + Field({ + name: "Paused", id: 0x4, conformance: "PAU", + description: "The ESA is currently paused by a client using the PauseRequest command" + }) + ), + + Datatype( + { name: "OptOutStateEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.4" } }, + Field({ + name: "NoOptOut", id: 0x0, conformance: "M", + description: "The user has not opted out of either local or grid optimizations" + }), + Field({ + name: "LocalOptOut", id: 0x1, conformance: "M", + description: "The user has opted out of local EMS optimizations only" + }), + Field({ + name: "GridOptOut", id: 0x2, conformance: "M", + description: "The user has opted out of grid EMS optimizations only" + }), + Field({ + name: "OptOut", id: 0x3, conformance: "M", + description: "The user has opted out of all external optimizations" + }) + ), + + Datatype( + { name: "CauseEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.5" } }, + Field({ + name: "NormalCompletion", id: 0x0, conformance: "M", + description: "The ESA completed the power adjustment as requested" + }), + Field({ name: "Offline", id: 0x1, conformance: "M", description: "The ESA was set to offline" }), + Field({ + name: "Fault", id: 0x2, conformance: "M", + description: "The ESA has developed a fault could not complete the adjustment" + }), + Field({ + name: "UserOptOut", id: 0x3, conformance: "M", + description: "The user has disabled the ESA’s flexibility capability" + }), + Field({ name: "Cancelled", id: 0x4, conformance: "M", description: "The adjustment was cancelled by a client" }) + ), + + Datatype( + { name: "AdjustmentCauseEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.6" } }, + Field({ + name: "LocalOptimization", id: 0x0, conformance: "M", + description: "The adjustment is to optimize the local energy usage" + }), + Field({ + name: "GridOptimization", id: 0x1, conformance: "M", + description: "The adjustment is to optimize the grid energy usage" + }) + ), + + Datatype( + { name: "ForecastUpdateReasonEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.7" } }, + Field({ + name: "InternalOptimization", id: 0x0, conformance: "M", + description: "The update was due to internal ESA device optimization" + }), + Field({ + name: "LocalOptimization", id: 0x1, conformance: "M", + description: "The update was due to local EMS optimization" + }), + Field({ + name: "GridOptimization", id: 0x2, conformance: "M", + description: "The update was due to grid optimization" + }) + ), + + Datatype( + { name: "PowerAdjustReasonEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.8" } }, + Field({ name: "NoAdjustment", id: 0x0, conformance: "M", description: "There is no Power Adjustment active" }), + Field({ + name: "LocalOptimizationAdjustment", id: 0x1, conformance: "M", + description: "There is PowerAdjustment active due to local EMS optimization" + }), + Field({ + name: "GridOptimizationAdjustment", id: 0x2, conformance: "M", + description: "There is PowerAdjustment active due to local EMS optimization" + }) + ), + + Datatype( + { + name: "CostStruct", type: "struct", + details: "This indicates a generic mechanism for expressing cost to run an appliance, in terms of financial, " + + "GHG emissions, comfort value etc.", + xref: { document: "cluster", section: "9.2.7.9" } + }, + + Field({ + name: "CostType", id: 0x0, type: "CostTypeEnum", conformance: "M", default: 0, + details: "This field shall indicate the type of cost being represented (see CostTypeEnum).", + xref: { document: "cluster", section: "9.2.7.9.1" } + }), + + Field({ + name: "Value", id: 0x1, type: "int32", conformance: "M", default: 0, + details: "This field shall indicate the value of the cost. This may be negative (indicating that it is not a " + + "cost, but a free benefit)." + + "\n" + + "For example, if the Value was -302 and DecimalPoints was 2, then this would represent a benefit of " + + "3.02.", + xref: { document: "cluster", section: "9.2.7.9.2" } + }), + + Field({ + name: "DecimalPoints", id: 0x2, type: "uint8", conformance: "M", default: 0, + details: "This field shall indicate the number of digits to the right of the decimal point in the Value " + + "field. For example, if the Value was 102 and DecimalPoints was 2, then this would represent a cost " + + "of 1.02.", + xref: { document: "cluster", section: "9.2.7.9.3" } + }), + + Field({ + name: "Currency", id: 0x3, type: "uint16", conformance: "O", constraint: "max 999", default: 0, + details: "Indicates the currency for the value in the Value field. The value of the currency field shall " + + "match the values defined by [ISO 4217]." + + "\n" + + "This is an optional field. It shall be included if CostType is Financial.", + xref: { document: "cluster", section: "9.2.7.9.4" } + }) + ), + + Datatype( + { name: "PowerAdjustStruct", type: "struct", xref: { document: "cluster", section: "9.2.7.10" } }, + + Field({ + name: "MinPower", id: 0x0, type: "power-mW", conformance: "M", default: 0, + details: "This field shall indicate the minimum power that the ESA can have its power adjusted to." + + "\n" + + "Note that this is a signed value. Negative values indicate power flows out of the node (e.g. " + + "discharging a battery).", + xref: { document: "cluster", section: "9.2.7.10.1" } + }), + + Field({ + name: "MaxPower", id: 0x1, type: "power-mW", conformance: "M", constraint: "min minPower", + default: 0, + + details: "This field shall indicate the maximum power that the ESA can have its power adjusted to." + + "\n" + + "Note that this is a signed value. Negative values indicate power flows out of the node (e.g. " + + "discharging a battery)." + + "\n" + + "For example, if the charging current of an EVSE can be adjusted within the range of 6A to 32A on a " + + "230V supply, then the power adjustment range is between 1380W and 7360W. Here the MinPower would be " + + "1380W, and MaxPower would be 7360W." + + "\n" + + "For example, if a battery storage inverter can discharge between 0 to 3000W towards a load, then " + + "power is flowing out of the node and is therefore negative. Its MinPower would be -3000W and its " + + "MaxPower would be 0W." + + "\n" + + "In another example, if a battery storage inverter can charge its internal battery, between 0W and " + + "2000W. Here power is flowing into the node when charging. As such the MinPower becomes 0W and " + + "MaxPower becomes 2000W.", + + xref: { document: "cluster", section: "9.2.7.10.2" } + }), + + Field({ + name: "MinDuration", id: 0x2, type: "elapsed-s", conformance: "M", default: 0, + details: "This field shall indicate the minimum duration, in seconds, that a controller may invoke an ESA " + + "power adjustment. Manufacturers may use this to as an anti-cycling capability to avoid controllers " + + "from rapidly making power adjustments.", + xref: { document: "cluster", section: "9.2.7.10.3" } + }), + + Field({ + name: "MaxDuration", id: 0x3, type: "elapsed-s", conformance: "M", constraint: "min minDuration", + details: "This field shall indicate the maximum duration, in seconds, that a controller may invoke an ESA " + + "power adjustment. Manufacturers may use this to protect the user experience, to avoid over heating " + + "of the ESA, ensuring that there is sufficient headroom to use or store energy in the ESA or for any " + + "other reason.", + xref: { document: "cluster", section: "9.2.7.10.4" } + }) + ), + + Datatype( + { name: "PowerAdjustCapabilityStruct", type: "struct", xref: { document: "cluster", section: "9.2.7.11" } }, + + Field( + { + name: "PowerAdjustCapability", id: 0x0, type: "list", conformance: "M", constraint: "max 8", + default: null, quality: "X", + + details: "This field shall indicate how the ESA can be adjusted at the current time." + + "\n" + + "For example, a battery storage inverter may need to regulate its internal temperature, or the " + + "charging rate of the battery may be limited due to cold temperatures, or a change in the state of " + + "charge of the battery may mean that the maximum charging or discharging rate is limited." + + "\n" + + "An empty list shall indicate that no power adjustment is currently possible." + + "\n" + + "Multiple entries in the list allow indicating that permutations of scenarios may be possible." + + "\n" + + "For example, a 10kWh battery could be at 80% state of charge. If charging at 2kW, then it would be " + + "full in 1 hour. However, it could be discharged at 2kW for 4 hours." + + "\n" + + "In this example the list of PowerAdjustStructs allows multiple scenarios to be offered as follows:", + + xref: { document: "cluster", section: "9.2.7.12" } + }, + + Field({ name: "entry", type: "PowerAdjustStruct" }) + ), + + Field({ name: "Cause", id: 0x1, type: "PowerAdjustReasonEnum", conformance: "M", default: 0 }) + ), + + Datatype( + { + name: "ForecastStruct", type: "struct", + + details: "This indicates a list of 'slots' describing the overall timing of the ESA’s planned energy and " + + "power use, with different power and energy demands per slot. For example, slots might be used to " + + "describe the distinct stages of a washing machine cycle." + + "\n" + + "Where an ESA does not know the actual power and energy use of the system, it may support the SFR" + + "\n" + + "feature and instead report its internal state.", + + xref: { document: "cluster", section: "9.2.7.13" } + }, + + Field({ + name: "ForecastId", id: 0x0, type: "uint32", conformance: "M", default: 0, + + details: "This field shall indicate the sequence number for the current forecast. If the ESA updates a " + + "forecast, it shall monotonically increase this value." + + "\n" + + "The ESA does not need to persist this value across reboots, since the EMS SHOULD be able to detect " + + "that any previous subscriptions are lost if a device reboots. The loss of a subscription and " + + "subsequent re-subscription allows the EMS to learn about any new forecasts." + + "\n" + + "The value of ForecastID is allowed to wrap.", + + xref: { document: "cluster", section: "9.2.7.13.1" } + }), + + Field({ + name: "ActiveSlotNumber", id: 0x1, type: "uint16", conformance: "M", default: 0, quality: "X", + details: "This field shall indicate which element of the Slots list is currently active in the Forecast " + + "sequence. A null value indicates that the sequence has not yet started.", + xref: { document: "cluster", section: "9.2.7.13.2" } + }), + + Field({ + name: "StartTime", id: 0x2, type: "epoch-s", conformance: "M", + details: "This field shall indicate the planned start time, in UTC, for the entire Forecast.", + xref: { document: "cluster", section: "9.2.7.13.3" } + }), + Field({ + name: "EndTime", id: 0x3, type: "epoch-s", conformance: "M", + details: "This field shall indicate the planned end time, in UTC, for the entire Forecast.", + xref: { document: "cluster", section: "9.2.7.13.4" } + }), + + Field({ + name: "EarliestStartTime", id: 0x4, type: "epoch-s", conformance: "STA", quality: "X", + details: "This field shall indicate the earliest start time, in UTC, that the entire Forecast can be shifted " + + "to. A null value indicates that it can be started immediately.", + xref: { document: "cluster", section: "9.2.7.13.5" } + }), + + Field({ + name: "LatestEndTime", id: 0x5, type: "epoch-s", conformance: "STA", + details: "This field shall indicate the latest end time, in UTC, for the entire Forecast." + + "\n" + + "e.g. for an EVSE charging session, this may indicate the departure time for the vehicle, by which " + + "time the charging session must end.", + xref: { document: "cluster", section: "9.2.7.13.6" } + }), + + Field({ + name: "IsPausable", id: 0x6, type: "bool", conformance: "M", + details: "This field shall indicate that some part of the Forecast can be paused. It aims to allow a client " + + "to read this flag and if it is false, then none of the slots contain SlotIsPausable set to true. " + + "This can save a client from having to check each slot in the list.", + xref: { document: "cluster", section: "9.2.7.13.7" } + }), + + Field( + { + name: "Slots", id: 0x7, type: "list", conformance: "M", constraint: "max 10", + details: "This field shall contain a list of SlotStructs." + + "\n" + + "It shall contain at least 1 entry, and a maximum of 10.", + xref: { document: "cluster", section: "9.2.7.13.8" } + }, + + Field({ name: "entry", type: "SlotStruct" }) + ), + + Field({ + name: "ForecastUpdateReason", id: 0x8, type: "ForecastUpdateReasonEnum", conformance: "M", + details: "This field shall contain the reason the current Forecast was generated.", + xref: { document: "cluster", section: "9.2.7.13.9" } + }) + ), + + Datatype( + { + name: "SlotStruct", type: "struct", + details: "This indicates a specific stage of an ESA’s operation.", + xref: { document: "cluster", section: "9.2.7.14" } + }, + + Field({ + name: "MinDuration", id: 0x0, type: "elapsed-s", conformance: "M", + details: "This field shall indicate the minimum time (in seconds) that the appliance expects to be in this " + + "slot for.", + xref: { document: "cluster", section: "9.2.7.14.1" } + }), + + Field({ + name: "MaxDuration", id: 0x1, type: "elapsed-s", conformance: "M", + details: "This field shall indicate the maximum time (in seconds) that the appliance expects to be in this " + + "slot for.", + xref: { document: "cluster", section: "9.2.7.14.2" } + }), + + Field({ + name: "DefaultDuration", id: 0x2, type: "elapsed-s", conformance: "M", + details: "This field shall indicate the expected time (in seconds) that the appliance expects to be in this " + + "slot for.", + xref: { document: "cluster", section: "9.2.7.14.3" } + }), + + Field({ + name: "ElapsedSlotTime", id: 0x3, type: "elapsed-s", conformance: "M", + + details: "This field shall indicate the time (in seconds) that has already elapsed whilst in this slot. If " + + "the slot has not yet been started, then it shall be 0. Once the slot has been completed, then this " + + "reflects how much time was spent in this slot." + + "\n" + + "When subscribed to, a change in this field value shall NOT cause the Forecast attribute to be " + + "updated since this value may change every 1 second." + + "\n" + + "When the Forecast attribute is read, then this value shall be the most recent value.", + + xref: { document: "cluster", section: "9.2.7.14.4" } + }), + + Field({ + name: "RemainingSlotTime", id: 0x4, type: "elapsed-s", conformance: "M", + + details: "This field shall indicate the time (in seconds) that is estimated to be remaining." + + "\n" + + "Note that it may not align to the DefaultDuration - ElapsedSlotTime since an appliance may have " + + "revised its planned operation based on conditions." + + "\n" + + "When subscribed to, a change in this field value shall NOT cause the Forecast attribute to be " + + "updated, since this value may change every 1 second." + + "\n" + + "Note that if the ESA is currently paused, then this value shall NOT change." + + "\n" + + "When the Forecast attribute is read, then this value shall be the most recent value.", + + xref: { document: "cluster", section: "9.2.7.14.5" } + }), + + Field({ + name: "SlotIsPausable", id: 0x5, type: "bool", conformance: "PAU", + details: "This field shall indicate whether this slot can be paused.", + xref: { document: "cluster", section: "9.2.7.14.6" } + }), + + Field({ + name: "MinPauseDuration", id: 0x6, type: "elapsed-s", conformance: "PAU", + details: "This field shall indicate the shortest period that the slot can be paused for. This can be set to " + + "avoid controllers trying to pause ESAs for short periods and then resuming operation in a cyclic " + + "fashion which may damage or cause excess energy to be consumed with restarting of an operation.", + xref: { document: "cluster", section: "9.2.7.14.7" } + }), + + Field({ + name: "MaxPauseDuration", id: 0x7, type: "elapsed-s", conformance: "PAU", + details: "This field shall indicate the longest period that the slot can be paused for.", + xref: { document: "cluster", section: "9.2.7.14.8" } + }), + + Field({ + name: "ManufacturerEsaState", id: 0x8, type: "uint16", conformance: "SFR", + + details: "This field shall indicate a manufacturer defined value indicating the state of the ESA." + + "\n" + + "This may be used by an observing EMS which also has access to the metering data to ascertain the " + + "typical power drawn when the ESA is in a manufacturer defined state." + + "\n" + + "Some appliances, such as smart thermostats, may not know how much power is being drawn by the HVAC " + + "system, but do know what they have asked the HVAC system to do." + + "\n" + + "Manufacturers can use this value to indicate a variety of states in an unspecified way. For " + + "example, they may choose to use values between 0-100 as a percentage of compressor modulation, or " + + "could use these values as Enum states meaning heating with fan, heating without fan etc." + + "\n" + + "NOTE An ESA shall always use the same value to represent the same operating state." + + "\n" + + "By providing this information a smart EMS may be able to learn the observed power draw when the ESA " + + "is put into a specific state. It can potentially then use the ManufacturerESAState field in the " + + "Forecast attribute along with observed power drawn to predict the power draw from the appliance and " + + "potentially ask it to modify its timing via one of the adjustment request commands, or adjust other " + + "ESAs power to compensate.", + + xref: { document: "cluster", section: "9.2.7.14.9" } + }), + + Field({ + name: "NominalPower", id: 0x9, type: "power-mW", conformance: "PFR", + details: "This field shall indicate the expected power that the appliance will use during this slot. It may " + + "be considered the average value over the slot, and some variation from this would be expected (for " + + "example, as it is ramping up).", + xref: { document: "cluster", section: "9.2.7.14.10" } + }), + + Field({ + name: "MinPower", id: 0xa, type: "power-mW", conformance: "PFR", + details: "This field shall indicate the lowest power that the appliance expects to use during this slot. " + + "(e.g. during a ramp up it may be 0W)." + + "\n" + + "Some appliances (e.g. battery inverters which can charge and discharge) may have a negative power.", + xref: { document: "cluster", section: "9.2.7.14.11" } + }), + + Field({ + name: "MaxPower", id: 0xb, type: "power-mW", conformance: "PFR", + details: "This field shall indicate the maximum power that the appliance expects to use during this slot. " + + "(e.g. during a ramp up it may be 0W). This field ignores the effects of short-lived inrush currents." + + "\n" + + "Some appliances (e.g. battery inverters which can charge and discharge) may have a negative power.", + xref: { document: "cluster", section: "9.2.7.14.12" } + }), + + Field({ + name: "NominalEnergy", id: 0xc, type: "energy-mWh", conformance: "PFR", + details: "This field shall indicate the expected energy that the appliance expects to use or produce during " + + "this slot." + + "\n" + + "Some appliances (e.g. battery inverters which can charge and discharge) may have a negative energy.", + xref: { document: "cluster", section: "9.2.7.14.13" } + }), + + Field( + { + name: "Costs", id: 0xd, type: "list", conformance: "O", constraint: "max 5", + + details: "This field shall indicate the current estimated cost for operating." + + "\n" + + "For example, if the device has access to an Energy pricing server it may be able to use the tariff " + + "to estimate the cost of energy for this slot in the power forecast." + + "\n" + + "When an Energy Management System requests a change in the schedule, then the device may suggest a " + + "change in the cost as a result of shifting its energy. This can allow a demand side response " + + "service to be informed of the relative cost to use energy at a different time." + + "\n" + + "The Costs field is a list of CostStruct structures which allows multiple CostTypeEnum and Values to " + + "be shared by the energy appliance. These could be based on GHG emissions, comfort value for the " + + "consumer etc." + + "\n" + + "For example, comfort could be expressed in abstract units or in currency. A water heater that is " + + "heated earlier in the day is likely to lose some of its heat before it is needed, which could " + + "require a top-up heating event to occur later in the day (which may incur additional cost)." + + "\n" + + "If the ESA cannot calculate its cost for any reason (such as losing its connection to a Price " + + "server) it may omit this field. This is treated as extra meta data that an EMS may use to optimize " + + "a system.", + + xref: { document: "cluster", section: "9.2.7.14.14" } + }, + + Field({ name: "entry", type: "CostStruct" }) + ), + + Field({ + name: "MinPowerAdjustment", id: 0xe, type: "power-mW", conformance: "FA & PFR", + + details: "This field shall indicate the minimum power that the appliance can be requested to use." + + "\n" + + "For example, some EVSEs cannot be switched on to charge below 6A which may equate to ~1.3kW in EU " + + "markets. If the slot indicates a NominalPower of 0W (indicating it is expecting to be off), this " + + "allows an ESA to indicate it could be switched on to charge, but this would be the minimum power " + + "limit it can be set to.", + + xref: { document: "cluster", section: "9.2.7.14.15" } + }), + + Field({ + name: "MaxPowerAdjustment", id: 0xf, type: "power-mW", conformance: "FA & PFR", + + details: "This field shall indicate the maximum power that the appliance can be requested to use." + + "\n" + + "For example, an EVSE may be limited by its electrical supply to 32A which would be ~7.6kW in EU " + + "markets. If the slot indicates a NominalPower of 0W (indicating it is expecting to be off), this " + + "allows an ESA to indicate it could be switched on to charge, but this would be the maximum power " + + "limit it can be set to.", + + xref: { document: "cluster", section: "9.2.7.14.16" } + }), + + Field({ + name: "MinDurationAdjustment", id: 0x10, type: "elapsed-s", conformance: "FA", + + details: "This field shall indicate the minimum time, in seconds, that the slot can be requested to shortened " + + "to." + + "\n" + + "For example, if the slot indicates a NominalPower of 0W (indicating it is expecting to be off), " + + "this would allow an ESA to specify the minimum time it could be switched on for. This is to help " + + "protect the appliance from being damaged by short cycling times." + + "\n" + + "For example, a heat pump compressor may have a minimum cycle time of order a few minutes.", + + xref: { document: "cluster", section: "9.2.7.14.17" } + }), + + Field({ + name: "MaxDurationAdjustment", id: 0x11, type: "elapsed-s", conformance: "FA", + + details: "This field shall indicate the maximum time, in seconds, that the slot can be requested to extended " + + "to." + + "\n" + + "For example, if the slot indicates a NominalPower of 0W (indicating it is expecting to be off), " + + "this allows an ESA to specify the maximum time it could be switched on for. This may allow a " + + "battery or water heater to indicate the maximum duration that it can charge for before becoming " + + "full. In the case of a battery inverter which can be discharged, it may equally indicate the " + + "maximum time the battery could be discharged for (at the MaxPowerAdjustment power level).", + + xref: { document: "cluster", section: "9.2.7.14.18" } + }) + ), + + Datatype( + { name: "SlotAdjustmentStruct", type: "struct", xref: { document: "cluster", section: "9.2.7.15" } }, + + Field({ + name: "SlotIndex", id: 0x0, type: "uint8", conformance: "M", constraint: "desc", + details: "This field shall indicate the index into the Slots list within the Forecast that is to be modified. " + + "It shall be less than the actual length of the Slots list (implicitly it must be in the range 0 to " + + "9 based on the maximum length of the Slots list constraint).", + xref: { document: "cluster", section: "9.2.7.15.1" } + }), + + Field({ + name: "NominalPower", id: 0x1, type: "power-mW", conformance: "PFR", constraint: "desc", + details: "This field shall indicate the new requested power that the ESA shall operate at. It MUST be between " + + "the AbsMinPower and AbsMaxPower attributes as advertised by the ESA if it supports PFR." + + "\n" + + "This is a signed value and can be used to indicate charging or discharging. If the ESA does NOT " + + "support PFR this value shall be ignored by the ESA.", + xref: { document: "cluster", section: "9.2.7.15.2" } + }), + + Field({ + name: "Duration", id: 0x2, type: "elapsed-s", conformance: "M", constraint: "desc", + details: "This field shall indicate the new requested duration, in seconds, that the ESA shall extend or " + + "shorten the slot duration to. It MUST be between the MinDurationAdjustment and " + + "MaxDurationAdjustment for the slot as advertised by the ESA.", + xref: { document: "cluster", section: "9.2.7.15.3" } + }) + ), + + Datatype( + { + name: "ConstraintsStruct", type: "struct", + details: "The ConstraintsStruct allows a client to inform an ESA about a constraint period (such as a grid " + + "event, or perhaps excess solar PV). The format allows the client to suggest that the ESA can either " + + "turn up its energy consumption, or turn down its energy consumption during this period.", + xref: { document: "cluster", section: "9.2.7.16" } + }, + + Field({ + name: "StartTime", id: 0x0, type: "epoch-s", conformance: "M", constraint: "desc", + details: "This field shall indicate the start time of the constraint period that the client wishes the ESA to " + + "compute a new Forecast." + + "\n" + + "This value is in UTC and MUST be in the future.", + xref: { document: "cluster", section: "9.2.7.16.1" } + }), + + Field({ + name: "Duration", id: 0x1, type: "elapsed-s", conformance: "M", constraint: "max 86400", + details: "This field shall indicate the duration of the constraint in seconds.", + xref: { document: "cluster", section: "9.2.7.16.2" } + }), + + Field({ + name: "NominalPower", id: 0x2, type: "power-mW", conformance: "PFR", constraint: "desc", + details: "This field shall indicate the nominal power that client wishes the ESA to operate at during the " + + "constrained period. It MUST be between the AbsMinPower and AbsMaxPower attributes as advertised by " + + "the ESA if it supports PFR." + + "\n" + + "This is a signed value and can be used to indicate charging or discharging.", + xref: { document: "cluster", section: "9.2.7.16.3" } + }), + + Field({ + name: "MaximumEnergy", id: 0x3, type: "energy-mWh", conformance: "PFR", + details: "This field shall indicate the maximum energy that can be transferred to or from the ESA during the " + + "constraint period." + + "\n" + + "This is a signed value and can be used to indicate charging or discharging.", + xref: { document: "cluster", section: "9.2.7.16.4" } + }), + + Field({ + name: "LoadControl", id: 0x4, type: "int8", conformance: "SFR", + + details: "This field shall indicate the turn up or turn down nature that the grid wants as the outcome by the " + + "ESA during the constraint period." + + "\n" + + "This is expressed as a signed value between -100 to +100. A value of 0 would indicate no bias to " + + "using more or less energy. A negative value indicates a request to use less energy. A positive " + + "value indicates a request to use more energy." + + "\n" + + "Note that the mapping between values and operation is manufacturer specific.", + + xref: { document: "cluster", section: "9.2.7.16.5" } + }) + ) + ), + + Cluster( + { + name: "EnergyEvse", id: 0x99, classification: "application", pics: "EEVSE", + + details: "Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or " + + "Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of " + + "Electric Vehicle Supply Equipment (EVSE) management." + + "\n" + + "Devices targeted by this cluster include Electric Vehicle Supply Equipment (EVSE). The cluster " + + "generically assumes a signaling protocol (J1772 in NA and IEC61851 in Europe and Asia) between the " + + "EVSE and Electric Vehicle (EV) that utilizes a pilot signal to manage the states of the charging " + + "process. [SAE J2847/3_202311] version and IEC61841 define Pilot signal as a modulated DC voltage on " + + "a single wire." + + "\n" + + "Power Line Communication (PLC) is supported by some EVSEs (e.g. for support of ISO 15118 in Europe " + + "and SAE J2931/4 in NA) and may enable features such as Vehicle to Grid (V2G) or Vehicle to" + + "\n" + + "Home (V2H) that allows for bi-directional charging/discharging of electric vehicles." + + "\n" + + "More modern EVSE devices may optionally support ISO 15118-20 in Europe and SAE J2836/3 for NA to " + + "support bi-directional charging (Vehicle to Grid - V2G) and Plug and Charge capabilities." + + "\n" + + "This cluster definition assumes AC charging only. DC charging options may be added in future " + + "revisions of this cluster." + + "\n" + + "This cluster supports a safety mechanism that may lockout remote operation until the initial " + + "latching conditions have been met. Some of the fault conditions defined in SAE J1772, such as " + + "Ground- Fault Circuit Interrupter (GFCI) or Charging Circuit Interrupting Device (CCID), may " + + "require clearing by an operator by, for example, pressing a button on the equipment or breaker " + + "panel." + + "\n" + + "This EVSE cluster is written around support of a single EVSE. Having multiple EVSEs at home or a " + + "business is managed by backend system and outside scope of this cluster." + + "\n" + + "Note that in many deployments the EVSE may be outside the home and may suffer from intermittent " + + "network connections (e.g. a weak WiFi signal). It also allows for a charging profile to be pre- " + + "configured, in case there is a temporary communications loss during a charging session.", + + xref: { document: "cluster", section: "9.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.3.4" } }, + + Field({ + name: "PREF", conformance: "M", constraint: "0", description: "ChargingPreferences", + + details: "Since some EVSEs cannot obtain the SoC from the vehicle, some EV charging solutions allow the " + + "consumer to specify a daily charging target (for adding energy to the EV’s battery). This feature " + + "allows the consumer to specify how many miles or km of additional range they need for their typical " + + "daily commute. This range requirement can be converted into a daily energy demand with a target " + + "charging completion time." + + "\n" + + "The EVSE itself can use this information (or may allow a controller such as an EMS) to compute an " + + "optimized charging schedule." + + "\n" + + "An EVSE device which includes a Device Energy Management device with the Device Energy Management " + + "cluster PFR (Power Forecast Reporting) feature can use the charging preferences information to " + + "produce its power forecast." + + "\n" + + "EVSE devices that support the Device Energy Management cluster’s FA feature can have their charging " + + "profiles set by a controller device such as an EMS. For example, if the EVSE advertises a simple " + + "power forecast which allows the EMS to adjust over a wide range of power and time durations, then " + + "the EVSE may allow the EMS to propose a revised optimized forecast (which is the charging profile). " + + "For example, a solar PV ESA may also share its Forecast, so enabling an EMS to adjust the EVSE " + + "forecast to the best time to charge so that any excess solar generation is used to charge the EV." + + "\n" + + "See the Device Energy Management Cluster for more details.", + + xref: { document: "cluster", section: "9.3.4.1" } + }), + + Field({ + name: "SOC", conformance: "P, O", constraint: "1", description: "SoCReporting", + + details: "Vehicles and EVSEs which support ISO 15118 may allow the vehicle to report its battery size and " + + "state of charge. If the EVSE supports PLC it may have a vehicle connected which optionally supports " + + "reporting of its battery size and current State of Charge (SoC)." + + "\n" + + "If the EVSE supports reporting of State of Charge this feature will only work if a compatible EV is " + + "connected." + + "\n" + + "Note some EVSEs may use other undefined mechanisms to obtain vehicle State of Charge outside the " + + "scope of this cluster.", + + xref: { document: "cluster", section: "9.3.4.2" } + }), + + Field({ + name: "PNC", conformance: "P, O", constraint: "2", description: "PlugAndCharge", + + details: "If the EVSE supports PLC, it may be able to support the Plug and Charge feature. e.g. this may " + + "allow the vehicle ID to be obtained which may allow an energy management system to track energy " + + "usage per vehicle (e.g. to give the owner an indicative cost of charging, or for work place " + + "charging)." + + "\n" + + "If the EVSE supports the Plug and Charge feature, it will only work if a compatible EV is connected.", + + xref: { document: "cluster", section: "9.3.4.3" } + }), + + Field({ + name: "RFID", conformance: "O", constraint: "3", description: "Rfid", + + details: "If the EVSE is fitted with an RFID reader, it may be possible to obtain the User or Vehicle ID from " + + "an RFID card. This may be used to record a charging session against a specific charging account, " + + "and may optionally be used to authorize a charging session." + + "\n" + + "An RFID event can be generated when a user taps an RFID card onto the RFID reader. The event must " + + "be subscribed to by the EVSE Management cluster client. This client may use this to enable the EV " + + "to charge or discharge. The lookup and authorization of RIFD UID is outside the scope of this " + + "cluster.", + + xref: { document: "cluster", section: "9.3.4.4" } + }), + + Field({ + name: "V2X", conformance: "P, O", constraint: "4", description: "V2X", + + details: "If the EVSE can support bi-directional charging, it may be possible to request that the vehicle can " + + "discharge to the home or grid." + + "\n" + + "The charging and discharging may be controlled by a home Energy Management System (EMS) using the " + + "Device Energy Management cluster of the associated Device Energy Management device. For example, an " + + "EMS may use the PA (Power Adjustment) feature to continually adjust the charge/discharge current " + + "to/from the EV so as to minimise the energy flow from/to the grid as the demand in the home and the " + + "solar supply to the home both fluctuate.", + + xref: { document: "cluster", section: "9.3.4.5" } + }) + ), + + Attribute({ + name: "State", id: 0x0, type: "StateEnum", access: "R V", conformance: "M", quality: "X", + + details: "Indicates the current status of the EVSE. This higher-level status is partly derived from the " + + "signaling protocol as communicated between the EVSE and the vehicle through the pilot signal." + + "\n" + + "The State attribute shall change when the EVSE detects change of condition of the EV (plugged in or " + + "unplugged, whether the vehicle is asking for demand or not, and if it is charging or discharging)." + + "\n" + + "NOTE" + + "\n" + + "SessionEnding is not really a state but a transition. However, the transition period may take a few " + + "seconds and is useful for some clean up purposes." + + "\n" + + "The Fault state is used to indicate that the FaultState attribute is not NoError." + + "\n" + + "A null value shall indicate that the state cannot be determined.", + + xref: { document: "cluster", section: "9.3.8.1" } + }), + + Attribute({ + name: "SupplyState", id: 0x1, type: "SupplyStateEnum", access: "R V", conformance: "M", + details: "Indicates whether the EV is currently allowed to charge from or discharge to the EVSE.", + xref: { document: "cluster", section: "9.3.8.2" } + }), + + Attribute({ + name: "FaultState", id: 0x2, type: "FaultStateEnum", access: "R V", conformance: "M", + details: "Indicates the type of fault detected by the EVSE (internally or as detected in the pilot signal)." + + "\n" + + "When the SupplyState attribute is DisabledError, the FaultState attribute will be one of the values " + + "listed in FaultStateEnum, except NoError. For all values of SupplyState other than DisabledError, " + + "the FaultState attribute shall be NoError.", + xref: { document: "cluster", section: "9.3.8.3" } + }), + + Attribute({ + name: "ChargingEnabledUntil", id: 0x3, type: "epoch-s", access: "R V", conformance: "M", default: 0, + quality: "X N", + + details: "Indicates the time, in UTC, that the EVSE will automatically stop current flow to the EV." + + "\n" + + "A null value indicates the EVSE is always enabled for charging." + + "\n" + + "A value in the past or 0x0 indicates that EVSE charging shall be disabled. The attribute is only " + + "set via the payload of the EnableCharging command." + + "\n" + + "This attribute shall be persisted, for example a temporary power failure should not stop the " + + "vehicle from being charged.", + + xref: { document: "cluster", section: "9.3.8.4" } + }), + + Attribute({ + name: "DischargingEnabledUntil", id: 0x4, type: "epoch-s", access: "R V", conformance: "V2X", + default: 0, quality: "X N", + + details: "Indicates the time, in UTC, that the EVSE will automatically stop current flow from the EV." + + "\n" + + "A null value indicates the EVSE is always enabled for discharging." + + "\n" + + "A value in the past or 0x0 indicates that EVSE discharging shall be disabled. The attribute is only " + + "set via the payload of the EnableDischarging command." + + "\n" + + "This attribute shall be persisted, for example a temporary power failure should not stop the " + + "vehicle from being discharged.", + + xref: { document: "cluster", section: "9.3.8.5" } + }), + + Attribute({ + name: "CircuitCapacity", id: 0x5, type: "amperage-mA", access: "R V", conformance: "M", + constraint: "min 0", default: 0, quality: "N", + details: "Indicates the capacity that the circuit that the EVSE is connected to can provide. It is intended " + + "to allow implementation of a self-managed network of EVSEs. It is assumed that the device will " + + "allow the setting of such values by an installer.", + xref: { document: "cluster", section: "9.3.8.6" } + }), + + Attribute({ + name: "MinimumChargeCurrent", id: 0x6, type: "amperage-mA", access: "R V", conformance: "M", + constraint: "min 0", default: 6000, quality: "N", + details: "Indicates the minimum current that can be delivered by the EVSE to the EV." + + "\n" + + "The attribute can be set using the EnableCharging command.", + xref: { document: "cluster", section: "9.3.8.7" } + }), + + Attribute({ + name: "MaximumChargeCurrent", id: 0x7, type: "amperage-mA", access: "R V", conformance: "M", + constraint: "min 0", default: 0, quality: "N", + + details: "Indicates the maximum current that can be delivered by the EVSE to the EV." + + "\n" + + "This shall represent the actual maximum current offered to the EV at any time. Note that the EV can " + + "draw less current than this value. For example, the EV may be limiting its power draw based on the " + + "operating conditions of the battery, such as temperature and state of charge." + + "\n" + + "The attribute can be initially set using the EnableCharging command or by adjusting the " + + "UserMaximumChargeCurrent attribute." + + "\n" + + "This attribute value shall be the minimum of:" + + "\n" + + " • CircuitCapacity - Electrician’s installation setting" + + "\n" + + " • CableAssemblyCurrentLimit (detected by the EVSE when the cable is plugged in)" + + "\n" + + " • MaximumChargeCurrent field in the EnableCharging command" + + "\n" + + " • UserMaximumChargeCurrent attribute", + + xref: { document: "cluster", section: "9.3.8.8" } + }), + + Attribute({ + name: "MaximumDischargeCurrent", id: 0x8, type: "amperage-mA", access: "R V", conformance: "V2X", + constraint: "min 0", default: 0, quality: "N", + + details: "Indicates the maximum current that can be received by the EVSE from the EV. This attribute can be " + + "set using the EnableDischarging command." + + "\n" + + "This attribute value shall be the minimum of:" + + "\n" + + " • CircuitCapacity - Electrician’s installation setting" + + "\n" + + " • CableAssemblyCurrentLimit (detected by the EVSE when the cable is plugged in)" + + "\n" + + " • MaximumDischargeCurrent field in the EnableDischarging command", + + xref: { document: "cluster", section: "9.3.8.9" } + }), + + Attribute({ + name: "UserMaximumChargeCurrent", id: 0x9, type: "amperage-mA", access: "RW VM", conformance: "O", + constraint: "desc", default: 0, quality: "N", + + details: "Indicates a maximum current that can set by the consumer (e.g. via an app) as a preference to " + + "further reduce the charging rate. This may be desirable if the home owner has a solar PV or battery " + + "storage system which may only be able to deliver a limited amount of power. The consumer can " + + "manually control how much they allow the EV to take." + + "\n" + + "This attribute value shall be limited by the EVSE to be in the range of:" + + "\n" + + "MinimumChargeCurrent <= UserMaximumChargeCurrent <= MaximumChargeCurrent" + + "\n" + + "where MinimumChargeCurrent and MaximumChargeCurrent are the values received in the EnableCharging " + + "command." + + "\n" + + "Its default value SHOULD be initialized to the same as the CircuitCapacity attribute. This value " + + "shall be persisted across reboots to ensure it does not cause charging issues during temporary " + + "power failures.", + + xref: { document: "cluster", section: "9.3.8.10" } + }), + + Attribute({ + name: "RandomizationDelayWindow", id: 0xa, type: "elapsed-s", access: "RW VM", conformance: "O", + constraint: "max 86400", default: 600, quality: "N", + + details: "Indicates the size of a random window over which the EVSE will randomize the start of a charging " + + "session. This value is in seconds." + + "\n" + + "This is a feature that is mandated in some markets (such as UK) where the EVSE should by default " + + "randomize its start time within the randomization window. By default in the UK this should be 600s." + + "\n" + + "For example, if the RandomizationDelayWindow is 600s (i.e. 10 minutes) and if there was a cheap " + + "rate energy starting at 00:30, then the EVSE must compute a random delay between 0-599s and add " + + "this to its initial planned start time.", + + xref: { document: "cluster", section: "9.3.8.11" } + }), + + Attribute({ + name: "NextChargeStartTime", id: 0x23, type: "epoch-s", access: "R V", conformance: "PREF", + default: null, quality: "X", + + details: "Indicates the time, in UTC, when the EVSE plans to start the next scheduled charge based on the " + + "charging preferences." + + "\n" + + "A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to " + + "use Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that " + + "charging is enabled.", + + xref: { document: "cluster", section: "9.3.8.12" } + }), + + Attribute({ + name: "NextChargeTargetTime", id: 0x24, type: "epoch-s", access: "R V", conformance: "PREF", + default: null, quality: "X", + + details: "Indicates the time, in UTC, when the EVSE SHOULD complete the next scheduled charge based on the " + + "charging preferences." + + "\n" + + "A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to " + + "use Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that " + + "charging is enabled.", + + xref: { document: "cluster", section: "9.3.8.13" } + }), + + Attribute({ + name: "NextChargeRequiredEnergy", id: 0x25, type: "energy-mWh", access: "R V", conformance: "PREF", + constraint: "min 0", default: null, quality: "X", + + details: "Indicates the amount of energy that the EVSE is going to attempt to add to the vehicle in the next " + + "charging target." + + "\n" + + "A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to " + + "use Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that " + + "charging is enabled, or that the next ChargingTargetStruct is using the TargetSoC value to charge " + + "the vehicle.", + + xref: { document: "cluster", section: "9.3.8.14" } + }), + + Attribute({ + name: "NextChargeTargetSoC", id: 0x26, type: "percent", access: "R V", conformance: "PREF", + default: null, quality: "X", + + details: "Indicates the target SoC the EVSE is going to attempt to reach when the vehicle is next charged." + + "\n" + + "A null value indicates that there is no scheduled charging" + + "\n" + + "Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that " + + "charging is enabled, or that the next ChargingTargetStruct is using the AddedEnergy value to charge " + + "the vehicle." + + "\n" + + "If the SOC feature is not supported, only the values null and 100% are supported.", + + xref: { document: "cluster", section: "9.3.8.15" } + }), + + Attribute( + { + name: "ApproximateEvEfficiency", id: 0x27, type: "uint16", access: "RW VM", conformance: "[PREF]", + constraint: "desc", default: null, quality: "X N", + + details: "Indicates the vehicle efficiency rating for a connected vehicle." + + "\n" + + "This can be used to help indicate to the user approximately how many miles or km of range will be " + + "added. It allows user interfaces to display to the user simpler terms that they can relate to " + + "compared to kWh." + + "\n" + + "This is value is stored in km per kWh multiplied by a scaling factor of 1000." + + "\n" + + "A null value indicates that the EV efficiency is unknown and the NextChargeRequiredEnergy attribute " + + "cannot be converted from Wh to miles or km." + + "\n" + + "To convert from Wh into Range:" + + "\n" + + "AddedRange (km) = AddedEnergy (Wh) x ApproxEVEfficiency (km/kWh x 1000) AddedRange (Miles) = " + + "AddedEnergy (Wh) x ApproxEVEfficiency (km/kWh x 1000) x 0.6213" + + "\n" + + "Example:" + + "\n" + + "ApproxEVEfficiency (km/kWh x 1000): 4800 (i.e. 4.8km/kWh x 1000)" + + "\n" + + "AddedEnergy (Wh): 10,000" + + "\n" + + "AddedRange (km) = 10,000 x 4800 / 1,000,000 = 48 km" + + "\n" + + "AddedRange (Miles) = AddedEnergy (Wh) x ApproxEVEfficiency (km/kWh x 1000) x" + + "\n" + + "0.6213" + + "\n" + + "= 29.82 Miles", + + xref: { document: "cluster", section: "9.3.8.16" } + } + ), + + Attribute({ + name: "StateOfCharge", id: 0x30, type: "percent", access: "R V", conformance: "SOC", default: null, + quality: "X", + details: "Indicates the state of charge of the EV battery in steps of 1%. The values are in the 0-100%. This " + + "attribute is only available on EVSEs which can read the state of charge from the vehicle and that " + + "support the SOC feature. If the StateOfCharge cannot be read from the vehicle it shall be returned " + + "with a NULL value.", + xref: { document: "cluster", section: "9.3.8.17" } + }), + + Attribute({ + name: "BatteryCapacity", id: 0x31, type: "energy-mWh", access: "R V", conformance: "SOC", + constraint: "min 0", default: null, quality: "X", + details: "Indicates the capacity of the EV battery in mWh. This value is always positive.", + xref: { document: "cluster", section: "9.3.8.18" } + }), + + Attribute({ + name: "VehicleId", id: 0x32, type: "string", access: "R V", conformance: "PNC", + constraint: "max 32", default: null, quality: "X", + details: "Indicates the vehicle ID read by the EVSE via ISO-15118 using the PNC feature, if the EVSE supports " + + "this capability." + + "\n" + + "The field may be based on the e-Mobility Account Identifier (EMAID). A null value shall indicate " + + "that this is unknown.", + xref: { document: "cluster", section: "9.3.8.19" } + }), + + Attribute({ + name: "SessionId", id: 0x40, type: "uint32", access: "R V", conformance: "M", default: null, + quality: "X N", + xref: { document: "cluster", section: "9.3.8" } + }), + Attribute({ + name: "SessionDuration", id: 0x41, type: "elapsed-s", access: "R V", conformance: "M", + default: null, quality: "X N Q", + xref: { document: "cluster", section: "9.3.8" } + }), + Attribute({ + name: "SessionEnergyCharged", id: 0x42, type: "energy-mWh", access: "R V", conformance: "M", + constraint: "min 0", default: null, quality: "X N Q", + xref: { document: "cluster", section: "9.3.8" } + }), + Attribute({ + name: "SessionEnergyDischarged", id: 0x43, type: "energy-mWh", access: "R V", conformance: "V2X", + constraint: "min 0", default: null, quality: "X N Q", + xref: { document: "cluster", section: "9.3.8" } + }), + + Event( + { + name: "EvConnected", id: 0x0, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when the EV is plugged in.", + xref: { document: "cluster", section: "9.3.10.1" } + }, + Field({ + name: "SessionId", id: 0x0, type: "uint32", conformance: "M", + details: "This is the new session ID created after the vehicle is plugged in.", + xref: { document: "cluster", section: "9.3.10.1.1" } + }) + ), + + Event( + { + name: "EvNotDetected", id: 0x1, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when the EV is unplugged or not detected (having been previously " + + "plugged in). When the vehicle is unplugged then the session is ended.", + xref: { document: "cluster", section: "9.3.10.2" } + }, + + Field({ + name: "SessionId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall indicate the current value of the SessionID attribute.", + xref: { document: "cluster", section: "9.3.10.2.1" } + }), + Field({ + name: "State", id: 0x1, type: "StateEnum", conformance: "M", + details: "This field shall indicate the value of the State attribute prior to the EV not being detected.", + xref: { document: "cluster", section: "9.3.10.2.2" } + }), + + Field({ + name: "SessionDuration", id: 0x2, type: "elapsed-s", conformance: "M", + details: "This field shall indicate the total duration of the session, from the start of the session when the " + + "EV was plugged in, until it was unplugged.", + xref: { document: "cluster", section: "9.3.10.2.3" } + }), + + Field({ + name: "SessionEnergyCharged", id: 0x3, type: "energy-mWh", conformance: "M", constraint: "min 0", + + details: "This field shall indicate the total amount of energy transferred from the EVSE to the EV during the " + + "session." + + "\n" + + "Note that if bi-directional charging occurs during the session, then this value shall only include " + + "the sum of energy transferred from the EVSE to the EV, and shall NOT be a net value of charging and " + + "discharging energy.", + + xref: { document: "cluster", section: "9.3.10.2.4" } + }), + + Field({ + name: "SessionEnergyDischarged", id: 0x4, type: "energy-mWh", conformance: "V2X", + constraint: "min 0", + + details: "This field shall indicate the total amount of energy transferred from the EV to the EVSE during the " + + "session." + + "\n" + + "Note that if bi-directional discharging occurs during the session, then this value shall only " + + "include the sum of energy transferred from the EV to the EVSE, and shall NOT be a net value of " + + "charging and discharging energy.", + + xref: { document: "cluster", section: "9.3.10.2.5" } + }) + ), + + Event( + { + name: "EnergyTransferStarted", id: 0x2, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated whenever the EV starts charging or discharging, except when an EV has " + + "switched between charging and discharging under the control of the PowerAdjustment feature of the " + + "Device Energy Management cluster of the associated Device Energy Management device.", + xref: { document: "cluster", section: "9.3.10.3" } + }, + + Field({ + name: "SessionId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall indicate the value of the SessionID attribute at the time the event was generated.", + xref: { document: "cluster", section: "9.3.10.3.1" } + }), + Field({ + name: "State", id: 0x1, type: "StateEnum", conformance: "M", + details: "This field shall indicate the value of the State attribute at the time the event was generated.", + xref: { document: "cluster", section: "9.3.10.3.2" } + }), + + Field({ + name: "MaximumCurrent", id: 0x2, type: "amperage-mA", conformance: "M", constraint: "min 0", + + details: "This field shall indicate the value of the maximum charging current at the time the event was " + + "generated." + + "\n" + + "A non-zero value indicates that the EV has been enabled for charging and the value is taken " + + "directly from the MaximumChargeCurrent attribute. A zero value indicates that the EV has not been " + + "enabled for charging.", + + xref: { document: "cluster", section: "9.3.10.3.3" } + }), + + Field({ + name: "MaximumDischargeCurrent", id: 0x3, type: "amperage-mA", conformance: "V2X", + constraint: "min 0", + + details: "This field shall indicate the value of the maximum discharging current at the time the event was " + + "generated." + + "\n" + + "A non-zero value indicates that the EV has been enabled for discharging and the value is taken " + + "directly from the MaximumDischargeCurrent attribute. A zero value indicates that the EV has not " + + "been enabled for discharging.", + + xref: { document: "cluster", section: "9.3.10.3.4" } + }) + ), + + Event( + { + name: "EnergyTransferStopped", id: 0x3, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated whenever the EV stops charging or discharging, except when an EV has " + + "switched between charging and discharging under the control of the PowerAdjustment feature of the " + + "Device Energy Management cluster of the associated Device Energy Management device.", + xref: { document: "cluster", section: "9.3.10.4" } + }, + + Field({ + name: "SessionId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall indicate the value of the SessionID attribute prior to the energy transfer " + + "stopping.", + xref: { document: "cluster", section: "9.3.10.4.1" } + }), + + Field({ + name: "State", id: 0x1, type: "StateEnum", conformance: "M", + details: "This field shall indicate the value of the State attribute prior to the energy transfer stopping.", + xref: { document: "cluster", section: "9.3.10.4.2" } + }), + Field({ + name: "Reason", id: 0x2, type: "EnergyTransferStoppedReasonEnum", conformance: "M", + details: "This field shall indicate the reason why the energy transferred stopped.", + xref: { document: "cluster", section: "9.3.10.4.3" } + }), + + Field({ + name: "EnergyTransferred", id: 0x4, type: "energy-mWh", conformance: "M", constraint: "min 0", + details: "This field shall indicate the amount of energy transferred from the EVSE to the EV since the " + + "previous EnergyTransferStarted event, in mWh.", + xref: { document: "cluster", section: "9.3.10.4.4" } + }), + + Field({ + name: "EnergyDischarged", id: 0x5, type: "energy-mWh", conformance: "V2X", constraint: "min 0", + details: "This field shall indicate the amount of energy transferred from the EV to the EVSE since the " + + "previous EnergyTransferStarted event, in mWh.", + xref: { document: "cluster", section: "9.3.10.4.5" } + }) + ), + + Event( + { + name: "Fault", id: 0x4, access: "V", conformance: "M", priority: "critical", + + details: "If the EVSE detects a fault it shall generate a Fault Event. The SupplyState attribute shall be set " + + "to DisabledError and the type of fault detected by the EVSE shall be stored in the FaultState " + + "attribute." + + "\n" + + "This event shall be generated when the FaultState changes from any error state. i.e. if it changes " + + "from NoError to any other state and if the error then clears, this would generate 2 events." + + "\n" + + "It is assumed that the fault will be cleared locally on the EVSE device. When all faults have been " + + "cleared, the EVSE device shall set the FaultState attribute to NoError and the SupplyState " + + "attribute shall be set back to its previous state.", + + xref: { document: "cluster", section: "9.3.10.5" } + }, + + Field({ + name: "SessionId", id: 0x0, type: "uint32", conformance: "M", quality: "X", + details: "This field shall indicate the value of the SessionID attribute prior to the Fault State being " + + "changed. A value of null indicates no sessions have occurred before the fault occurred.", + xref: { document: "cluster", section: "9.3.10.5.1" } + }), + + Field({ + name: "State", id: 0x1, type: "StateEnum", conformance: "M", + details: "This field shall indicate the value of the State attribute prior to the Fault State being changed.", + xref: { document: "cluster", section: "9.3.10.5.2" } + }), + + Field({ + name: "FaultStatePreviousState", id: 0x2, type: "FaultStateEnum", conformance: "M", + details: "This field shall indicate the value of the FaultState attribute prior to the Fault State being " + + "changed.", + xref: { document: "cluster", section: "9.3.10.5.3" } + }), + + Field({ + name: "FaultStateCurrentState", id: 0x4, type: "FaultStateEnum", conformance: "M", + details: "This field shall indicate the current value of the FaultState attribute.", + xref: { document: "cluster", section: "9.3.10.5.4" } + }) + ), + + Event( + { + name: "Rfid", id: 0x5, access: "V", conformance: "[RFID]", priority: "info", + details: "This event shall be generated when a RFID card has been read. This allows a controller to register " + + "the card ID and use this to authenticate and start the charging session.", + xref: { document: "cluster", section: "9.3.10.6" } + }, + + Field({ + name: "Uid", id: 0x0, type: "octstr", conformance: "M", constraint: "max 10", + details: "The UID field (ISO 14443A UID) is either 4, 7 or 10 bytes.", + xref: { document: "cluster", section: "9.3.10.6.1" } + }) + ), + + Command({ + name: "Disable", id: 0x1, access: "O T", conformance: "M", direction: "request", response: "status", + details: "Allows a client to disable the EVSE from charging and discharging.", + xref: { document: "cluster", section: "9.3.9.1" } + }), + + Command( + { + name: "EnableCharging", id: 0x2, access: "O T", conformance: "M", direction: "request", + response: "status", + details: "This command allows a client to enable the EVSE to charge an EV, and to provide or update the " + + "maximum and minimum charge current.", + xref: { document: "cluster", section: "9.3.9.2" } + }, + + Field({ + name: "ChargingEnabledUntil", id: 0x0, type: "epoch-s", conformance: "M", default: null, + quality: "X", + details: "This field shall indicate the expiry time, in UTC, when charging will be automatically disabled." + + "\n" + + "A value in the past in this field shall disable the EVSE charging whereas a null value shall enable " + + "it permanently.", + xref: { document: "cluster", section: "9.3.9.2.1" } + }), + + Field({ + name: "MinimumChargeCurrent", id: 0x1, type: "amperage-mA", conformance: "M", constraint: "min 0", + details: "This field shall indicate the minimum current that can be delivered by the EVSE to the EV in " + + "trickle mode. The EVSE current limit can be advertised to an EV in 0.6A steps." + + "\n" + + "The value of the MinimumChargeCurrent attribute shall be set to the value of this field (see " + + "MinimumChargeCurrent attribute for further details).", + xref: { document: "cluster", section: "9.3.9.2.2" } + }), + + Field({ + name: "MaximumChargeCurrent", id: 0x2, type: "amperage-mA", conformance: "M", constraint: "min 0", + + details: "This field shall indicate the maximum current that can be delivered by the EVSE to the EV. The EVSE " + + "current limit can be advertised to an EV in 0.6A steps." + + "\n" + + "The value of the this field shall be stored by the EVSE to determine the value of " + + "MaximumChargeCurrent attribute. For example, if the UserMaximumChargeCurrent attribute is adjusted " + + "below then this value, and then later adjusted above this value, the resulting MaximumChargeCurrent " + + "attribute will be limited to this value.", + + xref: { document: "cluster", section: "9.3.9.2.3" } + }) + ), + + Command( + { + name: "EnableDischarging", id: 0x3, access: "O T", conformance: "V2X", direction: "request", + response: "status", + details: "Upon receipt, this shall allow a client to enable the discharge of an EV, and to provide or update " + + "the maximum discharge current.", + xref: { document: "cluster", section: "9.3.9.3" } + }, + + Field({ + name: "DischargingEnabledUntil", id: 0x0, type: "epoch-s", conformance: "M", default: null, + quality: "X", + details: "This field shall indicate the expiry time, in UTC, when discharging will be automatically disabled." + + "\n" + + "A value in the past in this field shall disable the EVSE discharging whereas a null value shall " + + "enable EVSE discharging permanently.", + xref: { document: "cluster", section: "9.3.9.3.1" } + }), + + Field({ + name: "MaximumDischargeCurrent", id: 0x1, type: "amperage-mA", conformance: "M", + constraint: "min 0", + details: "This field shall indicate the maximum current that can be received by the EVSE from the EV. The " + + "EVSE current limit can be advertised to an EV in 0.6A steps. The value of the " + + "MaximumDischargeCurrent attribute shall be stored and persisted across reboots by the EVSE to the " + + "value of this field.", + xref: { document: "cluster", section: "9.3.9.3.2" } + }) + ), + + Command({ + name: "StartDiagnostics", id: 0x4, access: "O T", conformance: "O", direction: "request", + response: "status", + details: "Allows a client to put the EVSE into a self-diagnostics mode.", + xref: { document: "cluster", section: "9.3.9.4" } + }), + + Command( + { + name: "SetTargets", id: 0x5, access: "O T", conformance: "PREF", direction: "request", + response: "status", + details: "Allows a client to set the user specified charging targets.", + xref: { document: "cluster", section: "9.3.9.5" } + }, + + Field( + { + name: "ChargingTargetSchedules", id: 0x0, type: "list", conformance: "M", constraint: "max 7", + details: "This field shall indicate a list of up to 7 sets of daily charging targets together with their " + + "associated days of the week. Each of the days of the week may only be included in a single " + + "ChargingTargetSchedule within this list field.", + xref: { document: "cluster", section: "9.3.9.5.1" } + }, + + Field({ name: "entry", type: "ChargingTargetScheduleStruct" }) + ) + ), + + Command({ + name: "GetTargets", id: 0x6, access: "O T", conformance: "PREF", direction: "request", + response: "GetTargetsResponse", + details: "Allows a client to retrieve the current set of charging targets.", + xref: { document: "cluster", section: "9.3.9.6" } + }), + + Command({ + name: "ClearTargets", id: 0x7, access: "O T", conformance: "PREF", direction: "request", + response: "status", + details: "Allows a client to clear all stored charging targets.", + xref: { document: "cluster", section: "9.3.9.8" } + }), + + Command( + { + name: "GetTargetsResponse", id: 0x0, conformance: "PREF", direction: "response", + details: "The GetTargetsResponse is sent in response to the GetTargets Command.", + xref: { document: "cluster", section: "9.3.9.7" } + }, + + Field( + { + name: "ChargingTargetSchedules", id: 0x0, type: "list", conformance: "M", constraint: "max 7", + details: "This field shall indicate a list of up to 7 sets of daily charging targets together with their " + + "associated days of the week.", + xref: { document: "cluster", section: "9.3.9.7.1" } + }, + + Field({ name: "entry", type: "ChargingTargetScheduleStruct" }) + ) + ), + + Datatype( + { name: "TargetDayOfWeekBitmap", type: "map8", xref: { document: "cluster", section: "9.3.7.1" } }, + Field({ name: "Sunday", constraint: "0", description: "Sunday" }), + Field({ name: "Monday", constraint: "1", description: "Monday" }), + Field({ name: "Tuesday", constraint: "2", description: "Tuesday" }), + Field({ name: "Wednesday", constraint: "3", description: "Wednesday" }), + Field({ name: "Thursday", constraint: "4", description: "Thursday" }), + Field({ name: "Friday", constraint: "5", description: "Friday" }), + Field({ name: "Saturday", constraint: "6", description: "Saturday" }) + ), + + Datatype( + { name: "StateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.2" } }, + Field({ name: "NotPluggedIn", id: 0x0, conformance: "M", description: "The EV is not plugged in." }), + Field({ + name: "PluggedInNoDemand", id: 0x1, conformance: "M", + description: "The EV is plugged in, but not demanding current." + }), + Field({ + name: "PluggedInDemand", id: 0x2, conformance: "M", + description: "The EV is plugged in and is demanding current, but EVSE is not allowing current to flow." + }), + Field({ + name: "PluggedInCharging", id: 0x3, conformance: "M", + description: "The EV is plugged in, charging is in progress, and current is flowing" + }), + Field({ + name: "PluggedInDischarging", id: 0x4, conformance: "V2X", + description: "The EV is plugged in, discharging is in progress, and current is flowing" + }), + Field({ + name: "SessionEnding", id: 0x5, conformance: "M", + description: "The EVSE is transitioning from any plugged- in state to NotPluggedIn" + }), + Field({ name: "Fault", id: 0x6, conformance: "M", description: "There is a fault (see FaultState attribute)" }) + ), + + Datatype( + { name: "SupplyStateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.3" } }, + Field({ + name: "Disabled", id: 0x0, conformance: "M", + description: "The EV is not currently allowed to charge or discharge" + }), + Field({ + name: "ChargingEnabled", id: 0x1, conformance: "M", + description: "The EV is currently allowed to charge" + }), + Field({ + name: "DischargingEnabled", id: 0x2, conformance: "[V2X]", + description: "The EV is currently allowed to discharge" + }), + Field({ + name: "DisabledError", id: 0x3, conformance: "M", + description: "The EV is not currently allowed to charge or discharge due to an error. The error must be cleared before operation can continue." + }), + Field({ + name: "DisabledDiagnostics", id: 0x4, conformance: "M", + description: "The EV is not currently allowed to charge or discharge due to self- diagnostics mode." + }), + Field({ + name: "Enabled", id: 0x5, conformance: "[V2X]", + description: "The EV is currently allowed to charge and discharge" + }) + ), + + Datatype( + { name: "FaultStateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.4" } }, + Field({ name: "NoError", id: 0x0, conformance: "M", description: "The EVSE is not in an error state." }), + Field({ + name: "MeterFailure", id: 0x1, conformance: "M", + description: "The EVSE is unable to obtain electrical measurements." + }), + Field({ + name: "OverVoltage", id: 0x2, conformance: "M", + description: "The EVSE input voltage level is too high." + }), + Field({ + name: "UnderVoltage", id: 0x3, conformance: "M", + description: "The EVSE input voltage level is too low." + }), + Field({ + name: "OverCurrent", id: 0x4, conformance: "M", + description: "The EVSE detected charging current higher than allowed by charger." + }), + Field({ + name: "ContactWetFailure", id: 0x5, conformance: "M", + description: "The EVSE detected voltage on charging pins when the contactor is open." + }), + Field({ + name: "ContactDryFailure", id: 0x6, conformance: "M", + description: "The EVSE detected absence of voltage after enabling contactor." + }), + Field({ + name: "GroundFault", id: 0x7, conformance: "M", + description: "The EVSE has an unbalanced current supply." + }), + Field({ name: "PowerLoss", id: 0x8, conformance: "M", description: "The EVSE has detected a loss in power." }), + Field({ + name: "PowerQuality", id: 0x9, conformance: "M", + description: "The EVSE has detected another power quality issue (e.g. phase imbalance)." + }), + Field({ + name: "PilotShortCircuit", id: 0xa, conformance: "M", + description: "The EVSE pilot signal amplitude short circuited to ground." + }), + Field({ name: "EmergencyStop", id: 0xb, conformance: "M", description: "The emergency stop button was pressed." }), + Field({ + name: "EvDisconnected", id: 0xc, conformance: "M", + description: "The EVSE detected that the cable has been disconnected." + }), + Field({ + name: "WrongPowerSupply", id: 0xd, conformance: "M", + description: "The EVSE could not determine proper power supply level." + }), + Field({ + name: "LiveNeutralSwap", id: 0xe, conformance: "M", + description: "The EVSE detected Live and Neutral are swapped." + }), + Field({ + name: "OverTemperature", id: 0xf, conformance: "M", + description: "The EVSE internal temperature is too high." + }), + Field({ name: "Other", id: 0xff, conformance: "M", description: "Any other reason." }) + ), + + Datatype( + { + name: "EnergyTransferStoppedReasonEnum", type: "enum8", + xref: { document: "cluster", section: "9.3.7.5" } + }, + Field({ name: "EvStopped", id: 0x0, conformance: "M", description: "The EV decided to stop" }), + Field({ name: "EvseStopped", id: 0x1, conformance: "M", description: "The EVSE decided to stop" }), + Field({ name: "Other", id: 0x2, conformance: "M", description: "An other unknown reason" }) + ), + + Datatype( + { + name: "ChargingTargetStruct", type: "struct", + + details: "This represents a single user specified charging target for an EV." + + "\n" + + "An EVSE or EMS system optimizer may use this information to take the Time of Use Tariff, grid " + + "carbon intensity, local generation (solar PV) into account to provide the cheapest and cleanest " + + "energy to the EV." + + "\n" + + "The optimization strategy is not defined here, however in simple terms, the AddedEnergy requirement " + + "can be fulfilled by knowing the charging Power (W) and the time needed to charge." + + "\n" + + "To compute the Charging Time: Required Energy (Wh) = Power (W) x ChargingTime (s) / 3600 Therefore: " + + "ChargingTime (s) = (3600 x RequiredEnergy (wH)) / Power (W)" + + "\n" + + "To compute the charging time: Charging StartTime = TargetTimeMinutesPastMidnight - ChargingTime", + + xref: { document: "cluster", section: "9.3.7.6" } + }, + + Field({ + name: "TargetTimeMinutesPastMidnight", id: 0x0, type: "uint16", conformance: "M", + constraint: "max 1439", default: 0, + + details: "This field shall indicate the desired charging completion time of the associated day. The time will " + + "be represented by a 16 bits unsigned integer to designate the minutes since midnight. For example, " + + "6am will be represented by 360 minutes since midnight and 11:30pm will be represented by 1410 " + + "minutes since midnight." + + "\n" + + "This field is based on local wall clock time. In case of Daylight Savings Time transition which may " + + "result in an extra hour or one hour less in the day, the charging algorithm should take into " + + "account the shift appropriately." + + "\n" + + "Note that if the TargetTimeMinutesPastMidnight values are too close together (e.g. 2 per day) these " + + "may overlap. The EVSE may have to coalesce the charging targets into a single target. e.g. if the " + + "1st charging target cannot be met in the time available, the EVSE may be forced to begin working " + + "towards the 2nd charging target and immediately continue until both targets have been satisfied (or " + + "the vehicle becomes full)." + + "\n" + + "The EVSE itself cannot predict the behavior of the vehicle (i.e. if it cannot obtain the SoC from " + + "the vehicle), so should attempt to perform a sensible operation based on these targets. It is " + + "recommended that the charging schedule is pessimistic (i.e. starts earlier) since the vehicle may " + + "charge more slowly than the electrical supply may provide power (especially if it is cold)." + + "\n" + + "If the user configures large charging targets (e.g. high values of AddedEnergy or SoC) then it is " + + "expected that the EVSE may need to begin charging immediately, and may not be able to guarantee " + + "that the vehicle will be able to reach the target.", + + xref: { document: "cluster", section: "9.3.7.6.1" } + }), + + Field({ + name: "TargetSoC", id: 0x1, type: "percent", conformance: "SOC, O.a+", default: 0, + + details: "This field represents the target SoC that the vehicle should be charged to before the " + + "TargetTimeMinutesPastMidnight." + + "\n" + + "If the EVSE supports the SOC feature and can obtain the SoC of the vehicle:" + + "\n" + + " • the TargetSoC field shall take precedence over the AddedEnergy field." + + "\n" + + " • the EVSE SHOULD charge to the TargetSoC and then stop the charging automatically when it " + + " reaches that point." + + "\n" + + " • if the TargetSoC value is set to 100% then the EVSE SHOULD continue to charge the vehicle until " + + " the vehicle decides to stop charging." + + "\n" + + "If the EVSE does not support the SOC feature or cannot obtain the SoC of the vehicle:" + + "\n" + + " • the AddedEnergy field shall take precedence over the TargetSoC field, and if the EVSE does not " + + " support the SOC feature then the TargetSoC field may only take the values null or 100%." + + "\n" + + " • if the AddedEnergy field has not been provided, the EVSE SHOULD assume the vehicle is empty" + + "\n" + + "and charge until the vehicle stops demanding a charge.", + + xref: { document: "cluster", section: "9.3.7.6.2" } + }), + + Field({ + name: "AddedEnergy", id: 0x2, type: "energy-mWh", conformance: "[SOC], O.a+", constraint: "min 0", + default: 0, + + details: "This field represents the amount of energy that the user would like to have added to the vehicle " + + "before the TargetTimeMinutesPastMidnight." + + "\n" + + "This represents a positive value in mWh that SHOULD be added during the session (i.e. if the " + + "vehicle charging is stopped and started several times, this equates to the total energy since the " + + "vehicle has been plugged in)." + + "\n" + + "The maximum value (500kWh) is much larger than most EV batteries on the market today. If the client " + + "tries to set this value too high then the EVSE will need to start charging immediately and continue " + + "charging until the vehicle stops demanding charge (i.e. it is full). Therefore the maximum value " + + "should be set based on typical battery size of the vehicles on the market (e.g. 70000Wh), however " + + "this is up to the client to carefully choose a value." + + "\n" + + "NOTE" + + "\n" + + "If the EVSE can obtain the Battery Capacity of the vehicle, it SHOULD NOT limit this AddedEnergy " + + "value to the Battery Capacity of the vehicle, since the EV may also require energy for heating and " + + "cooling of the battery during charging, or for heating or cooling the cabin.", + + xref: { document: "cluster", section: "9.3.7.6.3" } + }) + ), + + Datatype( + { + name: "ChargingTargetScheduleStruct", type: "struct", + details: "This represents a set of user specified charging targets for an EV for a set of specified days.", + xref: { document: "cluster", section: "9.3.7.7" } + }, + + Field({ + name: "DayOfWeekForSequence", id: 0x0, type: "TargetDayOfWeekBitmap", conformance: "M", + details: "This field shall indicate the days of the week that the charging targets SHOULD be associated to. " + + "This field is a bitmap and therefore the associated targets could be applied to multiple days.", + xref: { document: "cluster", section: "9.3.7.8" } + }), + + Field( + { + name: "ChargingTargets", id: 0x1, type: "list", conformance: "M", constraint: "max 10", + details: "This field shall indicate a list of up to 10 charging targets for each of the associated days of " + + "the week.", + xref: { document: "cluster", section: "9.3.7.9" } + }, + + Field({ name: "entry", type: "ChargingTargetStruct" }) + ) + ) + ), + + Cluster( + { + name: "EnergyEvseMode", id: 0x9d, type: "ModeBase", classification: "application", pics: "EEVSEM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for EVSE devices.", + xref: { document: "cluster", section: "9.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.4.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + + details: "At least one entry in the SupportedModes attribute shall include the Manual mode tag in the " + + "ModeTags field list." + + "\n" + + "Modes with entries in the SupportedModes attribute which contain multiple mode tags permitting" + + "\n" + + "charging or discharging under different conditions shall permit the charging or discharging to " + + "occur if any of the conditions are satisfied." + + "\n" + + "Modes shall NOT have both the Manual tag and the TimeOfUse or SolarCharging tags defined in the " + + "SupportedModes attribute.", + + xref: { document: "cluster", section: "9.4.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "9.4.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "9.4.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "9.4.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "9.4.5.1" } + }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "9.4.7.1" } }), + + Field({ + name: "Manual", id: 0x4000, + details: "While in modes with this tag, and once enabled with the EnableCharging command, the EVSE will " + + "permit charging based on demand from the EV.", + xref: { document: "cluster", section: "9.4.7.1.1" } + }), + + Field({ + name: "TimeOfUse", id: 0x4001, + details: "While in modes with this tag, and once enabled with the EnableCharging command, the EVSE will " + + "attempt to automatically start charging based on the user’s charging targets (for example, set " + + "based on a Time of Use tariff to charge at the cheapest times of the day).", + xref: { document: "cluster", section: "9.4.7.1.2" } + }), + + Field({ + name: "SolarCharging", id: 0x4002, + details: "While in modes with this tag, and once enabled with the EnableCharging, the EVSE will attempt to" + + "\n" + + "automatically start charging based on available excess solar PV generation, limiting the charging " + + "power to avoid importing energy from the grid.", + xref: { document: "cluster", section: "9.4.7.1.3" } + }), + + Field({ + name: "V2X", id: 0x4003, + + details: "While in modes with this tag, and once enabled with the EnableDischarging command, the EVSE will " + + "permit discharging based on the current charge state of the EV, and its control from an associated " + + "Device Energy Management cluster." + + "\n" + + "NOTE" + + "\n" + + "being in a mode with this tag set or not does not affect the handling of the EnableDischarging " + + "command by the Energy EVSE cluster, but once enabled, only modes with this tag enable the " + + "discharging to actually occur.", + + xref: { document: "cluster", section: "9.4.7.1.4" } + }) + ) + ), + + Cluster( + { + name: "WaterHeaterManagement", id: 0x94, classification: "application", pics: "EWATERHTR", + + details: "This cluster is used to allow clients to control the operation of a hot water heating appliance so " + + "that it can be used with energy management." + + "\n" + + "Heating of hot water is one of the main energy uses in homes, and when coupled with the Energy " + + "Management cluster, it can help consumers save cost (e.g. using power at cheaper times or from " + + "local solar PV generation).", + + xref: { document: "cluster", section: "9.5" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.5.4" } }, + Field({ + name: "EM", conformance: "O", constraint: "0", description: "EnergyManagement", + details: "Allows energy management control of the tank" + }), + Field({ + name: "TP", conformance: "O", constraint: "1", description: "TankPercent", + details: "Supports monitoring the percentage of hot water in the tank" + }) + ), + + Attribute({ + name: "HeaterTypes", id: 0x0, type: "WaterHeaterHeatSourceBitmap", access: "R V", conformance: "M", + default: 0, quality: "F", + details: "Indicates the heat sources that the water heater can call on for heating. If a bit is set then the " + + "water heater supports the corresponding heat source.", + xref: { document: "cluster", section: "9.5.7.1" } + }), + + Attribute({ + name: "HeatDemand", id: 0x1, type: "WaterHeaterHeatSourceBitmap", access: "R V", conformance: "M", + default: 0, + details: "Indicates if the water heater is heating water. If a bit is set then the corresponding heat source " + + "is active.", + xref: { document: "cluster", section: "9.5.7.2" } + }), + + Attribute({ + name: "TankVolume", id: 0x2, type: "uint16", access: "R V", conformance: "EM", default: 0, + details: "Indicates the volume of water that the hot water tank can hold (in units of Litres). This allows an " + + "energy management system to estimate the required heating energy needed to reach the target " + + "temperature.", + xref: { document: "cluster", section: "9.5.7.3" } + }), + + Attribute( + { + name: "EstimatedHeatRequired", id: 0x3, type: "energy-mWh", access: "R V", conformance: "EM", + constraint: "min 0", default: 0, + + details: "Indicates the estimated heat energy needed to raise the water temperature to the target setpoint. " + + "This can be computed by taking the specific heat capacity of water (4182 J/kg °C) and by knowing " + + "the current temperature of the water, the tank volume and target temperature." + + "\n" + + "For example, if the target temperature was 60°C, the current temperature was 20°C and the tank " + + "volume was 100L:" + + "\n" + + "Mass of water = 1kg per Litre" + + "\n" + + "Total Mass = 100 x 1kg = 100kg" + + "\n" + + "Δ Temperature = (target temperature - current temperature)" + + "\n" + + "= (60°C - 20°C) = 40°C" + + "\n" + + "Energy required to" + + "\n" + + "heat the water to 60°C = 4182 x 40 x 100 = 16,728,000 J" + + "\n" + + "Converting Joules in to Wh of heat (divide by 3600):" + + "\n" + + "If the TankPercent feature is supported, then this estimate shall also take into account the " + + "percentage of the water in the tank which is already hot." + + "\n" + + "NOTE" + + "\n" + + "The electrical energy required to heat the water depends on the heating system used to heat the " + + "water. For example, a direct electric immersion heating element can be close to 100% efficient, so " + + "the electrical energy needed to heat the hot water is nearly the same as the " + + "EstimatedHeatEnergyRequired. However some forms of heating, such as an air-source heat pump which " + + "extracts heat from ambient air, requires much less electrical energy to heat hot water. Heat pumps " + + "can be produce 3kWh of heat output for 1kWh of electrical energy input. The conversion between heat " + + "energy and electrical energy is outside the scope of this cluster.", + + xref: { document: "cluster", section: "9.5.7.4" } + } + ), + + Attribute( + { + name: "TankPercentage", id: 0x4, type: "percent", access: "R V", conformance: "TP", default: 0, + + details: "Indicates an approximate level of hot water stored in the tank, which might help consumers " + + "understand the amount of hot water remaining in the tank. The accuracy of this attribute is " + + "manufacturer specific." + + "\n" + + "In most hot water tanks, there is a stratification effect where the hot water layer rests above a " + + "cooler layer of water below. For this reason cold water is fed in at the bottom of the tank and the " + + "hot water is drawn from the top." + + "\n" + + "Some water tanks might use multiple temperature probes to estimate the level of the hot water " + + "layer. A water heater with multiple temperature probes is likely to implement an algorithm to " + + "estimate the hot water tank percentage by taking into account the temperature values of each probe " + + "to determine the height of the hot water." + + "\n" + + "However it might be possible with a single temperature probe to estimate how much hot water is left " + + "using a simpler algorithm:" + + "\n" + + "For example, if the target temperature was 60°C, the CurrentTemperature was 40°C from a single " + + "temperature probe measuring the average water temperature and the temperature of incoming cold " + + "water (COLD_WATER_TEMP) was assumed to be 20°C:" + + "\n" + + "TankPercentage = int(((current temperature - COLD_WATER_TEMP) / (target temperature - " + + "COLD_WATER_TEMP)) * 100)" + + "\n" + + "TankPercentage = min( max(TankPercentage,0), 100)" + + "\n" + + "TankPercentage = 50%", + + xref: { document: "cluster", section: "9.5.7.5" } + } + ), + + Attribute({ + name: "BoostState", id: 0x5, type: "BoostStateEnum", access: "R V", conformance: "M", default: 0, + details: "Indicates whether the Boost, as triggered by a Boost command, is currently" + + "\n" + + "Active or Inactive." + + "\n" + + "See Boost and CancelBoost commands for more details.", + xref: { document: "cluster", section: "9.5.7.6" } + }), + + Event( + { + name: "BoostStarted", id: 0x0, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated whenever a Boost command is accepted." + + "\n" + + "The corresponding structure fields within the WaterHeaterBoostInfoStruct are copied from the Boost " + + "command.", + xref: { document: "cluster", section: "9.5.9.1" } + }, + + Field({ name: "BoostInfo", id: 0x0, type: "WaterHeaterBoostInfoStruct", conformance: "M" }) + ), + + Event({ + name: "BoostEnded", id: 0x1, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated whenever the BoostState transitions from Active to Inactive.", + xref: { document: "cluster", section: "9.5.9.2" } + }), + + Command( + { + name: "Boost", id: 0x0, access: "M", conformance: "M", direction: "request", response: "status", + details: "Allows a client to request that the water heater is put into a Boost state.", + xref: { document: "cluster", section: "9.5.8.1" } + }, + Field({ name: "BoostInfo", id: 0x0, type: "WaterHeaterBoostInfoStruct", conformance: "M" }) + ), + + Command({ + name: "CancelBoost", id: 0x1, access: "M", conformance: "M", direction: "request", + response: "status", + details: "Allows a client to cancel an ongoing Boost operation. This command has no payload.", + xref: { document: "cluster", section: "9.5.8.2" } + }), + + Datatype( + { name: "WaterHeaterHeatSourceBitmap", type: "map8", xref: { document: "cluster", section: "9.5.6.1" } }, + Field({ name: "ImmersionElement1", constraint: "0", description: "Immersion Heating Element 1" }), + Field({ name: "ImmersionElement2", constraint: "1", description: "Immersion Heating Element 2" }), + Field({ name: "HeatPump", constraint: "2", description: "Heat pump Heating" }), + Field({ name: "Boiler", constraint: "3", description: "Boiler Heating (e.g. Gas or Oil)" }), + Field({ name: "Other", constraint: "4", description: "Other Heating" }) + ), + + Datatype( + { name: "BoostStateEnum", type: "enum8", xref: { document: "cluster", section: "9.5.6.2" } }, + Field({ name: "Inactive", id: 0x0, conformance: "M", description: "Boost is not currently active" }), + Field({ name: "Active", id: 0x1, conformance: "M", description: "Boost is currently active" }) + ), + + Datatype( + { name: "WaterHeaterBoostInfoStruct", type: "struct", xref: { document: "cluster", section: "9.5.6.3" } }, + Field({ + name: "Duration", id: 0x0, type: "elapsed-s", conformance: "M", constraint: "min 1", + details: "This field shall indicate the time period, in seconds, for which the boost state is activated.", + xref: { document: "cluster", section: "9.5.6.3.1" } + }), + + Field({ + name: "OneShot", id: 0x1, type: "bool", conformance: "[!TP], [TP].a-", default: false, + + details: "This field shall indicate whether the boost state shall be automatically canceled once the hot " + + "water has reached either:" + + "\n" + + " • the set point temperature (from the thermostat cluster)" + + "\n" + + " • the TemporarySetpoint temperature (if specified)" + + "\n" + + " • the TargetPercentage (if specified).", + + xref: { document: "cluster", section: "9.5.6.3.2" } + }), + + Field({ + name: "EmergencyBoost", id: 0x2, type: "bool", conformance: "O", default: false, + details: "This field shall indicate that the consumer wants the water to be heated quickly. This may cause " + + "multiple heat sources to be activated (e.g. a heat pump and direct electric immersion heating " + + "element)." + + "\n" + + "The choice of which heat sources are activated is manufacturer specific.", + xref: { document: "cluster", section: "9.5.6.3.3" } + }), + + Field({ + name: "TemporarySetpoint", id: 0x3, type: "temperature", conformance: "O", constraint: "desc", + + details: "This field shall indicate the target temperature to which the water will be heated." + + "\n" + + "If included, it shall be used instead of the thermostat cluster set point temperature whilst the " + + "boost state is activated." + + "\n" + + "The value of this field shall be within the constraints of the MinHeatSetpointLimit and " + + "MaxHeatSetpointLimit attributes (inclusive), of the thermostat cluster.", + + xref: { document: "cluster", section: "9.5.6.3.4" } + }), + + Field({ + name: "TargetPercentage", id: 0x4, type: "percent", conformance: "TargetReheat, [TP]", + details: "This field shall indicate the target percentage of hot water in the tank that the TankPercentage " + + "attribute must reach before the heating is switched off.", + xref: { document: "cluster", section: "9.5.6.3.5" } + }), + + Field({ + name: "TargetReheat", id: 0x5, type: "percent", conformance: "[TP].a-", + constraint: "max targetPercentage", + + details: "This field shall indicate the percentage to which the hot water in the tank shall be allowed to " + + "fall before again beginning to reheat it." + + "\n" + + "For example if the TargetPercentage was 80%, and the TargetReheat was 40%, then after initial " + + "heating to 80% hot water, the tank may have hot water drawn off until only 40% hot water remains. " + + "At this point the heater will begin to heat back up to 80% of hot water. If this field and the " + + "OneShot field were both omitted, heating would begin again after any water draw which reduced the " + + "TankPercentage below 80%." + + "\n" + + "This field shall be less than or equal to the TargetPercentage field.", + + xref: { document: "cluster", section: "9.5.6.3.6" } + }) + ) + ), + + Cluster( + { + name: "WaterHeaterMode", id: 0x9e, type: "ModeBase", classification: "application", pics: "WHM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for water heater devices.", + xref: { document: "cluster", section: "9.6" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.6.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + + details: "At least one entry in the SupportedModes attribute shall include the Manual mode tag in the " + + "ModeTags field list." + + "\n" + + "At least one entry in the SupportedModes attribute shall include the Off mode tag in the ModeTags " + + "field list." + + "\n" + + "An entry in the SupportedModes attribute that includes one of an Off, Manual, or Timed tag shall " + + "NOT also include an additional instance of any one of these tag types.", + + xref: { document: "cluster", section: "9.6.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "9.6.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "9.6.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "9.6.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "9.6.5.1" } + }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ + name: "Off", id: 0x4000, + details: "While in modes with this tag, the device will not attempt to keep the water warm.", + xref: { document: "cluster", section: "9.6.7.1.1" } + }), + + Field({ + name: "Manual", id: 0x4001, + details: "While in modes with this tag, the device will attempt to keep the water warm based on the " + + "OccupiedHeatingSetpoint attribute of the associated Thermostat cluster.", + xref: { document: "cluster", section: "9.6.7.1.2" } + }), + + Field({ + name: "Timed", id: 0x4002, + details: "While in modes with this tag, the device will attempt to keep the water warm based on the Schedules " + + "attribute of the associated Thermostat cluster.", + xref: { document: "cluster", section: "9.6.7.1.3" } + }) + ) + ), + + Cluster( + { + name: "EnergyPreference", id: 0x9b, classification: "application", pics: "EPREF", + details: "This cluster provides an interface to specify preferences for how devices should consume energy." + + "\n" + + "NOTE Support for Energy Preference cluster is provisional.", + xref: { document: "cluster", section: "9.7" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.7.4" } }, + + Field({ + name: "BALA", conformance: "O.a+", constraint: "0", description: "EnergyBalance", + details: "This feature allows a user to select from a list of energy balances with associated descriptions of " + + "which strategies a device will use to target the specified balance.", + xref: { document: "cluster", section: "9.7.4.1" } + }), + + Field({ + name: "LPMS", conformance: "O.a+", constraint: "1", description: "LowPowerModeSensitivity", + details: "This feature allows the user to select a condition or set of conditions which will cause the device " + + "to switch to a mode using less power. For example, a device might provide a scale of durations that " + + "must elapse without user interaction before it goes to sleep.", + xref: { document: "cluster", section: "9.7.4.2" } + }) + ), + + Attribute( + { + name: "EnergyBalances", id: 0x0, type: "list", access: "R V", conformance: "BALA", + constraint: "2 to 10", quality: "F", + + details: "Indicates a list of BalanceStructs, each representing a step along a linear scale of relative " + + "priorities. A Step field with a value of zero shall indicate that the device SHOULD entirely favor " + + "the priority specified by the first element in EnergyPriorities; whereas a Step field with a value " + + "of 100 shall indicate that the device SHOULD entirely favor the priority specified by the second " + + "element in EnergyPriorities. The midpoint value of 50 shall indicate an even split between the two " + + "priorities." + + "\n" + + "This shall contain at least two BalanceStructs." + + "\n" + + "Each BalanceStruct shall have a Step field larger than the Step field on the previous BalanceStruct " + + "in the list." + + "\n" + + "The first BalanceStruct shall have a Step value of zero, and the last BalanceStruct shall have a " + + "Step value of 100.", + + xref: { document: "cluster", section: "9.7.6.1" } + }, + + Field({ name: "entry", type: "BalanceStruct" }) + ), + + Attribute({ + name: "CurrentEnergyBalance", id: 0x1, type: "uint8", access: "RW VO", conformance: "BALA", + quality: "N", + + details: "Indicates the current preference of the user for balancing different priorities during device use. " + + "The value of this attribute is the index, 0-based, into the EnergyBalances attribute for the " + + "currently selected balance." + + "\n" + + "If an attempt is made to set this attribute to an index outside the maximum index for " + + "EnergyBalances, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If the value of EnergyBalances changes after an update, the device shall migrate the value of the " + + "CurrentEnergyBalance attribute to the index which the manufacturer specifies most closely matches " + + "the previous value, while preserving extreme preferences as follows:" + + "\n" + + " 1. If the previous value of CurrentEnergyBalance was zero, indicating a total preference for the " + + " priority specified by the first element in EnergyPriorities, the new value of " + + " CurrentEnergyBalance shall also be zero." + + "\n" + + " 2. If the previous value of CurrentEnergyBalance was the index of the last BalanceStruct in the " + + " previous value of EnergyBalances, indicating a total preference for the priority specified by " + + " the last element in EnergyPriorities, the new value of CurrentEnergyBalance shall be the index " + + " of the last element in the updated value of EnergyBalances.", + + xref: { document: "cluster", section: "9.7.6.2" } + }), + + Attribute( + { + name: "EnergyPriorities", id: 0x2, type: "list", access: "R V", conformance: "BALA", + constraint: "2", quality: "F", + + details: "Indicates two extremes for interpreting the values in the EnergyBalances attribute. These two " + + "priorities shall be in opposition to each other; e.g. Comfort vs. Efficiency or Speed vs. " + + "WaterConsumption." + + "\n" + + "If the value of EnergyPriorities changes after an update to represent a new balance between " + + "priorities, the value of the CurrentEnergyBalance attribute shall be set to its default.", + + xref: { document: "cluster", section: "9.7.6.3" } + }, + + Field({ name: "entry", type: "EnergyPriorityEnum" }) + ), + + Attribute( + { + name: "LowPowerModeSensitivities", id: 0x3, type: "list", access: "R V", conformance: "LPMS", + constraint: "2 to 10", quality: "F", + details: "Indicates a list of BalanceStructs, each representing a condition or set of conditions for the " + + "device to enter a low power mode. This shall contain at least two BalanceStructs." + + "\n" + + "Each BalanceStruct shall have a Step field larger than the Step field on the previous BalanceStruct " + + "in the list.", + xref: { document: "cluster", section: "9.7.6.4" } + }, + + Field({ name: "entry", type: "BalanceStruct" }) + ), + + Attribute({ + name: "CurrentLowPowerModeSensitivity", id: 0x4, type: "uint8", access: "RW VO", + conformance: "LPMS", quality: "N", + + details: "Indicates the current preference of the user for determining when the device should enter a low " + + "power mode. The value of this attribute is the index, 0-based, into the LowPowerModeSensitivities " + + "attribute for the currently selected preference." + + "\n" + + "If an attempt is made to set this attribute to an index outside the maximum index for " + + "LowPowerModeSensitivities, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If the value of LowPowerModeSensitivities changes after an update, the device shall migrate the " + + "value of the LowPowerModeSensitivity attribute to the index which the manufacturer specifies most " + + "closely matches the previous value.", + + xref: { document: "cluster", section: "9.7.6.5" } + }), + + Datatype( + { name: "EnergyPriorityEnum", type: "enum8", xref: { document: "cluster", section: "9.7.5.1" } }, + Field({ + name: "Comfort", id: 0x0, conformance: "M", description: "User comfort", + details: "This value shall emphasize user comfort; e.g. local temperature for a thermostat.", + xref: { document: "cluster", section: "9.7.5.1.1" } + }), + + Field({ + name: "Speed", id: 0x1, conformance: "M", description: "Speed of operation", + details: "This value shall emphasize how quickly a device accomplishes its targeted use; e.g. how quickly a " + + "robot vacuum completes a cleaning cycle.", + xref: { document: "cluster", section: "9.7.5.1.2" } + }), + + Field({ + name: "Efficiency", id: 0x2, conformance: "M", + description: "Amount of Energy consumed by the device", + details: "This value shall emphasize how much energy a device uses; e.g. electricity usage for a Pump.", + xref: { document: "cluster", section: "9.7.5.1.3" } + }), + + Field({ + name: "WaterConsumption", id: 0x3, conformance: "M", + description: "Amount of water consumed by the device" + }) + ), + + Datatype( + { + name: "BalanceStruct", type: "struct", + details: "This represents a step along a scale of preferences.", + xref: { document: "cluster", section: "9.7.5.2" } + }, + Field({ + name: "Step", id: 0x0, type: "percent", conformance: "M", quality: "F", + details: "This field shall indicate the relative value of this step.", + xref: { document: "cluster", section: "9.7.5.2.1" } + }), + + Field({ + name: "Label", id: 0x1, type: "string", conformance: "O", constraint: "max 64", quality: "F", + details: "This field shall indicate an optional string explaining which actions a device might take at the " + + "given step value.", + xref: { document: "cluster", section: "9.7.5.2.2" } + }) + ) + ), + + Cluster( + { + name: "DeviceEnergyManagementMode", id: 0x9f, type: "ModeBase", classification: "application", + pics: "DEMM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for Device Energy Management devices.", + xref: { document: "cluster", section: "9.8" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.8.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + + details: "At least one entry in the SupportedModes attribute shall include the NoOptimization mode tag in the " + + "ModeTags field." + + "\n" + + "At least one entry in the SupportedModes attribute shall include the LocalOptimization mode tag in " + + "the ModeTags field list." + + "\n" + + "At least one entry in the SupportedModes attribute shall include the GridOptimization mode tag in " + + "the ModeTags field list." + + "\n" + + "An entry in the SupportedModes attribute that includes one of an DeviceOptimization, " + + "LocalOptimization, or GridOptimization tags shall NOT also include NoOptimization tag.", + + xref: { document: "cluster", section: "9.8.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "9.8.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "9.8.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "9.8.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "9.8.5.1" } + }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "9.8.7.1" } }), + + Field({ + name: "NoOptimization", id: 0x4000, + details: "The device prohibits optimization of energy usage management: its energy usage is determined only " + + "by the user configuration and internal device needs.", + xref: { document: "cluster", section: "9.8.7.1.1" } + }), + + Field({ + name: "DeviceOptimization", id: 0x4001, + details: "The device is permitted to manage its own energy usage. For example, using tariff information it " + + "may obtain.", + xref: { document: "cluster", section: "9.8.7.1.2" } + }), + + Field({ + name: "LocalOptimization", id: 0x4002, + details: "The device permits management of energy usage by an energy manager to optimize the local energy " + + "usage.", + xref: { document: "cluster", section: "9.8.7.1.3" } + }), + + Field({ + name: "GridOptimization", id: 0x4003, + details: "The device permits management of energy usage by an energy manager to optimize the grid energy " + + "usage.", + xref: { document: "cluster", section: "9.8.7.1.4" } + }) + ) + ), + + Cluster( + { + name: "WiFiNetworkManagement", id: 0x451, classification: "application", pics: "WIFINM", + details: "This cluster provides an interface for getting information about the Wi-Fi network that a Network " + + "Infrastructure Manager device type provides. Privileged nodes within the same fabric as a Network " + + "Infrastructure Manager can use these interfaces to request information related to the Wi-Fi Network " + + "such as SSID and Passphrase.", + xref: { document: "cluster", section: "10.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "Ssid", id: 0x0, type: "octstr", access: "R V", conformance: "M", constraint: "1 to 32", + default: null, quality: "X N", + + details: "Indicates the SSID of the primary Wi-Fi network provided by this device." + + "\n" + + "A value of null shall indicate that no primary Wi-Fi network is available (e.g. because the Wi-Fi " + + "network has not yet been configured by the user)." + + "\n" + + "NOTE" + + "\n" + + "The SSID in Wi-Fi is a collection of 1-32 bytes, the text encoding of which is not specified. " + + "Implementations must be careful to support transferring these byte strings without requiring a " + + "particular encoding. The most common encoding is UTF-8, however this is just a convention. Some " + + "configurations may use Latin-1 or other character sets.", + + xref: { document: "cluster", section: "10.2.4.1" } + }), + + Attribute({ + name: "PassphraseSurrogate", id: 0x1, type: "uint64", access: "R M", conformance: "M", + default: null, quality: "X N", + + details: "This attribute shall contain an arbitrary numeric value; this value shall increase whenever the " + + "passphrase or PSK associated with the primary Wi-Fi network provided by this device changes." + + "\n" + + "A value of null shall indicate that no primary Wi-Fi network is available." + + "\n" + + "Clients can subscribe to this attribute or compare its value to a locally cached copy to detect if " + + "a cached passphrase value has become stale." + + "\n" + + "It is recommended that servers implement this attribute as either a timestamp or a counter. When " + + "implemented as a counter it SHOULD be initialized with a random value." + + "\n" + + "NOTE" + + "\n" + + "The passphrase itself is not exposed as an attribute to avoid its unintentional retrieval or " + + "caching by clients that use wildcard reads or otherwise routinely read all available attributes. It " + + "can be retrieved using the NetworkPassphraseRequest" + + "\n" + + "command.", + + xref: { document: "cluster", section: "10.2.4.2" } + }), + + Command({ + name: "NetworkPassphraseRequest", id: 0x0, access: "M", conformance: "M", direction: "request", + response: "NetworkPassphraseResponse", + + details: "This command is used to request the current WPA-Personal passphrase or PSK associated with the " + + "Wi-Fi network provided by this device." + + "\n" + + "If the command is not executed via a CASE session, the command shall be rejected with a status of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "If no primary Wi-Fi network is available (the SSID attribute is null), the command shall be " + + "rejected with a status of INVALID_IN_STATE." + + "\n" + + "Otherwise a NetworkPassphraseResponse shall be generated.", + + xref: { document: "cluster", section: "10.2.5.1" } + }), + + Command({ + name: "NetworkPassphraseResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command shall be generated in response to a NetworkPassphraseRequest command.", + xref: { document: "cluster", section: "10.2.5.2" } + }) + ), + + Cluster( + { + name: "ThreadBorderRouterManagement", id: 0x452, classification: "application", pics: "TBRM", + details: "This cluster provides an interface for managing a Thread Border Router and the Thread network that " + + "it belongs to. Privileged nodes within the same fabric as a Thread Border Router can use these " + + "interfaces to request and set credentials information to the Thread network.", + xref: { document: "cluster", section: "10.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "10.3.4" } }, + + Field({ + name: "PC", conformance: "O", constraint: "0", description: "PanChange", + + details: "This feature shall indicate the ability of the Border Router to change its already configured PAN " + + "to another, by setting a pending dataset." + + "\n" + + "NOTE" + + "\n" + + "This feature flag can be used to protect an already-configured network from accidental " + + "configuration change, e.g. when the Thread Border Router serves non-Matter devices that do not " + + "support PAN change for an implementation-specific reason.", + + xref: { document: "cluster", section: "10.3.4.1" } + }) + ), + + Attribute({ + name: "BorderRouterName", id: 0x0, type: "string", access: "R V", conformance: "M", + constraint: "1 to 63", + details: "Indicates a user-friendly name identifying the device model or product of the Border Router in " + + "MeshCOP (DNS-SD service name) as defined in the Thread specification, and has the following " + + "recommended format: ._meshcop._udp. An example name would be ACME Border " + + "Router (74be)._meshcop._udp.", + xref: { document: "cluster", section: "10.3.5.1" } + }), + + Attribute({ + name: "BorderAgentId", id: 0x1, type: "octstr", access: "R V", conformance: "M", constraint: "16", + details: "Indicates a 16-byte globally unique ID for a Thread Border Router device. This ID is " + + "manufacturer-specific, and it is created and managed by the border router’s implementation.", + xref: { document: "cluster", section: "10.3.5.2" } + }), + + Attribute({ + name: "ThreadVersion", id: 0x2, type: "uint16", access: "R V", conformance: "M", quality: "F", + details: "Indicates the Thread version supported by the Thread interface configured by the cluster instance." + + "\n" + + "The format shall match the value mapping defined in the \"Version TLV\" section of the Thread " + + "specification. For example, Thread 1.3.0 would have ThreadVersion set to 4.", + xref: { document: "cluster", section: "10.3.5.3" } + }), + + Attribute({ + name: "InterfaceEnabled", id: 0x3, type: "bool", access: "R V", conformance: "M", default: false, + quality: "N", + details: "Indicates whether the associated IEEE 802.15.4 Thread interface is enabled or disabled.", + xref: { document: "cluster", section: "10.3.5.4" } + }), + + Attribute({ + name: "ActiveDatasetTimestamp", id: 0x4, type: "uint64", access: "R V", conformance: "M", + default: 0, quality: "X N", + details: "Null if the Thread Border Router has no dataset configured, otherwise it shall be the timestamp " + + "value extracted from the Active Dataset value configured by the Thread Node to which the border " + + "router is connected. This attribute shall be updated when a new Active dataset is configured on the " + + "Thread network to which the border router is connected.", + xref: { document: "cluster", section: "10.3.5.5" } + }), + + Attribute({ + name: "PendingDatasetTimestamp", id: 0x5, type: "uint64", access: "R V", conformance: "M", + default: 0, quality: "X N", + details: "Null if the Thread Border Router has no Pending dataset configured, otherwise it shall be the " + + "timestamp value extracted from the Pending Dataset value configured by the Thread Node to which the " + + "border router is connected. This attribute shall be updated when a new Pending dataset is " + + "configured on the Thread network to which the border router is connected.", + xref: { document: "cluster", section: "10.3.5.6" } + }), + + Command({ + name: "GetActiveDatasetRequest", id: 0x0, access: "M", conformance: "M", direction: "request", + response: "DatasetResponse", + + details: "This command shall be used to request the active operational dataset of the Thread network to which " + + "the border router is connected." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "If an internal error occurs, then this command shall fail with a FAILURE status code sent back to " + + "the initiator." + + "\n" + + "Otherwise, this shall generate a DatasetResponse command.", + + xref: { document: "cluster", section: "10.3.6.1" } + }), + + Command({ + name: "GetPendingDatasetRequest", id: 0x1, access: "M", conformance: "M", direction: "request", + response: "DatasetResponse", + + details: "This command shall be used to request the pending dataset of the Thread network to which the border " + + "router is connected." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "If an internal error occurs, then this command shall fail with a FAILURE status code sent back to " + + "the initiator." + + "\n" + + "Otherwise, this shall generate a DatasetResponse command.", + + xref: { document: "cluster", section: "10.3.6.2" } + }), + + Command( + { + name: "DatasetResponse", id: 0x2, conformance: "M", direction: "response", + details: "This command is sent in response to GetActiveDatasetRequest or GetPendingDatasetRequest command.", + xref: { document: "cluster", section: "10.3.6.3" } + }, + + Field({ + name: "Dataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254", + details: "If no dataset (active or pending as requested) is configured, this field shall be set to empty." + + "\n" + + "Otherwise, this field shall contain the active or pending dataset of the Thread network to which " + + "the Border Router is connected as an octet string containing the raw Thread TLV value of the " + + "dataset, as defined in the Thread specification.", + xref: { document: "cluster", section: "10.3.6.3.1" } + }) + ), + + Command( + { + name: "SetActiveDatasetRequest", id: 0x3, access: "M T", conformance: "M", direction: "request", + response: "status", + details: "This command shall be used to set the active Dataset of the Thread network to which the Border " + + "Router is connected, when there is no active dataset already.", + xref: { document: "cluster", section: "10.3.6.4" } + }, + + Field({ + name: "ActiveDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254", + details: "This field shall contain the active dataset to set of the Thread network to configure in the Border " + + "Router as an octet string containing the raw Thread TLV value of the dataset, as defined in the " + + "Thread specification.", + xref: { document: "cluster", section: "10.3.6.4.1" } + }), + + Field({ + name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", + details: "See Breadcrumb Attribute section of General Commissioning Cluster in [MatterCore] for usage.", + xref: { document: "cluster", section: "10.3.6.4.2" } + }) + ), + + Command( + { + name: "SetPendingDatasetRequest", id: 0x4, access: "M T", conformance: "PC", direction: "request", + response: "status", + + details: "This command shall be used to set or update the pending Dataset of the Thread network to which the " + + "Border Router is connected, if the Border Router supports PAN Change." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "This PendingDataset field shall contain the pending dataset to which the Thread network should be " + + "updated. The format of the data shall be an octet string containing the raw Thread TLV value of the " + + "pending dataset, as defined in the Thread specification." + + "\n" + + "If any of the parameters in the PendingDataset is invalid, the command shall fail with a status of " + + "INVALID_COMMAND." + + "\n" + + "Otherwise, this command shall configure the pending dataset of the Thread network to which the " + + "Border Router is connected, with the value given in the PendingDataset parameter. The Border Router " + + "will manage activation of the pending dataset as defined in the Thread specification.", + + xref: { document: "cluster", section: "10.3.6.5" } + }, + + Field({ name: "PendingDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254" }) + ) + ), + + Cluster( + { + name: "ThreadNetworkDirectory", id: 0x453, classification: "application", pics: "THNETDIR", + details: "This cluster stores a list of Thread networks (including the credentials required to access each " + + "network), as well as a designation of the user’s preferred network, to facilitate the sharing of " + + "Thread networks across fabrics.", + xref: { document: "cluster", section: "10.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "PreferredExtendedPanId", id: 0x0, type: "octstr", access: "RW VM", conformance: "M", + constraint: "8", default: null, quality: "X N", + + details: "Indicates the Thread Extended PAN ID value for the Thread network designated by the user to be " + + "their preferred network for commissioning of Thread devices. If not null, the value of this " + + "attribute shall match the ExtendedPanID of a network in the ThreadNetworks attribute. A write " + + "operation with a non-null value that does not match any network in the ThreadNetworks list shall be " + + "rejected with a status of CONSTRAINT_ERROR." + + "\n" + + "The purpose of designating one Thread network as preferred is to help a commissioner to select a " + + "Thread network when a Thread device is within suitable range of more than one Thread network which " + + "appears in the ThreadNetworks list. A value of null indicates that there is no current preferred " + + "network: All networks may be treated as equally preferred by a commissioner with access to this " + + "cluster." + + "\n" + + "This attribute may be automatically set to the ExtendedPanID of the first Thread network added to " + + "the ThreadNetworks list." + + "\n" + + "A client shall obtain user consent before changing the value of this attribute from a non-null " + + "value." + + "\n" + + "On a factory reset this attribute shall be reset to null.", + + xref: { document: "cluster", section: "10.4.5.1" } + }), + + Attribute( + { + name: "ThreadNetworks", id: 0x1, type: "list", access: "R V", conformance: "M", + constraint: "max threadNetworkTableSize", quality: "N", + + details: "Indicates the list of Thread Networks known about by this cluster. If the node hosting this cluster " + + "includes a Thread Border Router, then an entry for its Thread Network shall be included in this " + + "list." + + "\n" + + "The list can be modified via the AddNetwork and RemoveNetwork commands." + + "\n" + + "For each entry in the list, the cluster server also stores a Thread Operational Dataset. Clients " + + "use the GetOperationalDataset command to obtain the Operational Dataset for an entry in this list." + + "\n" + + "On a factory reset this list shall be cleared, and any Thread Operational datasets previously " + + "stored shall be removed from the Node.", + + xref: { document: "cluster", section: "10.4.5.2" } + }, + + Field({ name: "entry", type: "ThreadNetworkStruct" }) + ), + + Attribute({ + name: "ThreadNetworkTableSize", id: 0x2, type: "uint8", access: "R V", conformance: "M", + constraint: "desc", default: 10, quality: "F", + details: "Indicates the maximum number of entries that can be held in the ThreadNetworks list; it shall be at " + + "least 2 times the number of SupportedFabrics advertised in the Operational Credentials Cluster on " + + "the root endpoint of this node.", + xref: { document: "cluster", section: "10.4.5.3" } + }), + + Command( + { + name: "AddNetwork", id: 0x0, access: "M T", conformance: "M", direction: "request", + response: "status", + details: "Adds an entry to the ThreadNetworks attribute with the specified Thread Operational Dataset." + + "\n" + + "If there is an existing entry with the Extended PAN ID then the Thread Operational Dataset for that " + + "entry is replaced. As a result, changes to the network parameters (e.g. Channel, Network Name, " + + "PSKc, …) of an existing entry with a given Extended PAN ID can be made using this command.", + xref: { document: "cluster", section: "10.4.6.1" } + }, + + Field({ + name: "OperationalDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254", + details: "This field shall represent the Operational Dataset for the network, using the encoding defined in " + + "the Thread specification. It shall contain at least the following sub-TLVs: Active Timestamp, " + + "Channel, Channel Mask, Extended PAN ID, Network Key, Network Mesh-Local Prefix, Network Name, PAN " + + "ID, PSKc, and Security Policy.", + xref: { document: "cluster", section: "10.4.6.1.1" } + }) + ), + + Command( + { + name: "RemoveNetwork", id: 0x1, access: "M T", conformance: "M", direction: "request", + response: "status", + details: "Removes the network with the given Extended PAN ID from the ThreadNetworks attribute.", + xref: { document: "cluster", section: "10.4.6.2" } + }, + + Field({ name: "ExtendedPanId", id: 0x0, type: "octstr", conformance: "M", constraint: "8" }) + ), + + Command( + { + name: "GetOperationalDataset", id: 0x2, access: "M", conformance: "M", direction: "request", + response: "OperationalDatasetResponse", + details: "Retrieves the Thread Operational Dataset with the given Extended PAN ID.", + xref: { document: "cluster", section: "10.4.6.3" } + }, + + Field({ name: "ExtendedPanId", id: 0x0, type: "octstr", conformance: "M", constraint: "8" }) + ), + + Command( + { + name: "OperationalDatasetResponse", id: 0x3, conformance: "M", direction: "response", + details: "Contains the Thread Operational Dataset for the Extended PAN specified in GetOperationalDataset.", + xref: { document: "cluster", section: "10.4.6.4" } + }, + Field({ name: "OperationalDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254" }) + ), + + Datatype( + { + name: "ThreadNetworkStruct", type: "struct", + details: "Represents the data associated with a Thread Network.", + xref: { document: "cluster", section: "10.4.4.1" } + }, + + Field({ + name: "ExtendedPanId", id: 0x0, type: "octstr", conformance: "M", constraint: "8", + details: "This field shall indicate the Extended PAN ID from the OperationalDataset for the given Thread " + + "network.", + xref: { document: "cluster", section: "10.4.4.1.1" } + }), + + Field({ + name: "NetworkName", id: 0x1, type: "string", conformance: "M", constraint: "1 to 16", + details: "This field shall indicate the Network Name from the OperationalDataset for the given Thread network.", + xref: { document: "cluster", section: "10.4.4.1.2" } + }), + Field({ + name: "Channel", id: 0x2, type: "uint16", conformance: "M", + details: "This field shall indicate the Channel from the OperationalDataset for the given Thread network.", + xref: { document: "cluster", section: "10.4.4.1.3" } + }), + + Field({ + name: "ActiveTimestamp", id: 0x3, type: "uint64", conformance: "M", + details: "This field shall indicate the Active Timestamp from the OperationalDataset for the given Thread " + + "network.", + xref: { document: "cluster", section: "10.4.4.1.4" } + }) + ) + ), + + Attribute({ + name: "ClusterRevision", id: 0xfffd, type: "uint16", access: "R V", conformance: "M", + constraint: "min 1", isSeed: true, quality: "F", + + details: "The ClusterRevision attribute indicates the revision of the server cluster specification supported " + + "by the cluster instance. An implementation of a cluster specification before the ClusterRevision " + + "attribute was added shall have an assumed cluster revision of 0 (zero). For a new cluster " + + "specification, the initial value for the ClusterRevision attribute shall be 1 (not zero)." + + "\n" + + "A history of revision numbers for a cluster specification release is listed in the Revision History " + + "section for a cluster specification. Each new revision of a cluster specification shall specify a " + + "new revision number incremented (by 1) from the last. The highest revision number in a cluster " + + "specification’s Revision History is the revision number for the cluster specification. Therefore, a " + + "ClusterRevision attribute value shall be the (highest) revision number of the cluster specification " + + "that has been implemented.", + + xref: { document: "core", section: "7.13.1" } + }), + + Attribute({ + name: "FeatureMap", id: 0xfffc, type: "map32", access: "R V", conformance: "M", default: 0, + isSeed: true, quality: "F", + + details: "Each instance of a cluster shall support this attribute." + + "\n" + + "The FeatureMap attribute shall indicate whether the server supports zero or more optional cluster " + + "features. A cluster feature is a set of cluster elements that are mandatory or optional for a " + + "defined feature of the cluster. If a cluster feature is supported by the cluster instance, then the " + + "corresponding bit shall be set to 1, otherwise the bit shall be set to 0 (zero). All undefined bits " + + "in" + + "\n" + + "this attribute shall be set to 0 (zero)." + + "\n" + + "The set of cluster elements that are designated as mandatory (M) are implicitly part of the " + + "mandatory cluster feature set, and do not have a bit in the FeatureMap attribute." + + "\n" + + "A cluster specification shall support this attribute if the cluster supports features. If a cluster " + + "specification is revised to support features (and so this attribute), each bit in the FeatureMap " + + "attribute shall have a defined default value (1 or 0), to conform with the previous revision of the " + + "cluster specification, that did not support the FeatureMap attribute. The value of 1 means the " + + "feature elements were mandatory (M) in the previous revision. The value of 0 (zero) means the " + + "elements were optional in the previous revision." + + "\n" + + "Any newly created feature set of a cluster shall be dependent on that cluster." + + "\n" + + "Feature sets are revision controlled as part of a cluster using the ClusterRevision attribute. The " + + "cluster specification is the independent element that is revision controlled. A remote application " + + "reading the FeatureMap and ClusterRevision Attribute will then know exactly what features are " + + "supported in the cluster instance." + + "\n" + + "Each feature set shall be well defined within the cluster specification. Each feature shall be " + + "mapped to a short capitalized code name for the feature set to be referenced as a conformance tag " + + "in the cluster specification text, including the Conformance columns defining the elements of the " + + "cluster." + + "\n" + + "If a cluster defines more than 32 feature sets, then it will be necessary to add another feature " + + "bitmap attribute. Any client trying to reference the new feature set will know about the new " + + "bitmap, because it knows about the new feature set(s). Legacy products will not know about the new " + + "feature set nor the new bitmap." + + "\n" + + "For a cluster whose definition which does not define a FeatureMap, the server shall set this " + + "attribute to 0 (zero)." + + "\n" + + "Please see Feature Conformance for details on conformance.", + + xref: { document: "core", section: "7.13.2" } + }), + + Attribute( + { + name: "AttributeList", id: 0xfffb, type: "list", access: "R V", conformance: "M", isSeed: true, + quality: "F", + details: "Each instance of a cluster shall support this attribute. This attribute shall be a list of the " + + "attribute IDs of the attributes supported by the cluster instance.", + xref: { document: "core", section: "7.13.3" } + }, + + Field({ name: "entry", type: "attrib-id" }) + ), + + Attribute( + { name: "EventList", id: 0xfffa, conformance: "D", isSeed: true, xref: { document: "core", section: "7.13" } } + ), + + Attribute( + { + name: "AcceptedCommandList", id: 0xfff9, type: "list", access: "R V", conformance: "M", + isSeed: true, quality: "F", + + details: "This attribute is a list of client generated commands which are supported by this cluster server " + + "instance." + + "\n" + + "Each instance of a cluster shall support this attribute." + + "\n" + + "This attribute shall be a list of the command IDs for client generated commands that are supported " + + "and processed by the server." + + "\n" + + "For each client request command in this list that mandates a response from the server, the" + + "\n" + + "response command shall be indicated in the GeneratedCommandList attribute." + + "\n" + + "If any attribute on a server supports atomic writes, this attribute shall contain the command ID " + + "for AtomicRequest.", + + xref: { document: "core", section: "7.13.4" } + }, + + Field({ name: "entry", type: "command-id" }) + ), + + Attribute( + { + name: "GeneratedCommandList", id: 0xfff8, type: "list", access: "R V", conformance: "M", + isSeed: true, quality: "F", + + details: "This attribute is a list of server generated commands. A server generated command is a server to " + + "client command." + + "\n" + + "Each instance of a cluster shall support this attribute." + + "\n" + + "This attribute shall be a list of the command IDs for server generated commands." + + "\n" + + "For each command in this list that is a response to a client command request, the request command " + + "shall be indicated in the AcceptedCommandList attribute." + + "\n" + + "If any attribute on a server supports atomic writes, this attribute shall contain the command ID " + + "for AtomicResponse.", + + xref: { document: "core", section: "7.13.5" } + }, + + Field({ name: "entry", type: "command-id" }) + ), + + Field({ + name: "FabricIndex", id: 0xfe, type: "fabric-idx", access: "R F V", conformance: "M", + constraint: "1 to 254", isSeed: true, + + details: "This field shall be present for fabric-scoped data. This field does not have to be defined " + + "explicitly in the field table for fabric-scoped data." + + "\n" + + "This field shall NOT be present in a write interaction. For a write interaction, the server shall " + + "provide the value of the accessing fabric-index as the FabricIndex field value to processing logic, " + + "after receipt of the interaction. For a read interaction this field shall be included in all " + + "reported data that is defined as fabric-scoped.", + + xref: { document: "core", section: "7.13.6" } + }), + + Datatype( + { name: "AtomicRequestTypeEnum", type: "enum8", xref: { document: "core", section: "7.15.4" } }, + Field({ name: "BeginWrite", id: 0x0, conformance: "M", description: "Begin an atomic write" }), + Field({ name: "CommitWrite", id: 0x1, conformance: "M", description: "Commit an atomic write" }), + Field({ + name: "RollbackWrite", id: 0x2, conformance: "M", + description: "Rollback an atomic write, discarding any pending changes" + }) + ), + + Datatype( + { + name: "AtomicAttributeStatusStruct", type: "struct", + details: "This struct indicates the status of an attribute during an atomic write.", + xref: { document: "core", section: "7.15.5" } + }, + Field({ + name: "AttributeId", id: 0x0, type: "attrib-id", conformance: "M", + details: "This field shall indicate the ID of the attribute with the associated StatusCode.", + xref: { document: "core", section: "7.15.5.1" } + }), + Field({ + name: "StatusCode", id: 0x1, type: "status", conformance: "M", + details: "This field shall indicate the atomic status of an attribute.", + xref: { document: "core", section: "7.15.5.2" } + }) + ), + + Datatype({ + name: "bool", description: "Boolean", isSeed: true, metatype: "boolean", + details: "The Boolean type represents a logical value, either FALSE or TRUE." + + "\n" + + " • FALSE shall be equivalent to the value 0 (zero)." + + "\n" + + " • TRUE shall be equivalent to the value 1 (one).", + xref: { document: "core", section: "7.19.1.1" } + }), + + Datatype({ + name: "map8", byteSize: 1, description: "8-bit bitmap", isSeed: true, metatype: "bitmap", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "map16", byteSize: 2, description: "16-bit bitmap", isSeed: true, metatype: "bitmap", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "map32", byteSize: 4, description: "32-bit bitmap", isSeed: true, metatype: "bitmap", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "map64", byteSize: 8, description: "64-bit bitmap", isSeed: true, metatype: "bitmap", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "uint8", byteSize: 1, description: "Unsigned 8-bit integer", isSeed: true, + metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "uint16", byteSize: 2, description: "Unsigned 16-bit integer", isSeed: true, + metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "uint24", byteSize: 3, description: "Unsigned 24-bit integer", isSeed: true, + metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "uint32", byteSize: 4, description: "Unsigned 32-bit integer", isSeed: true, + metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "uint40", byteSize: 5, description: "Unsigned 40-bit integer", isSeed: true, + metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "uint48", byteSize: 6, description: "Unsigned 48-bit integer", isSeed: true, + metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "uint56", byteSize: 7, description: "Unsigned 56-bit integer", isSeed: true, + metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "uint64", byteSize: 8, description: "Unsigned 64-bit integer", isSeed: true, + metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "int8", byteSize: 1, description: "Signed 8-bit integer", isSeed: true, metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "int16", byteSize: 2, description: "Signed 16-bit integer", isSeed: true, metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "int24", byteSize: 3, description: "Signed 24-bit integer", isSeed: true, metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "int32", byteSize: 4, description: "Signed 32-bit integer", isSeed: true, metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "int40", byteSize: 5, description: "Signed 40-bit integer", isSeed: true, metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "int48", byteSize: 6, description: "Signed 48-bit integer", isSeed: true, metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "int56", byteSize: 7, description: "Signed 56-bit integer", isSeed: true, metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "int64", byteSize: 8, description: "Signed 64-bit integer", isSeed: true, metatype: "integer", + xref: { document: "core", section: "7.19.1" } + }), + Datatype({ + name: "single", byteSize: 4, description: "Single precision", isSeed: true, metatype: "float", + xref: { document: "core", section: "7.19.1" } + }), + + Datatype({ + name: "double", byteSize: 8, description: "Double precision", isSeed: true, metatype: "float", + + details: "The double precision number format is based on the IEEE 754-2019 double precision (64-bit) format " + + "for binary floating-point arithmetic." + + "\n" + + "The format and interpretation of values of this data type follow the same rules as given for the " + + "single precision data type, but with wider mantissa and exponent ranges." + + "\n" + + "See IEEE 754-2019 for more details on the representable values.", + + xref: { document: "core", section: "7.19.1.6" } + }), + + Datatype({ + name: "octstr", description: "Octet string", isSeed: true, metatype: "bytes", + details: "The octet string data type defines a sequence of octets with a finite octet count from 0 to 65534. " + + "It is recommended to define a constraint on the maximum possible count.", + xref: { document: "core", section: "7.19.1.7" } + }), + + Datatype({ + name: "list", description: "List", isSeed: true, metatype: "array", + + details: "A list is defined as a collection of entries of the same data type, with a finite count from 0 to " + + "65534. A cluster specification may define further constraints on the maximum possible count. The " + + "list entry data type shall be any defined data type, except a list data type, or any data type " + + "derived from a list." + + "\n" + + "The quality columns for a list definition are for the list." + + "\n" + + "The list entries are indicated with an index that is an unsigned integer starting at 0 (zero). The " + + "maintained order of entries, by index, is defined in the cluster specification, or undefined. Data " + + "that is defined as a list is indicated with \"list[X]\" where X is the entry type. The data type of " + + "the list entry has its own qualities, constraints, and conformance." + + "\n" + + "### To define qualities for the list entry data type, make the list entry data type a defined local " + + "derived data type, with a table including the columns required to define and constrain the data " + + "type." + + "\n" + + "There is an inline shortcut to define the list entry data type constraints. See List Constraints." + + "\n" + + "It is recommended to put a maximum constraint on the list and list entry data types." + + "\n" + + "It is recommended that a list entry data type be a struct, to enable the addition of new fields to " + + "the list’s entries in the future." + + "\n" + + " • The cluster data version shall be incremented when the list order or entries change." + + "\n" + + " • An entry shall NOT be null." + + "\n" + + " • The list shall support reading and reporting all entries." + + "\n" + + " • The list shall support reporting, updates, and/or deletion of one or more entries." + + "\n" + + " • If the list is writable, it shall support writing or deleting the entire list." + + "\n" + + " • If the list is writable, it shall support updating one or more individual entries by indicating " + + " an index per updated entry." + + "\n" + + " • If the list is writable, it shall support deleting one or more individual entries by indicating " + + " an index per deleted entry." + + "\n" + + " • If the list is writable, it shall support adding one or more individual entries." + + "\n" + + " • A list may define an entry that is a struct that is fabric-scoped (see Fabric-Scoped Quality)." + + "\n" + + "### Fabric-Scoped List" + + "\n" + + " • A fabric-scoped list shall define an entry data type that is a struct, which shall also be " + + " fabric-scoped (see Fabric-Scoped Struct)." + + "\n" + + "Each entry in a fabric-scoped list shall be fabric-scoped to a particular fabric or no fabric." + + "\n" + + "### Fabric-Filtered List" + + "\n" + + "A fabric-scoped list supports a fabric-filter that filters the view of the list for read and write " + + "interactions. This filter simplifies client side logic that does not want to read or write fabric " + + "data that is not associated with the accessing fabric." + + "\n" + + " • An interaction upon a list with fabric-filtering shall only indicate and access entries where " + + " the associated fabric matches the accessing fabric, and all other entries shall be ignored." + + "\n" + + " • Fabric-filtered list entries shall be in the same order as the full list." + + "\n" + + " • Fabric-filtered list entries shall be indexed from 0 with no gaps, as if the other entries did " + + " not exist." + + "\n" + + " • For a write interaction, fabric-filtering shall be enabled." + + "\n" + + " • When writing to a fabric-scoped list, the write interaction shall be on an accessing fabric, " + + " otherwise, the write interaction shall fail (see Interaction Model)." + + "\n" + + " • For a read interaction on a list, fabric-filtering may be enabled." + + "\n" + + " • For a read interaction on a list, with fabric-filtering disabled, the list shall be reported as " + + " a full list with all entries.", + + xref: { document: "core", section: "7.19.1.8" } + }), + + Datatype({ + name: "struct", description: "Struct", isSeed: true, metatype: "object", + + details: "A struct is a sequence of fields of any data type. Individual fields are identified by a field ID " + + "of unsigned integer, starting at 0 (zero), for the first field." + + "\n" + + " • A struct itself shall have no constraint qualities." + + "\n" + + " • Each struct field shall have its own qualities." + + "\n" + + " • Access, conformance and persistence qualities, when not explicitly defined, shall be inherited " + + " from the instance of the struct itself." + + "\n" + + " • Struct fields may have optional conformance." + + "\n" + + " • A struct shall support reading and reporting of all fields." + + "\n" + + " • A struct shall support reporting changes to one or more fields." + + "\n" + + " • If the struct is writable, it shall support writing the entire struct." + + "\n" + + " • If a field of the struct is writable, the struct shall support updating the field." + + "\n" + + " • Because of optional struct field conformance, instances of the same struct may support multiple " + + " 'flavors' of the same struct data type, but with a different set of optional fields." + + "\n" + + "### Fabric-Scoped Struct" + + "\n" + + " • A fabric-scoped struct shall only be defined and occur as an entry in a fabric-scoped list." + + "\n" + + " • A fabric-scoped struct shall support the global FabricIndex field of type fabric-index, which " + + " indicates the associated fabric of the struct, or indicates that there is no associated fabric." + + "\n" + + " • The table that defines fields of a fabric-scoped struct shall NOT list the global FabricIndex " + + " field, which is a global field and defined implicitly." + + "\n" + + " • The global FabricIndex field of a fabric-scoped struct SHOULD NOT be indicated in a write " + + " interaction." + + "\n" + + " • The global FabricIndex field of a fabric-scoped struct shall be ignored in a write interaction." + + "\n" + + " • The global FabricIndex field SHOULD NOT be indicated on a fabric-scoped struct contained in the " + + " payload of a command request." + + "\n" + + " • The global FabricIndex field shall be ignored on a fabric-scoped struct contained in the " + + " payload of a command request." + + "\n" + + " • When a write interaction creates a fabric-scoped struct entry (in a fabric-scoped list), the " + + " server shall implicitly load the accessing fabric-index into the global FabricIndex field of " + + " the struct." + + "\n" + + " • When the payload of a command request contains a fabric-scoped struct, the server shall " + + " implicitly load the accessing fabric-index into the global FabricIndex field of the struct." + + "\n" + + "### • A fabric-scoped struct may be defined with some fields that are fabric-sensitive." + + "\n" + + " • For interactions on a fabric-scoped struct that report back data, fabric-sensitive struct " + + " fields shall NOT be indicated when reporting data back to the client, when the struct has an " + + " associated fabric, and it is not the accessing fabric.", + + xref: { document: "core", section: "7.19.1.9" } + }), + + Datatype({ + name: "percent", type: "uint8", description: "Percentage units 1%", isSeed: true, + xref: { document: "core", section: "7.19.2" } + }), + Datatype({ + name: "percent100ths", type: "uint16", description: "Percentage units 0.01%", isSeed: true, + xref: { document: "core", section: "7.19.2" } + }), + + Datatype({ + name: "tod", type: "struct", description: "Time of day", isSeed: true, + + details: "The Time of Day data type shall be a struct with these fields: Hours, Minutes, Seconds, and " + + "Hundredths." + + "\n" + + "The hours field represents hours according to a 24-hour clock. The range is from 0 to 23. The " + + "minutes field represents minutes of the current hour. The range is from 0 to 59. The seconds field " + + "represents seconds of the current minute. The range is from 0 to 59. The hundredths field " + + "represents 100ths of the current second. The range is from 0 to 99. A value of null in any subfield " + + "indicates an unused subfield. If all subfields have a value of null, this indicates a null time of " + + "day.", + + xref: { document: "core", section: "7.19.2.3" } + }), + + Datatype( + { + name: "date", type: "struct", description: "Date", isSeed: true, metatype: "date", + details: "This data type shall be a struct as defined below.", + xref: { document: "core", section: "7.19.2.4" } + }, + Field({ + name: "Year", id: 0x0, type: "uint8", conformance: "M", default: null, quality: "X", + details: "The year subfield represents years from 1900 (0) to 2155 (255).", + xref: { document: "core", section: "7.19.2.4.1" } + }), + + Field({ + name: "Month", id: 0x1, type: "uint8", conformance: "M", constraint: "1 to 12", default: null, + quality: "X", + details: "This field represents months January (1) to December (12).", + xref: { document: "core", section: "7.19.2.4.2" } + }), + + Field({ + name: "Day", id: 0x2, type: "uint8", conformance: "M", constraint: "1 to 31", default: null, + quality: "X", + details: "This field represents the day of the month. Note that values in the range 29 to 31 may be invalid, " + + "depending on the month and year.", + xref: { document: "core", section: "7.19.2.4.3" } + }), + + Field({ + name: "DayOfWeek", id: 0x3, type: "uint8", conformance: "M", constraint: "1 to 7", default: null, + quality: "X", + details: "This represents the day of the week from Monday (1) to Sunday (7).", + xref: { document: "core", section: "7.19.2.4.4" } + }) + ), + + Datatype( + { + name: "epoch-us", type: "uint64", description: "Epoch Time in microseconds", isSeed: true, + + details: "This type represents an offset, in microseconds, from 0 hours, 0 minutes, 0 seconds, on the 1st of " + + "January, 2000 UTC (the Epoch), encoded as an unsigned 64-bit scalar value." + + "\n" + + "This offset is the sum of two parts: time elapsed, not counting leap-seconds, and a local time " + + "offset. The local time offset may include a timezone offset and a may include a DST offset." + + "\n" + + "Any use of this type shall indicate how the associated local time offset is determined in the " + + "specific context of that use. This may be done, for example, by simply saying the time is a UTC " + + "time, in which case the local time offset is 0." + + "\n" + + "A given Epoch Time value may be interpreted in at least two ways:" + + "\n" + + " 1. The value can be converted to a local clock date/time (year, month, day, hours, minutes, " + + " seconds, microseconds) by treating the local time offset as 0 and finding the UTC (year, " + + " month, day, hours, minutes, seconds, microseconds) tuple that corresponds to an elapsed time " + + " since the epoch time equal to the given value. The value then represents that tuple, but " + + " interpreted in the specific timezone and DST situation associated with the value. This " + + " procedure does not require knowing the local time offset of the value." + + "\n" + + " 2. The value can be converted to a UTC time by subtracting the associated local time offset from " + + " the Epoch Time value and then treating the resulting value as an elapsed count of microseconds " + + " since the epoch time." + + "\n" + + "For example, an Epoch Time value of 0x0000_0BF1_B7E1_0000 corresponds to an offset of exactly 152 " + + "days. This can be interpreted as \"00:00:00 on June 1, 2000\" in whatever local time zone is " + + "associated with the value. That corresponds to the following times in ISO 8601 notation:" + + "\n" + + " • 2000-06-01T00:00Z if the associated local time offset is 0 (i.e. the value is in UTC)." + + "\n" + + " • 2000-05-31T23:00Z if the associated local time offset is +1 hour (e.g. the CET timezone, " + + " without daylight savings)." + + "\n" + + " • 2000-06-01T00:00+02 if the associated local time offset is +1 hour." + + "\n" + + " • 2000-06-01T04:00Z if the associated local time offset is -4 hours (e.g. the EDT time zone, " + + " which includes daylight savings)." + + "\n" + + " • 2000-06-01T00:00-04 if the associated local time offset is -4 hours." + + "\n" + + "Conversion from NTP timestamps" + + "\n" + + "Timestamps from NTP also do not count leap seconds, but have a different epoch. NTP 128-bit " + + "timestamps consist of a 64-bit seconds portion (NTP(s)) and a 64-bit fractional seconds portion " + + "(NTP(frac)). NTP(s) at 00:00:00 can be calculated from the Modified Julian Day (MJD) as follows:" + + "\n" + + "NTP(s) = (MJD-15020) * (24*60*60)" + + "\n" + + "where 15020 is the MJD on January 1, 1900 (the NTP epoch)" + + "\n" + + "NTP(s) on January 1, 2000 00:00:00 UTC (MJD = 51544) is 3155673600 (0xBC17C200)" + + "\n" + + "Epoch Time has a microsecond precision, and this precision can be achieved by using the most " + + "significant 32 bits of the fractional portion (NTP(frac32)). Conversion between the 128-bit NTP " + + "timestamps and a UTC Epoch Time in Microseconds is as follows:" + + "\n" + + "UTC Epoch Time = (NTP(s) - 0xBC17C200)*10^6 + ((NTP(frac32)*10^6) / 2^32) where all numbers are " + + "treated as unsigned 64-bit integers and the division is integer division.", + + xref: { document: "core", section: "7.19.2.5" } + } + ), + + Datatype({ + name: "epoch-s", type: "uint32", description: "Epoch Time in seconds", isSeed: true, + + details: "This type has the same semantics as Epoch Time in Microseconds, except that:" + + "\n" + + " • the value encodes an offset in seconds, rather than microseconds;" + + "\n" + + " • the value is encoded as an unsigned 32-bit scalar, rather than 64-bit." + + "\n" + + "This type is employed where compactness of representation is important and where the resolution of " + + "seconds is still satisfactory.", + + xref: { document: "core", section: "7.19.2.6" } + }), + + Datatype({ + name: "posix-ms", type: "uint64", description: "POSIX Time in milliseconds", isSeed: true, + details: "This type represents an offset, in milliseconds, from the UNIX epoch (1970-01-01 00:00:00 UTC), " + + "encoded as an unsigned 64-bit scalar value." + + "\n" + + "This type is employed for compatibility reasons.", + xref: { document: "core", section: "7.19.2.7" } + }), + + Datatype({ + name: "systime-us", type: "uint64", description: "System Time in microseconds", isSeed: true, + details: "System time in microseconds is an unsigned 64-bit value representing the number of microseconds " + + "since boot.", + xref: { document: "core", section: "7.19.2.8" } + }), + + Datatype({ + name: "systime-ms", type: "uint64", description: "System Time in milliseconds", isSeed: true, + details: "System time in milliseconds is an unsigned 64-bit value representing the number of milliseconds " + + "since boot." + + "\n" + + "This type is employed for compatibility reasons.", + xref: { document: "core", section: "7.19.2.9" } + }), + + Datatype({ + name: "elapsed-s", type: "uint32", description: "Elapsed Time in seconds", isSeed: true, + details: "Elapsed time in seconds is an unsigned 32-bit value representing the time that has elapsed for an " + + "operation or other activity, as determined by the definition of the attribute using this type.", + xref: { document: "core", section: "7.19.2.10" } + }), + + Datatype( + { + name: "temperature", type: "int16", description: "Temperature", isSeed: true, + + details: "This type represents a temperature on the Celsius scale with a resolution of 0.01°C." + + "\n" + + " • value = (temperature in °C) x 100" + + "\n" + + "The range is constrained by absolute zero: -273.15°C to 327.67°C." + + "\n" + + "Conversion of Temperature Values for Display" + + "\n" + + "When converting temperature values for display manufacturers SHOULD ensure that calculations" + + "\n" + + "round to the nearest representable value. Particular care is needed when using integer arithmetic." + + "\n" + + "Sample Conversion Code" + + "\n" + + "Sample code provided to ensure consistent Fahrenheit to Celsius and vice-versa conversion between " + + "devices and across vendors." + + "\n" + + "For degF: the value is a int8u representing 2x temperature value in Fahrenheit (to get 0.5 " + + "resolution)." + + "\n" + + "For degC: the value is a int16s representing Celsius in" + + "\n" + + "0.01 resolution as expected by the ZCL format.", + + xref: { document: "core", section: "7.19.2.11" } + } + ), + + Datatype({ + name: "power-mW", type: "int64", description: "Power", isSeed: true, + details: "This type represents power measured in milliwatts.", + xref: { document: "core", section: "7.19.2.12" } + }), + Datatype({ + name: "amperage-mA", type: "int64", description: "Amperage", isSeed: true, + details: "This type represents amperage measured in milliamps.", + xref: { document: "core", section: "7.19.2.13" } + }), + Datatype({ + name: "voltage-mV", type: "int64", description: "Voltage", isSeed: true, + details: "This type represents voltage measured in millivolts.", + xref: { document: "core", section: "7.19.2.14" } + }), + Datatype({ + name: "energy-mWh", type: "int64", description: "Energy", isSeed: true, + details: "This type represents energy measured in milliwatt-hours.", + xref: { document: "core", section: "7.19.2.15" } + }), + Datatype({ + name: "enum8", type: "uint8", description: "8-bit enumeration", isSeed: true, metatype: "enum", + xref: { document: "core", section: "7.19.2" } + }), + Datatype({ + name: "enum16", type: "uint16", description: "16-bit enumeration", isSeed: true, metatype: "enum", + xref: { document: "core", section: "7.19.2" } + }), + + Datatype( + { + name: "priority", type: "enum8", description: "Priority", isSeed: true, + details: "This is an enumeration of priority used to tag events and possibly other data. The data type does " + + "not define any particular ordering among the values. Specific uses of the data type may assign " + + "semantics to the values that imply an ordering relationship.", + xref: { document: "core", section: "7.19.2.17" } + }, + + Field({ name: "Debug", id: 0x0, description: "Information for engineering debugging/troubleshooting" }), + Field({ + name: "Info", id: 0x1, + description: "Information that either drives customer facing features or provides insights into device functions that are used to drive analytics use cases" + }), + Field({ + name: "Critical", id: 0x2, + description: "Information or notification that impacts safety, a critical function, or ongoing reliable operation of the node or application supported on an endpoint." + }) + ), + + Datatype( + { + name: "status", type: "enum8", description: "Status Code", isSeed: true, metatype: "enum", + + details: "An enumeration value that means a success or error status. A status code is indicated as a response " + + "to an action in an interaction (see Interaction Model)." + + "\n" + + "A status code shall be one of:" + + "\n" + + " • a common status code from the set defined in the Interaction Model status code table;" + + "\n" + + " • a cluster status code that is scoped to a particular cluster." + + "\n" + + "The following table defines the enumeration ranges for status codes." + + "\n" + + "Status codes in an undefined range, or status codes undefined within a range are reserved and shall " + + "NOT be indicated.", + + xref: { document: "core", section: "7.19.2.18" } + }, + + Field({ + name: "Success", id: 0x0, description: "Operation was successful.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "Failure", id: 0x1, description: "Operation was not successful.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "InvalidSubscription", id: 0x7d, description: "Subscription ID is not active.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedAccess", id: 0x7e, + description: "The sender of the action or command does not have authorization or access.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedEndpoint", id: 0x7f, + description: "The endpoint indicated is unsupported on the node.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "InvalidAction", id: 0x80, + description: "The action is malformed, has missing fields, or fields with invalid values. Action not carried out.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedCommand", id: 0x81, + description: "The indicated command ID is not supported on the cluster instance. Command not carried out.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "InvalidCommand", id: 0x85, + description: "The cluster command is malformed, has missing fields, or fields with invalid values. Command not carried out.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedAttribute", id: 0x86, + description: "The indicated attribute ID, field ID or list entry does not exist for an attribute path.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "ConstraintError", id: 0x87, + description: "Out of range error or set to a reserved value. Attribute keeps its old value. Note that an attribute value may be out of range if an attribute is related to another, e.g. with minimum and maximum attributes. See the individual attribute descriptions for specific details.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedWrite", id: 0x88, description: "Attempt to write a read-only attribute.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "ResourceExhausted", id: 0x89, + description: "An action or operation failed due to insufficient available resources.INSUFFICIENT_SPACE is anobsolete name for this error code.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "NotFound", id: 0x8b, description: "The indicated data field or entry could not be found.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnreportableAttribute", id: 0x8c, + description: "Reports cannot be issued for this attribute.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "InvalidDataType", id: 0x8d, + description: "The data type indicated is undefined or invalid for the indicated data field. Command or action not carried out.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedRead", id: 0x8f, description: "Attempt to read a write-only attribute.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "DataVersionMismatch", id: 0x92, + description: "Cluster instance data version did not match request path", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "Timeout", id: 0x94, description: "The transaction was aborted due to time being exceeded.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedNode", id: 0x9b, + description: "The node ID indicated is not supported on the node.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "Busy", id: 0x9c, + description: "The receiver is busy processing another action that prevents the execution of the incoming action.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "AccessRestricted", id: 0x9d, + description: "The access to the action or command by the sender is permitted by the ACL but restricted by the ARL.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedCluster", id: 0xc3, + description: "The cluster indicated is not supported on the endpoint.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "NoUpstreamSubscription", id: 0xc5, + description: "Used by proxies to convey to clients the lack of an upstream subscription to a source.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "NeedsTimedInteraction", id: 0xc6, + description: "A Untimed Write or Untimed Invoke interaction was used for an attribute or command that requires a Timed Write or Timed Invoke.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "UnsupportedEvent", id: 0xc7, + description: "The indicated event ID is not supported on the cluster instance.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "PathsExhausted", id: 0xc8, + description: "The receiver has insufficient resources to support the specified number of paths in the request", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "TimedRequestMismatch", id: 0xc9, + description: "A request with TimedRequest field set to TRUE was issued outside a Timed transaction or a request with TimedRequest set to FALSE was issued inside a Timed transaction.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "FailsafeRequired", id: 0xca, + description: "A request requiring a Fail-safe context was invoked without the Fail-Safe context.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "InvalidInState", id: 0xcb, + description: "The received request cannot be handled due to the current operational state of the device", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "NoCommandResponse", id: 0xcc, + description: "A CommandDataIB is missing a response in the InvokeResponses of an Invoke Response action.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "TermsAndConditionsChanged", id: 0xcd, + description: "The node requires updated TC acceptance. The user MAY be directed to visit the EnhancedSetupFlowMaintenanceUrl to complete this.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "MaintenanceRequired", id: 0xce, + description: "The node requires the user to visit the EnhancedSetupFlowMaintenanceUrl for instructions on further action.", + xref: { document: "core", section: "8.10.1" } + }) + ), + + Datatype({ + name: "group-id", type: "uint16", description: "Group ID", isSeed: true, + details: "A 16-bit ID for a group scoped to a particular fabric as indicated by an accompanying fabric index " + + "adjacent instantiation.", + xref: { document: "core", section: "7.19.2.22" } + }), + + Datatype({ + name: "endpoint-no", type: "uint16", description: "Endpoint Number", isSeed: true, + details: "An unsigned number that indicates an instance of a device type. Endpoint numbers shall NOT be " + + "0xFFFF, to allow all endpoint number values to be expressible in nullable endpoint-no fields.", + xref: { document: "core", section: "7.19.2.23" } + }), + + Datatype({ + name: "vendor-id", type: "uint16", description: "Vendor ID", isSeed: true, + details: "A Vendor ID." + + "\n" + + "Vendor IDs may be used as a prefix in a Manufacturer Extensible Identifier format.", + xref: { document: "core", section: "7.19.2.24" } + }), + + Datatype({ + name: "devtype-id", type: "uint32", description: "Device Type ID", isSeed: true, + details: "An identifier that indicates conformance to a device type." + + "\n" + + "Device Type IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation " + + "are described in Data Model Types.", + xref: { document: "core", section: "7.19.2.25" } + }), + + Datatype({ + name: "fabric-id", type: "uint64", description: "Fabric ID", isSeed: true, + details: "A value to identify a fabric.", + xref: { document: "core", section: "7.19.2.19" } + }), + + Datatype({ + name: "fabric-idx", type: "uint8", description: "Fabric Index", isSeed: true, + details: "This is an index that maps to a particular fabric on the node, see Fabric-Index. It is used for:" + + "\n" + + " • the accessing fabric index of an interaction" + + "\n" + + " • the FabricIndex global field in fabric-scoped data", + xref: { document: "core", section: "7.19.2.20" } + }), + + Datatype({ + name: "cluster-id", type: "uint32", description: "Cluster ID", isSeed: true, + details: "An identifier that indicates conformance to a cluster specification." + + "\n" + + "Cluster IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation are " + + "described in Data Model Types.", + xref: { document: "core", section: "7.19.2.26" } + }), + + Datatype({ + name: "attrib-id", type: "uint32", description: "Attribute ID", isSeed: true, + details: "An identifier that indicates an attribute defined in a cluster specification." + + "\n" + + "Attribute IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation " + + "are described in Data Model Types.", + xref: { document: "core", section: "7.19.2.27" } + }), + + Datatype({ + name: "field-id", type: "uint32", description: "Field ID", isSeed: true, + details: "An identifier that indicates a field defined in a struct." + + "\n" + + "Field IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation are " + + "described in Data Model Types.", + xref: { document: "core", section: "7.19.2.28" } + }), + + Datatype({ + name: "event-id", type: "uint32", description: "Event ID", isSeed: true, + details: "An identifier that indicates an Event defined in a cluster specification." + + "\n" + + "Event IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation are " + + "described in Data Model Types.", + xref: { document: "core", section: "7.19.2.29" } + }), + + Datatype({ + name: "command-id", type: "uint32", description: "Command ID", isSeed: true, + details: "An identifier that indicates a command defined in a cluster specification." + + "\n" + + "Command IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation are " + + "described in Data Model Types.", + xref: { document: "core", section: "7.19.2.30" } + }), + + Datatype({ + name: "action-id", type: "uint8", description: "Action ID", isSeed: true, + details: "An identifier that indicates an action as defined in the Interaction Model specification.", + xref: { document: "core", section: "7.19.2.31" } + }), + + Datatype({ + name: "trans-id", type: "uint32", description: "Transaction ID", isSeed: true, + details: "An identifier for a transaction as defined in the Interaction Model specification, see Transaction " + + "ID.", + xref: { document: "core", section: "7.19.2.32" } + }), + + Datatype({ + name: "node-id", type: "uint64", description: "Node ID", isSeed: true, + details: "A 64-bit ID for a node scoped and unique to a particular fabric as indicated by an accompanying " + + "fabric-index adjacent instantiation.", + xref: { document: "core", section: "7.19.2.21" } + }), + + Datatype({ + name: "entry-idx", type: "uint16", description: "Entry Index", isSeed: true, + details: "This is an index for a list data type.", + xref: { document: "core", section: "7.19.2.33" } + }), + Datatype({ + name: "data-ver", type: "uint32", description: "Data Version", isSeed: true, + details: "An unsigned number that indicates a Data Version Type.", + xref: { document: "core", section: "7.19.2.34" } + }), + Datatype({ + name: "event-no", type: "uint64", description: "Event Number", isSeed: true, + details: "An unsigned number that indicates an Event instance.", + xref: { document: "core", section: "7.19.2.35" } + }), + + Datatype({ + name: "string", type: "octstr", description: "Character String", isSeed: true, metatype: "string", + + details: "The character string data type is derived from an octet string. The octets shall be characters with " + + "UTF-8 encoding. An instance of this data type shall NOT contain truncated code points." + + "\n" + + "Note that the character string type is a bounded sequence of characters whose size bound format is " + + "not specified in the data model, but rather a property of the underlying encoding. Therefore, no " + + "assumptions are to be made about the presence or absence of a length prefix or null-terminator " + + "byte, or other implementation considerations." + + "\n" + + "It is recommended to define constraints on the maximum possible string length." + + "\n" + + "If at least one of the code points within the string has value 31 (0x1F), which is Unicode " + + "INFORMATION SEPARATOR 1 and ASCII Unit Separator, then any client making use of the string shall " + + "only consider the code points that appear before the first INFORMATION SEPARATOR 1 as being the " + + "textual information carried by the string. Any comparison between such a string and other strings " + + "shall use the textual component before the first INFORMATION SEPARATOR 1. The remainder of the " + + "character string after a first INFORMATION SEPARATOR 1 is reserved for future use by this " + + "specification. Implementations of this version of the specification shall NOT produce character " + + "strings containing INFORMATION SEPARATOR 1.", + + xref: { document: "core", section: "7.19.2.36" } + }), + + Datatype({ + name: "ipadr", type: "octstr", description: "IP Address", isSeed: true, + xref: { document: "core", section: "7.19.2" } + }), + + Datatype({ + name: "ipv4adr", type: "octstr", description: "IPv4 Address", isSeed: true, + + details: "The IPv4 address data type is derived from an octet string. The octets shall correspond to the four " + + "octets in network byte order that comprise an IPv4 address represented utilizing quad-dotted " + + "notation." + + "\n" + + "Examples of encoding:" + + "\n" + + " • Address 192.168.2.235 → C0A802EB" + + "\n" + + " • Address 10.4.200.75 → 0A04C84B", + + xref: { document: "core", section: "7.19.2.38" } + }), + + Datatype({ + name: "ipv6adr", type: "octstr", description: "IPv6 Address", isSeed: true, + + details: "The IPv6 address data type is derived from an octet string. The octets shall correspond to the full " + + "16 octets that comprise an IPv6 address as defined by RFC 4291. The octets shall be presented in " + + "network byte order." + + "\n" + + "Examples of encoding:" + + "\n" + + " • Address 2001:DB8:0:0:8:800:200C:417A → 20010DB80000000000080800200C417A" + + "\n" + + " • Address 2001:0DB8:1122:3344:5566:7788:99AA:BBCC → 20010DB8112233445566778899AABBCC", + + xref: { document: "core", section: "7.19.2.39" } + }), + + Datatype({ + name: "ipv6pre", type: "octstr", description: "IPv6 Prefix", isSeed: true, + + details: "The IPv6 prefix data type is derived from an octet string. The octets shall be encoded" + + "\n" + + " • The first octet shall encode the prefix length, in bits, in the range of 0 to 128." + + "\n" + + " ◦ A value of 0 indicates an absent/invalid prefix." + + "\n" + + " • The subsequent octets shall encode the contiguous leftmost bits of the prefix, in network byte " + + " order, with left justification, such that the first bit of the prefix is in the most " + + " significant bit of the first octet. Encoding SHOULD use the least number of bytes to encode the " + + " prefix but may include unused trailing zeroes." + + "\n" + + "Examples of encoding:" + + "\n" + + " • Preferred minimal encoding: Prefix 2001:0DB8:0:CD30::/60 → 9 octets → 3C20010DB80000CD30" + + "\n" + + " • Preferred minimal encoding: Prefix 2001:0DB8:BB00::/40 → 6 octets → 2820010DB8BB" + + "\n" + + " • Allowed non-minimal encoding: Prefix 2001:0DB8:BB00::/40 → 7 octets → 2820010DB8BB00", + + xref: { document: "core", section: "7.19.2.40" } + }), + + Datatype({ + name: "hwadr", type: "octstr", description: "Hardware Address", isSeed: true, + details: "The Hardware Address data type shall be either a 48-bit IEEE MAC Address or a 64-bit IEEE MAC " + + "Address (e.g. EUI-64). The order of bytes is Big-Endian or display mode, where the first byte in " + + "the string is the left most or highest order byte.", + xref: { document: "core", section: "7.19.2.41" } + }), + + Datatype( + { + name: "semtag", type: "struct", description: "Semantic Tag", isSeed: true, + details: "This data type shall be represented by the following structure:", + xref: { document: "core", section: "7.19.2.42" } + }, + + Field({ + name: "MfgCode", id: 0x0, type: "vendor-id", conformance: "M", default: null, quality: "X", + + details: "If the MfgCode field is not null, it shall be the Vendor ID of the manufacturer who has defined a " + + "certain namespace and the NamespaceID field shall be the ID of a namespace defined by the " + + "manufacturer identified in the MfgCode field." + + "\n" + + "If a manufacturer specific Tag field is indicated in a list of SemanticTagStruct entries, the list " + + "shall include at least one standard tag which is not from any manufacturer’s namespace. A standard " + + "tag is a tag from a common namespace, a derived cluster namespace, or an applicable device-specific " + + "namespace." + + "\n" + + "If MfgCode is null, the NamespaceID field shall indicate a standard namespace.", + + xref: { document: "core", section: "7.19.2.42.1" } + }), + + Field({ + name: "NamespaceId", id: 0x1, type: "namespace", conformance: "M", + details: "The NamespaceID field shall identify a namespace." + + "\n" + + "The common and device-specific semantic tag namespaces are listed in StandardNamespaces.", + xref: { document: "core", section: "7.19.2.42.2" } + }), + + Field({ + name: "Tag", id: 0x2, type: "tag", conformance: "M", + details: "The Tag field shall be the ID of a semantic tag located within the namespace indicated by " + + "NamespaceID." + + "\n" + + "A device may expose tags from the common or device-specific namespaces and from " + + "manufacturer-specific namespaces in a single TagList.", + xref: { document: "core", section: "7.19.2.42.3" } + }), + + Field({ + name: "Label", id: 0x3, type: "string", conformance: "MfgCode != null, O", constraint: "max 64", + default: null, quality: "X", + + details: "The Label field, if present, shall contain human-readable text suitable for display on a client. " + + "The content of the Label field is defined by the manufacturer." + + "\n" + + "This field shall be present when the MfgCode is not null. This field SHOULD NOT be used if the Tag " + + "is from a standard namespace, unless the Tag requires further qualification. For example: A Tag " + + "that has the meaning of \"room\" in a location namespace, would require the a label string to qualify " + + "the type of room, such as \"1\", \"2b\", \"Bathroom\", etc.", + + xref: { document: "core", section: "7.19.2.42.4" } + }) + ), + + Datatype({ + name: "namespace", type: "enum8", description: "Namespace", isSeed: true, + details: "The Namespace type identifies the namespace used for a semantic tag.", + xref: { document: "core", section: "7.19.2.43" } + }), + Datatype({ + name: "tag", type: "enum8", description: "Tag", isSeed: true, + details: "The Tag type shall identify a semantic tag located within a namespace.", + xref: { document: "core", section: "7.19.2.44" } + }), + + Datatype( + { + name: "locationdesc", type: "struct", description: "Location Descriptor", isSeed: true, + details: "This data type shall be represented by the following structure:", + xref: { document: "core", section: "7.19.2.45" } + }, + + Field({ + name: "LocationName", id: 0x0, type: "string", conformance: "M", constraint: "max 128", + details: "This field shall indicate the name of the location. For example, \"blue room\"." + + "\n" + + "If the location name is not user provided, the logic that generates it (clients, devices etc.) " + + "SHOULD utilize synthesized user-friendly, understandable, names for the location, rather than " + + "opaque values such as \"private\" or \"2fe7c241-a50a-4863-896e-c5878da5ed68\".", + xref: { document: "core", section: "7.19.2.45.1" } + }), + + Field({ + name: "FloorNumber", id: 0x1, type: "int16", conformance: "M", quality: "X", + + details: "This field shall indicate the level number. Negative values correspond to basement levels." + + "\n" + + "Value zero indicates this is the main floor, which typically includes the main entrance to the " + + "user’s home. For a building with multiple levels, it is the client’s responsibility to map each " + + "level to/from a FloorNumber tag value, using the level numbering convention of the region where the " + + "client operates. For example, if the client operates in Europe, building level 1, which is one " + + "level up from the street level, SHOULD be mapped to FloorNumber tag value 0x1. If the client " + + "operates in North America, building level 1, which is at street level, SHOULD be mapped to " + + "FloorNumber tag value 0x0." + + "\n" + + "A null value indicates that this information is not available." + + "\n" + + "When the clients present the level information for user selection, they SHOULD use the operating " + + "region to determine how to render and map this data. For example, if the client operates in North " + + "America it SHOULD present the user a list that includes entries labeled \"basement\", \"first\", " + + "\"second\", and internally mapped to floor numbers -1, 0, and 1. If operating in Europe, the client " + + "SHOULD present a list that includes entries labeled \"basement\", \"ground\", \"first\", internally " + + "mapped to floor numbers -1, 0, and 1." + + "\n" + + "The floor number information is expected to be mostly useful to the clients, rather than the " + + "devices, such as for grouping devices that are located on the same level. For example, an " + + "automation may be defined for all devices located at the basement level (floor number -1)." + + "\n" + + "NOTE" + + "\n" + + "Handling complex level situations, such as half levels (side split houses), or the levels from an " + + "apartment building, is up to the client and/or user.", + + xref: { document: "core", section: "7.19.2.45.2" } + }), + + Field({ + name: "AreaType", id: 0x2, type: "tag", conformance: "M", quality: "X", + + details: "This field shall be the ID of an area semantic tag, located within the Common Area Namespace. For " + + "example, this tag may indicate that the location refers to a bedroom." + + "\n" + + "If this field is null, that indicates that the area type information is not available." + + "\n" + + "NOTE" + + "\n" + + "This field only indicates the type of the area. Multiple areas of the same type, such as bedrooms, " + + "may exist in a user’s home.", + + xref: { document: "core", section: "7.19.2.45.3" } + }) + ), + + Datatype( + { + name: "WildcardPathFlagsBitmap", type: "map8", + details: "The WildcardPathFlagsBitmap indicates flags that apply to the path, affecting wildcard expansion. " + + "The following flags are defined:", + xref: { document: "core", section: "8.9.2.3" } + }, + + Field({ + name: "WildcardSkipRootNode", constraint: "0", + description: "Skip the Root Node endpoint (endpoint 0) during wildcard expansion." + }), + Field({ + name: "WildcardSkipGlobalAttributes", constraint: "1", + description: "Skip several large global attributes during wildcard expansion." + }), + Field({ + name: "WildcardSkipAttributeList", constraint: "2", + description: "Skip the AttributeList global attribute during wildcard expansion." + }), + Field({ name: "Reserved", constraint: "3" }), + Field({ + name: "WildcardSkipCommandLists", constraint: "4", + description: "Skip the AcceptedCommandList and GeneratedCommandList global attributes during wildcard expansion." + }), + Field({ + name: "WildcardSkipCustomElements", constraint: "5", + description: "Skip any manufacturer-specific clusters or attributes during wildcard expansion." + }), + Field({ + name: "WildcardSkipFixedAttributes", constraint: "6", + description: "Skip any Fixed (F) quality attributes during wildcard expansion." + }), + Field({ + name: "WildcardSkipChangesOmittedAttributes", constraint: "7", + description: "Skip any Changes Omitted (C) quality attributes during wildcard expansion." + }), + Field({ + name: "WildcardSkipDiagnosticsClusters", constraint: "8", + description: "Skip all clusters with the Diagnostics (K) quality during wildcard expansion." + }) + ), + + Cluster( + { + name: "Descriptor", id: 0x1d, classification: "endpoint", pics: "DESC", + + details: "NOTE" + + "\n" + + "The Descriptor cluster is meant to replace the support from the Zigbee Device Object (ZDO) for " + + "describing a node, its endpoints and clusters." + + "\n" + + "This cluster describes an endpoint instance on the node, independently from other endpoints, but " + + "also allows composition of endpoints to conform to complex device type patterns." + + "\n" + + "This cluster supports a list of one or more device type identifiers that represent conformance to " + + "device type specifications." + + "\n" + + "The cluster supports a PartsList attribute that is a list of zero or more endpoints to support a " + + "composed device type.", + + xref: { document: "core", section: "9.5" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "9.5.4" } }, + + Field({ + name: "TAGLIST", conformance: "desc", constraint: "0", description: "TagList", + details: "See the Disambiguation section in the System Model spec for conformance requirements for this " + + "feature and the corresponding attribute.", + xref: { document: "core", section: "9.5.4.1" } + }) + ), + + Attribute( + { + name: "DeviceTypeList", id: 0x0, type: "list", access: "R V", conformance: "M", constraint: "min 1", + quality: "F", + + details: "This is a list of device types and corresponding revisions declaring endpoint conformance (see " + + "DeviceTypeStruct). At least one device type entry shall be present." + + "\n" + + "An endpoint shall conform to all device types listed in the DeviceTypeList. A cluster instance that " + + "is in common for more than one device type in the DeviceTypeList shall be supported as a shared " + + "cluster instance on the endpoint.", + + xref: { document: "core", section: "9.5.6.1" } + }, + + Field({ name: "entry", type: "DeviceTypeStruct" }) + ), + + Attribute( + { + name: "ServerList", id: 0x1, type: "list", access: "R V", conformance: "M", default: [], + quality: "F", + details: "This attribute shall list each cluster ID for the server clusters present on the endpoint instance.", + xref: { document: "core", section: "9.5.6.2" } + }, + + Field({ name: "entry", type: "cluster-id" }) + ), + + Attribute( + { + name: "ClientList", id: 0x2, type: "list", access: "R V", conformance: "M", default: [], + quality: "F", + details: "This attribute shall list each cluster ID for the client clusters present on the endpoint instance.", + xref: { document: "core", section: "9.5.6.3" } + }, + + Field({ name: "entry", type: "cluster-id" }) + ), + + Attribute( + { + name: "PartsList", id: 0x3, type: "list", access: "R V", conformance: "M", default: [], + details: "This attribute indicates composition of the device type instance. Device type instance composition " + + "shall include the endpoints in this list." + + "\n" + + "See Endpoint Composition for more information about which endpoints to include in this list.", + xref: { document: "core", section: "9.5.6.4" } + }, + + Field({ name: "entry", type: "endpoint-no" }) + ), + + Attribute( + { + name: "TagList", id: 0x4, type: "list", access: "R V", conformance: "TAGLIST", constraint: "1 to 6", + quality: "F", + + details: "This attribute shall be used to disambiguate sibling endpoints in certain situations, as defined in " + + "the Disambiguation section in the System Model specification. An example of such a situation might " + + "be a device with two buttons, with this attribute being used to indicate which of the two endpoints " + + "corresponds to the button on the left side." + + "\n" + + "It may also be used to provide information about an endpoint (e.g. the relative location of a " + + "Temperature sensor in a Temperature Controlled Cabinet)." + + "\n" + + " • A client SHOULD use these tags to convey disambiguation information and other relevant " + + " information to the user (e.g. showing it in a user interface), as appropriate." + + "\n" + + " • A client SHOULD use these tags in its logic to make decisions, as appropriate." + + "\n" + + "For example, a client may identify which endpoint maps to a certain function, orientation or " + + "labeling." + + "\n" + + "A client may use the Label field of each SemanticTagStruct, if present in each structure, to " + + "indicate characteristics of an endpoint, or to augment what is provided in the TagID field of the " + + "same structure.", + + xref: { document: "core", section: "9.5.6.5" } + }, + + Field({ name: "entry", type: "semtag" }) + ), + + Datatype( + { + name: "DeviceTypeStruct", type: "struct", + details: "The device type and revision define endpoint conformance to a release of a device type definition. " + + "See the Data Model specification for more information.", + xref: { document: "core", section: "9.5.5.1" } + }, + + Field({ + name: "DeviceType", id: 0x0, type: "devtype-id", conformance: "M", + details: "This shall indicate the device type definition. The endpoint shall conform to the device type " + + "definition and cluster specifications required by the device type.", + xref: { document: "core", section: "9.5.5.1.1" } + }), + + Field({ + name: "Revision", id: 0x1, type: "uint16", conformance: "M", constraint: "min 1", + details: "This is the implemented revision of the device type definition. The endpoint shall conform to this " + + "revision of the device type.", + xref: { document: "core", section: "9.5.5.1.2" } + }) + ) + ), + + Cluster( + { + name: "Binding", id: 0x1e, classification: "endpoint", pics: "BIND", + + details: "NOTE" + + "\n" + + "This scope of this document is the Binding cluster as part of the Cluster Library. The Binding " + + "cluster is meant to replace the support from the Zigbee Device Object (ZDO) for supporting the " + + "binding table." + + "\n" + + "A binding represents a persistent relationship between an endpoint and one or more other local or " + + "remote endpoints. A binding does not require that the relationship exists. It is up to the node " + + "application to set up the relationship." + + "\n" + + "A binding is used to inform a client endpoint of one or more targets for a potential interaction. " + + "For example: a light switch that controls one or more light bulbs, needs to be told the nodes and " + + "endpoints of the bulbs, or told a group in which the bulbs are members. For example: A client that " + + "needs to subscribe to an occupancy sensor, needs to know the node and endpoint of the sensor." + + "\n" + + "In such cases, a binding is used to direct a local endpoint to a target. The existence of the " + + "Binding cluster on the client endpoint, allows the creation of one or more binding entries " + + "(bindings) in the Binding cluster." + + "\n" + + "Each binding indicates another endpoint or cluster on another endpoint. Multiple bindings are " + + "allowed, depending on the interaction." + + "\n" + + "A binding is either a unicast binding, where the target is a single endpoint on a single node, or a " + + "groupcast binding, where the target is a group, which may indicate multiple endpoints on multiple " + + "nodes. The binding may also target a single cluster on the target endpoint(s)." + + "\n" + + "When a client cluster requires a target for an interaction, the Binding cluster shall exist on the " + + "same endpoint." + + "\n" + + "Once a binding entry is created on the Binding cluster, the client endpoint may initiate " + + "interactions to the binding target.", + + xref: { document: "core", section: "9.6" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "Binding", id: 0x0, type: "list", access: "RW F VM", conformance: "M", constraint: "desc", + default: [], quality: "N", + details: "Each entry shall represent a binding.", + xref: { document: "core", section: "9.6.6.1" } + }, + + Field({ name: "entry", type: "TargetStruct" }) + ), + + Datatype( + { name: "TargetStruct", type: "struct", xref: { document: "core", section: "9.6.5.1" } }, + + Field({ + name: "Node", id: 0x1, type: "node-id", access: "F", conformance: "Endpoint", + details: "This field is the remote target node ID. If the Endpoint field is present, this field shall be " + + "present.", + xref: { document: "core", section: "9.6.5.1.1" } + }), + + Field({ + name: "Group", id: 0x2, type: "group-id", access: "F", conformance: "!Endpoint", + constraint: "min 1", + details: "This field is the target group ID that represents remote endpoints. If the Endpoint field is " + + "present, this field shall NOT be present.", + xref: { document: "core", section: "9.6.5.1.2" } + }), + + Field({ + name: "Endpoint", id: 0x3, type: "endpoint-no", access: "F", conformance: "!Group", + details: "This field is the remote endpoint that the local endpoint is bound to. If the Group field is " + + "present, this field shall NOT be present.", + xref: { document: "core", section: "9.6.5.1.3" } + }), + + Field({ + name: "Cluster", id: 0x4, type: "cluster-id", access: "F", conformance: "O", + details: "This field is the cluster ID (client & server) on the local and target endpoint(s). If this field " + + "is present, the client cluster shall also exist on this endpoint (with this Binding cluster). If " + + "this field is present, the target shall be this cluster on the target endpoint(s).", + xref: { document: "core", section: "9.6.5.1.4" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) + ), + + Cluster( + { + name: "Label", classification: "endpoint", pics: "LABEL", + details: "This cluster provides a feature to tag an endpoint with zero or more labels. This is a base cluster " + + "that requires a derived cluster to create an instance.", + xref: { document: "core", section: "9.7" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "LabelList", id: 0x0, type: "list", conformance: "M", constraint: "derived", default: [], + details: "This is a list of string tuples. Each entry is a LabelStruct.", + xref: { document: "core", section: "9.7.5.1" } + }, + Field({ name: "entry", type: "LabelStruct" }) + ), + + Datatype( + { + name: "LabelStruct", type: "struct", + details: "This is a string tuple with strings that are user defined.", + xref: { document: "core", section: "9.7.4.1" } + }, + + Field({ + name: "Label", id: 0x0, type: "string", conformance: "M", constraint: "max 16", + details: "The Label or Value semantic is not defined here. Label examples: \"room\", \"zone\", \"group\", " + + "\"direction\".", + xref: { document: "core", section: "9.7.4.1.1" } + }), + + Field({ + name: "Value", id: 0x1, type: "string", conformance: "M", constraint: "max 16", + details: "The Label or Value semantic is not defined here. The Value is a discriminator for a Label that may " + + "have multiple instances. Label:Value examples: \"room\":\"bedroom 2\", \"orientation\":\"North\", " + + "\"floor\":\"2\", \"direction\":\"up\"", + xref: { document: "core", section: "9.7.4.1.2" } + }) + ) + ), + + Cluster( + { + name: "FixedLabel", id: 0x40, type: "Label", classification: "endpoint", pics: "FLABEL", + + details: "This cluster is derived from the Label cluster and provides a feature for the device to tag an " + + "endpoint with zero or more read-only labels." + + "\n" + + "Examples:" + + "\n" + + " • A bridge can use this to indicate grouping of bridged devices. For example: All bridged devices " + + " whose endpoints have an entry in their LabelList \"room\":\"bedroom 2\" are in the same (bed)room." + + "\n" + + " • A manufacturer can use this to identify a characteristic of an endpoint. For example to " + + " identify the endpoints of a luminaire, one pointing up, the other pointing down, one of the " + + " endpoints would have a LabelList entry \"orientation\":\"up\" while the other would have " + + " \"orientation\":\"down\". Using such indication, the user interface of a Node controlling this " + + " luminaire" + + "\n" + + "knows which of the endpoints is which of the lights." + + "\n" + + "Note that the TagList in the Descriptor cluster provides an alternative mechanism for such self- " + + "description using standardized tags rather than manufacturer-selected strings, yielding a " + + "standardized mechanism for features defined in the various namespaces. The second example above can " + + "be implemented using semantic tags Direction.Upward and Direction.Downward instead of (or in " + + "addition to) the Fixed Label cluster.", + + xref: { document: "core", section: "9.8" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "LabelList", id: 0x0, type: "list", access: "R V", conformance: "M", default: [], + quality: "N", + xref: { document: "core", section: "9.8.4" } + }, + Field({ name: "entry", type: "LabelStruct" }) + ) + ), + + Cluster( + { + name: "UserLabel", id: 0x41, type: "Label", classification: "endpoint", pics: "ULABEL", + details: "This cluster is derived from the Label cluster and provides a feature to tag an endpoint with zero " + + "or more writable labels.", + xref: { document: "core", section: "9.9" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "LabelList", id: 0x0, type: "list", access: "RW VM", conformance: "M", constraint: "min 4", + default: [], quality: "N", + details: "An implementation shall support at least 4 list entries per node for all User Label cluster " + + "instances on the node.", + xref: { document: "core", section: "9.9.4.1" } + }, + + Field({ name: "entry", type: "LabelStruct" }) + ) + ), + + Cluster( + { + name: "AccessControl", id: 0x1f, classification: "node", pics: "ACL", + + details: "The Access Control Cluster exposes a data model view of a Node’s Access Control List (ACL), which " + + "codifies the rules used to manage and enforce Access Control for the Node’s endpoints and their " + + "associated cluster instances. Access to this Access Control Cluster itself requires a special " + + "Administer privilege level, such that only Nodes granted such privilege (hereafter termed " + + "\"Administrators\") can manage the Access Control Cluster." + + "\n" + + "The Access Control Cluster shall be present on the root node endpoint of each Node, and shall NOT " + + "be present on any other Endpoint of any Node.", + + xref: { document: "core", section: "9.10" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "9.10.4" } }, + Field({ + name: "EXTS", conformance: "O", constraint: "0", description: "Extension", + details: "This feature indicates the device supports ACL Extension attribute.", + xref: { document: "core", section: "9.10.4.1" } + }), + + Field({ + name: "MNGD", conformance: "desc", constraint: "1", description: "ManagedDevice", + + details: "This feature is for a device that is managed by a service associated with the device vendor and " + + "which imposes default access restrictions upon each new fabric added to it. This could arise, for " + + "example, if the device is managed by a service provider under contract to an end-user, in such a " + + "way that the manager of the device does not unconditionally grant universal access to all of a " + + "device’s functionality, even for fabric administrators. For example, many Home Routers are managed " + + "by an Internet Service Provider (a service), and these services often have a policy that requires " + + "them to obtain user consent before certain administrative functions can be delegated to a third " + + "party (e.g., a fabric Administrator). These restrictions are expressed using an Access Restriction " + + "List (ARL)." + + "\n" + + "The purpose of this feature on the Access Control cluster is to indicate to a fabric Administrator " + + "that access by it to specific attributes, commands and/or events for specific clusters is currently " + + "prohibited. Attempts to access these restricted data model elements shall result in an error of " + + "ACCESS_RESTRICTED." + + "\n" + + "A device that implements this feature shall have a mechanism to honor the ReviewFabricRestrictions " + + "command, such as user interfaces or service interactions associated with a service provider or the " + + "device manufacturer, which allows the owner (or subscriber) to manage access restrictions for each " + + "fabric. The user interface design, which includes the way restrictions are organized and presented " + + "to the user, is not specified, but SHOULD be usable by non-expert end-users from common mobile " + + "devices, personal computers, or an on-device user interface." + + "\n" + + "Controllers and clients SHOULD incorporate generic handling of the ACCESS_RESTRICTED error code, " + + "when it appears in allowed contexts, in order to gracefully handle situations where this feature is " + + "encountered. Device vendors that adopt this feature SHOULD be judicious in its use given the risk " + + "of unexpected behavior in controllers and clients." + + "\n" + + "For certification testing, a device that implements this feature shall provide a way for all " + + "restrictions to be removed." + + "\n" + + "The ARL attribute provides the set of restrictions currently applied to this fabric." + + "\n" + + "The ReviewFabricRestrictions command provides a way for the fabric Administrator to request that " + + "the server triggers a review of the current fabric restrictions, by involving external entities " + + "such as end-users, or other services associated with the manager of the device hosting the server. " + + "This review process may involve communication between external services and the user, and may take " + + "an unpredictable amount of time to complete since an end-user may need to visit some resources, " + + "such as a mobile application or web site. A FabricRestrictionReviewUpdate event will be generated " + + "by the device within a predictable time period of the ReviewFabricRestrictionsResponse (see " + + "ReviewFabricRestrictions for specification of this time period), and this event can be correlated " + + "with the ReviewFabricRestrictionsResponse using a token provided in both. The device may provide " + + "instructions or a Redirect URL in the FabricRestrictionReviewUpdate event in order to help the user " + + "access the features required for managing per-fabric restrictions." + + "\n" + + "See Section 6.6.2, “Model” for a description of how access control is impacted by the ARL attribute." + + "\n" + + "### Managed Device Feature Usage Restrictions" + + "\n" + + "Use of this feature shall be limited to the mandatory clusters of endpoints having a device type " + + "that explicitly permits its use in the Device Library Specification. As a reminder, the device " + + "types associated with an endpoint are listed in the Descriptor cluster of the endpoint." + + "\n" + + "In addition, use of this feature shall NOT restrict the following clusters on any endpoint:" + + "\n" + + " 1. the Descriptor Cluster (0x001D)" + + "\n" + + " 2. the Binding Cluster (0x001E)" + + "\n" + + " 3. the Network Commissioning Cluster (0x0031)" + + "\n" + + " 4. the Identify Cluster (0x0003)" + + "\n" + + " 5. the Groups Cluster (0x0004)" + + "\n" + + "In addition, use of this feature shall NOT restrict the global attributes of any cluster." + + "\n" + + "Because ARLs cannot be used to restrict root node access or access to any clusters required for " + + "commissioning, administrators may determine the current restrictions of the ARL at any point, " + + "including during commissioning after joining the fabric.", + + xref: { document: "core", section: "9.10.4.2" } + }) + ), + + Attribute( + { + name: "Acl", id: 0x0, type: "list", access: "RW F A", conformance: "M", constraint: "desc", + + details: "An attempt to add an Access Control Entry when no more entries are available shall result in a " + + "RESOURCE_EXHAUSTED error being reported and the ACL attribute shall NOT have the entry added to it. " + + "See access control limits." + + "\n" + + "See the AccessControlEntriesPerFabric attribute for the actual value of the number of entries per " + + "fabric supported by the server." + + "\n" + + "Each Access Control Entry codifies a single grant of privilege on this Node, and is used by the " + + "Access Control Privilege Granting algorithm to determine if a subject has privilege to interact " + + "with targets on the Node.", + + xref: { document: "core", section: "9.10.6.3" } + }, + + Field({ name: "entry", type: "AccessControlEntryStruct" }) + ), + + Attribute( + { + name: "Extension", id: 0x1, type: "list", access: "RW F A", conformance: "EXTS", constraint: "desc", + details: "If present, the Access Control Extensions may be used by Administrators to store arbitrary data " + + "related to fabric’s Access Control Entries." + + "\n" + + "The Access Control Extension list shall support a single extension entry per supported fabric.", + xref: { document: "core", section: "9.10.6.4" } + }, + + Field({ name: "entry", type: "AccessControlExtensionStruct" }) + ), + + Attribute({ + name: "SubjectsPerAccessControlEntry", id: 0x2, type: "uint16", access: "R V", conformance: "M", + constraint: "min 4", default: 4, quality: "F", + + details: "This attribute shall provide the minimum number of Subjects per entry that are supported by this " + + "server." + + "\n" + + "Since reducing this value over time may invalidate ACL entries already written, this value shall " + + "NOT decrease across time as software updates occur that could impact this value. If this is a " + + "concern for a given implementation, it is recommended to only use the minimum value required and " + + "avoid reporting a higher value than the required minimum.", + + xref: { document: "core", section: "9.10.6.5" } + }), + + Attribute({ + name: "TargetsPerAccessControlEntry", id: 0x3, type: "uint16", access: "R V", conformance: "M", + constraint: "min 3", default: 3, quality: "F", + + details: "This attribute shall provide the minimum number of Targets per entry that are supported by this " + + "server." + + "\n" + + "Since reducing this value over time may invalidate ACL entries already written, this value shall " + + "NOT decrease across time as software updates occur that could impact this value. If this is a " + + "concern for a given implementation, it is recommended to only use the minimum value required and " + + "avoid reporting a higher value than the required minimum.", + + xref: { document: "core", section: "9.10.6.6" } + }), + + Attribute({ + name: "AccessControlEntriesPerFabric", id: 0x4, type: "uint16", access: "R V", conformance: "M", + constraint: "min 4", default: 4, quality: "F", + + details: "This attribute shall provide the minimum number of ACL Entries per fabric that are supported by " + + "this server." + + "\n" + + "Since reducing this value over time may invalidate ACL entries already written, this value shall " + + "NOT decrease across time as software updates occur that could impact this value. If this is a " + + "concern for a given implementation, it is recommended to only use the minimum value required and " + + "avoid reporting a higher value than the required minimum.", + + xref: { document: "core", section: "9.10.6.7" } + }), + + Attribute( + { + name: "CommissioningArL", id: 0x5, type: "list", access: "R V", conformance: "MNGD", + constraint: "desc", default: [], quality: "F", + + details: "This attribute shall provide the set of CommissioningAccessRestrictionEntryStruct applied during " + + "commissioning on a managed device." + + "\n" + + "When present, the CommissioningARL attribute shall indicate the access restrictions applying during " + + "commissioning." + + "\n" + + "Attempts to access data model elements described by an entry in the CommissioningARL attribute " + + "during commissioning shall result in an error of ACCESS_RESTRICTED. See Access Control Model for " + + "more information about the features related to controlling access to a Node’s Endpoint Clusters " + + "(\"Targets\" hereafter) from other Nodes." + + "\n" + + "See Section 9.10.4.2.1, “Managed Device Feature Usage Restrictions” for limitations on the use of " + + "access restrictions.", + + xref: { document: "core", section: "9.10.6.8" } + }, + + Field({ name: "entry", type: "CommissioningAccessRestrictionEntryStruct" }) + ), + + Attribute( + { + name: "Arl", id: 0x6, type: "list", access: "R F V", conformance: "MNGD", constraint: "desc", + default: [], + + details: "This attribute shall provide the set of AccessRestrictionEntryStruct applied to the associated " + + "fabric on a managed device." + + "\n" + + "When present, the ARL attribute shall indicate the access restrictions applying to the accessing " + + "fabric. In contrast, the CommissioningARL attribute indicates the accessing restrictions that apply " + + "when there is no accessing fabric, such as during commissioning." + + "\n" + + "The access restrictions are externally added/removed based on the particular relationship the " + + "device hosting this server has with external entities such as its owner, external service provider, " + + "or end-user." + + "\n" + + "Attempts to access data model elements described by an entry in the ARL attribute for the accessing " + + "fabric shall result in an error of ACCESS_RESTRICTED. See Access Control Model for more information " + + "about the features related to controlling access to a Node’s Endpoint Clusters (\"Targets\" " + + "hereafter) from other Nodes." + + "\n" + + "See Section 9.10.4.2.1, “Managed Device Feature Usage Restrictions” for limitations on the use of " + + "access restrictions.", + + xref: { document: "core", section: "9.10.6.9" } + }, + + Field({ name: "entry", type: "AccessRestrictionEntryStruct" }) + ), + + Event( + { + name: "AccessControlEntryChanged", id: 0x0, access: "S A", conformance: "M", priority: "info", + + details: "The cluster shall generate AccessControlEntryChanged events whenever its ACL attribute data is " + + "changed by an Administrator." + + "\n" + + " • Each added entry shall generate an event with ChangeType Added." + + "\n" + + " • Each changed entry shall generate an event with ChangeType Changed." + + "\n" + + " • Each removed entry shall generate an event with ChangeType Removed.", + + xref: { document: "core", section: "9.10.9.1" } + }, + + Field({ + name: "AdminNodeId", id: 0x1, type: "node-id", access: "S", conformance: "M", constraint: "desc", + quality: "X", + details: "The Node ID of the Administrator that made the change, if the change occurred via a CASE session." + + "\n" + + "Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change " + + "occurred via a CASE or PASE session; the other shall be null.", + xref: { document: "core", section: "9.10.9.1.1" } + }), + + Field({ + name: "AdminPasscodeId", id: 0x2, type: "uint16", access: "S", conformance: "M", constraint: "desc", + quality: "X", + + details: "The Passcode ID of the Administrator that made the change, if the change occurred via a PASE " + + "session. Non-zero values are reserved for future use (see PasscodeId generation in " + + "PBKDFParamRequest)." + + "\n" + + "Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change " + + "occurred via a CASE or PASE session; the other shall be null.", + + xref: { document: "core", section: "9.10.9.1.2" } + }), + + Field({ + name: "ChangeType", id: 0x3, type: "ChangeTypeEnum", access: "S", conformance: "M", + details: "The type of change as appropriate.", + xref: { document: "core", section: "9.10.9.1.3" } + }), + + Field({ + name: "LatestValue", id: 0x4, type: "AccessControlEntryStruct", access: "S", conformance: "M", + quality: "X", + details: "The latest value of the changed entry." + + "\n" + + "This field SHOULD be set if resources are adequate for it; otherwise it shall be set to NULL if " + + "resources are scarce.", + xref: { document: "core", section: "9.10.9.1.4" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Event( + { + name: "AccessControlExtensionChanged", id: 0x1, access: "S A", conformance: "EXTS", + priority: "info", + + details: "The cluster shall generate AccessControlExtensionChanged events whenever its extension attribute " + + "data is changed by an Administrator." + + "\n" + + " • Each added extension shall generate an event with ChangeType Added." + + "\n" + + " • Each changed extension shall generate an event with ChangeType Changed." + + "\n" + + " • Each removed extension shall generate an event with ChangeType Removed.", + + xref: { document: "core", section: "9.10.9.2" } + }, + + Field({ + name: "AdminNodeId", id: 0x1, type: "node-id", access: "S", conformance: "M", constraint: "desc", + quality: "X", + details: "The Node ID of the Administrator that made the change, if the change occurred via a CASE session." + + "\n" + + "Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change " + + "occurred via a CASE or PASE session; the other shall be null.", + xref: { document: "core", section: "9.10.9.2.1" } + }), + + Field({ + name: "AdminPasscodeId", id: 0x2, type: "uint16", access: "S", conformance: "M", constraint: "desc", + quality: "X", + + details: "The Passcode ID of the Administrator that made the change, if the change occurred via a PASE " + + "session. Non-zero values are reserved for future use (see PasscodeId generation in " + + "PBKDFParamRequest)." + + "\n" + + "Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change " + + "occurred via a CASE or PASE session; the other shall be null.", + + xref: { document: "core", section: "9.10.9.2.2" } + }), + + Field({ + name: "ChangeType", id: 0x3, type: "ChangeTypeEnum", access: "S", conformance: "M", + details: "The type of change as appropriate.", + xref: { document: "core", section: "9.10.9.2.3" } + }), + + Field({ + name: "LatestValue", id: 0x4, type: "AccessControlExtensionStruct", access: "S", conformance: "M", + quality: "X", + details: "The latest value of the changed extension." + + "\n" + + "This field SHOULD be set if resources are adequate for it; otherwise it shall be set to NULL if " + + "resources are scarce.", + xref: { document: "core", section: "9.10.9.2.4" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Event( + { + name: "FabricRestrictionReviewUpdate", id: 0x2, access: "S A", conformance: "MNGD", + priority: "info", + details: "The cluster shall generate a FabricRestrictionReviewUpdate event to indicate completion of a fabric " + + "restriction review. Due to the requirement to generate this event within a bound time frame of " + + "successful receipt of the ReviewFabricRestrictions command, this event may include additional steps " + + "that the client may present to the user in order to help the user locate the user interface for the " + + "Managed Device feature.", + xref: { document: "core", section: "9.10.9.3" } + }, + + Field({ + name: "Token", id: 0x0, type: "uint64", access: "S", conformance: "M", + details: "This field shall indicate the Token that can be used to correlate a " + + "ReviewFabricRestrictionsResponse with a FabricRestrictionReviewUpdate event.", + xref: { document: "core", section: "9.10.9.3.1" } + }), + + Field({ + name: "Instruction", id: 0x1, type: "string", access: "S", conformance: "O", constraint: "max 512", + + details: "This field shall provide human readable text that may be displayed to the user to help them locate " + + "the user interface for managing access restrictions for each fabric." + + "\n" + + "A device SHOULD implement the Localization Configuration Cluster when it has no other means to " + + "determine the locale to use for this text." + + "\n" + + "Examples include \"Please try again and immediately access device display for further instructions.\" " + + "or \"Please check email associated with your Acme account.\"", + + xref: { document: "core", section: "9.10.9.3.2" } + }), + + Field( + { + name: "ArlRequestFlowUrl", id: 0x2, type: "string", access: "S", conformance: "O", + constraint: "max 256", + + details: "This field shall indicate the URL for the service associated with the device maker which the user " + + "can visit to manage fabric limitations. The syntax of this field shall follow the syntax as " + + "specified in RFC 1738 and shall use the https scheme for internet-hosted URLs." + + "\n" + + " • The URL may embed the token, fabric index, fabric vendor, or other information transparently in " + + " order to pass context about the originating ReviewFabricRestrictions command to the service " + + " associated with the URL. The service associated with the device vendor may perform vendor ID " + + " verification on the fabric from which the ReviewFabricRestrictions command originated." + + "\n" + + " • If the device grants the request, the ARL attribute in the Access Control Cluster shall be " + + " updated to reflect the new access rights and a successful response shall be returned to the " + + " device making the request using the MTaer field of the callbackUrl. If the request is denied, " + + " the ARL attribute shall remain unchanged and a failure response shall be returned to the device " + + " making the request using the MTaer field of the callbackUrl." + + "\n" + + " • The device using this mechanism shall provide a service at the URL that can accept requests for " + + " additional access and return responses indicating whether the requests were granted or denied." + + "\n" + + " • This URL will typically lead to a server which (e.g. by looking at the User-Agent) redirects " + + " the user to allow viewing, downloading, installing or using a manufacturer-provided means for " + + " guiding the user through the process to review and approve or deny the request. The device " + + " manufacturer may choose to use a constructed URL which is valid in a HTTP GET request (i.e. " + + " dedicated for the product) such as, for example, https://domain.example/arl-app?vid=FFF1& " + + " pid=1234. If a client follows or launches the ARLRequestFlowUrl, it shall expand it as " + + " described in Section 9.10.9.3.4, “ARLRequestFlowUrl format”." + + "\n" + + " • A manufacturer contemplating using this flow should realize that" + + "\n" + + " ◦ This flow typically requires internet access to access the URL, and access extension may fail " + + " when internet connectivity is not available." + + "\n" + + " ◦ If the flow prefers to redirect the user to an app which is available on popular platforms, " + + " it SHOULD also provide a fallback option such as a web browser interface to ensure users can " + + " complete access extension." + + "\n" + + "### ARLRequestFlowUrl format" + + "\n" + + "The ARLRequestFlowUrl shall contain a query component (see RFC 3986 section 3.4) composed of one or " + + "more key-value pairs:" + + "\n" + + " • The query shall use the & delimiter between key/value pairs." + + "\n" + + " • The key-value pairs shall in the format name= where name is the key name, and " + + "\n" + + "is the contents of the value encoded with proper URL-encoded escaping." + + "\n" + + " • If key MTcu is present, it shall have a value of \"_\" (i.e. MTcu=_). This is the \"callback URL" + + "\n" + + "backUrl) placeholder\"." + + "\n" + + " • Any key whose name begins with MT not mentioned in the previous bullets shall be reserved for " + + " future use by this specification. Manufacturers shall NOT include query keys starting with MT " + + " in the ARLRequestFlowUrl unless they are referenced by a version of this specification." + + "\n" + + "Any other element in the ARLRequestFlowUrl query field not covered by the above rules, as well as " + + "the fragment field (if present), shall remain including the order of query key/value pairs present." + + "\n" + + "Expansion of ARLRequestFlowUrl by client" + + "\n" + + "Once the URL is obtained, it shall be expanded to form a final URL (ExpandedARLRequestFlowUrl) by " + + "proceeding with the following substitution algorithm on the original ARLRequestFlowUrl:" + + "\n" + + " 1. If key MTcu is present, compute the CallbackUrl desired (see Section 9.10.9.3.5, “CallbackUrl " + + " format for ARL Request Flow response”), and substitute the placeholder value \"_\" (i.e. in " + + " MTcu=_) in the ARLRequestFlowUrl with the desired contents, encoded with proper URL-encoded " + + " escaping (see RFC 3986 section 2)." + + "\n" + + "The final URL after expansion (ExpandedARLRequestFlowUrl) shall be the one to follow, rather than " + + "the original value obtained from the FabricRestrictionReviewUpdate event." + + "\n" + + "### CallbackUrl format for ARL Request Flow response" + + "\n" + + "If a CallbackUrl field (i.e. MTcu=) query field placeholder is present in the ARLRequestFlowUrl, " + + "the client may replace the placeholder value \"_\" in the ExpandedARLRequestFlowUrl with a URL that " + + "the manufacturer flow can use to make a smooth return to the client when the ARL flow has " + + "terminated." + + "\n" + + "This URL field may contain a query component (see RFC 3986 section 3.4). If a query is present, it " + + "shall be composed of one or more key-value pairs:" + + "\n" + + " • The query shall use the & delimiter between key/value pairs." + + "\n" + + " • The key-value pairs shall follow the format name= where name is the key name, and" + + "\n" + + " is the contents of the value encoded with proper URL-encoded escaping." + + "\n" + + " • If key MTaer is present, it shall have a value of \"_\" (i.e. MTaer=_). This is the placeholder " + + " for a \"access extension response\" provided by the manufacturer flow to the client. The " + + " manufacturer flow shall replace this placeholder with the final status of the access extension " + + " request, which shall be formatted following Expansion of CallbackUrl by the manufacturer custom " + + " flow and encoded with proper URL-encoded escaping." + + "\n" + + " • Any key whose name begins with MT not mentioned in the previous bullets shall be reserved for " + + " future use by this specification." + + "\n" + + "Any other element in the CallbackUrl query field not covered by the above rules, as well as the frag" + + "\n" + + "ment field (if present), shall remain as provided by the client through embedding within the" + + "\n" + + "ExpandedARLRequestFlowUrl, including the order of query key/value pairs present." + + "\n" + + "### Expansion of CallbackUrl by the manufacturer custom flow" + + "\n" + + "Once the CallbackUrl is obtained by the manufacturer flow, it may be expanded to form a final " + + "ExpandedARLRequestCallbackUrl URL to be used by proceeding with the following substitution " + + "algorithm on the provided CallbackUrl:" + + "\n" + + " • If key MTaer is present, the manufacturer custom flow having received the initial query " + + " containing the CallbackUrl shall substitute the placeholder value \"_\" (i.e. in MTaer=_) in the " + + " CallbackUrl with the final status of the access extension request flow which shall be one of " + + " the following. Any value returned in the MTaer field not listed above shall be considered an " + + " error and shall be treated as GeneralFailure." + + "\n" + + " ◦ Success - The flow completed successfully and the ARL attribute was updated. The client may " + + " now read the ARL attribute to determine the new access restrictions." + + "\n" + + " ◦ NoChange - The ARL attribute was already listing minimum restrictions for the requesting " + + " fabric." + + "\n" + + " ◦ GeneralFailure - The flow failed for an unspecified reason." + + "\n" + + " ◦ FlowAuthFailure - The user failed to authenticate to the flow." + + "\n" + + " ◦ NotFound - Access extension failed because the target fabric was not found." + + "\n" + + "A manufacturer custom flow having received an ExpandedARLRequestFlowUrl SHOULD attempt to open the " + + "ExpandedARLRequestCallbackUrl, on completion of the request, if an ExpandedARLRequestCallbackUrl " + + "was computed from the CallbackUrl and opening such a URL is supported." + + "\n" + + "Examples of ARLRequestFlowUrl URLs" + + "\n" + + "Below are some examples of valid ExpandedARLRequestFlowUrl for several valid values of " + + "ARLRequestFlowUrl, as well as some examples of invalid values of ARLRequestFlowUrl:" + + "\n" + + " • Invalid URL with no query string: http scheme is not allowed:" + + "\n" + + " ◦ http://company.domain.example/matter/arl/vFFF1p1234" + + "\n" + + " • Valid URL :" + + "\n" + + " ◦ https://company.domain.example/matter/arl/vFFF1p1234" + + "\n" + + " • Valid URL, CallbackUrl requested:" + + "\n" + + " ◦ Before expansion:" + + "\n" + + "https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTcu=_" + + "\n" + + " ◦ After expansion:" + + "\n" + + "https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTcu=https%3A%2F%2Fc " + + "lient.domain.example%2Fcb%3Ftoken%3DmAsJ6_vqbr-vjDiG_w%253D%253D%26MTaer%3D_" + + "\n" + + " ◦ The ExpandedARLRequestFlowUrl URL contains:" + + "\n" + + " ▪ A CallbackUrl with a client-provided arbitrary token= key/value pair and the MTaer= key/value " + + " pair place-holder to indicate support for a return access extension completion status: " + + " https://client.domain.example/cb?token=mAsJ6_vqbr-vjDiG_w%3D%3D&MTaer=_" + + "\n" + + " ▪ After expansion of the CallbackUrl (MTcu key) into an ExpandedCallbackUrl, with an example " + + " return access extension completion status of Success, the ExpandedARLRequestCallbackUrl would " + + " be:" + + "\n" + + "https://client.domain.example/cb?token=mAsJ6_vqbr- vjDiG_w%3D%3D&MTaer=Success" + + "\n" + + "Note that the MTcu key/value pair was initially provided URL-encoded within the " + + "ExpandedARLRequestFlowUrl URL and the MTaer=_ key/value pair placeholder now contains a substituted " + + "returned completion status." + + "\n" + + " • Invalid URL, due to MTza=79 key/value pair in reserved MT-prefixed keys reserved for future use:" + + "\n" + + " ◦ https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTop=_&MTza=79", + + xref: { document: "core", section: "9.10.9.3.3" } + } + ), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Command( + { + name: "ReviewFabricRestrictions", id: 0x0, access: "F A", conformance: "MNGD", direction: "request", + response: "ReviewFabricRestrictionsResponse", + + details: "This command signals to the service associated with the device vendor that the fabric administrator " + + "would like a review of the current restrictions on the accessing fabric. This command includes an " + + "optional list of ARL entries that the fabric administrator would like removed." + + "\n" + + "In response, a ReviewFabricRestrictionsResponse is sent which contains a token that can be used to " + + "correlate a review request with a FabricRestrictionReviewUpdate event." + + "\n" + + "Within 1 hour of the ReviewFabricRestrictionsResponse, the FabricRestrictionReviewUpdate event " + + "shall be generated, in order to indicate completion of the review and any additional steps required " + + "by the user for the review." + + "\n" + + "A review may include obtaining consent from the user, which can take time. For example, the user " + + "may need to respond to an email or a push notification." + + "\n" + + "The ARL attribute may change at any time due to actions taken by the user, or the service " + + "associated with the device vendor.", + + xref: { document: "core", section: "9.10.8.1" } + }, + + Field( + { + name: "Arl", id: 0x0, type: "list", conformance: "M", constraint: "desc", + details: "When the ARL field is provided, it indicates the specific restrictions that are requested for " + + "review. An empty list represents a generic request for review of all restrictions.", + xref: { document: "core", section: "9.10.8.1.1" } + }, + + Field({ name: "entry", type: "CommissioningAccessRestrictionEntryStruct" }) + ) + ), + + Command( + { + name: "ReviewFabricRestrictionsResponse", id: 0x1, conformance: "MNGD", direction: "response", + details: "Returns the review token for the request, which can be used to correlate with a " + + "FabricRestrictionReviewUpdate event.", + xref: { document: "core", section: "9.10.8.2" } + }, + + Field({ + name: "Token", id: 0x0, type: "uint64", conformance: "M", + details: "This field shall specify a Token that can be used to correlate a ReviewFabricRestrictionsResponse " + + "with a FabricRestrictionReviewUpdate event.", + xref: { document: "core", section: "9.10.8.2.1" } + }) + ), + + Datatype( + { name: "ChangeTypeEnum", type: "enum8", xref: { document: "core", section: "9.10.5.1" } }, + Field({ name: "Changed", id: 0x0, conformance: "M", description: "Entry or extension was changed" }), + Field({ name: "Added", id: 0x1, conformance: "M", description: "Entry or extension was added" }), + Field({ name: "Removed", id: 0x2, conformance: "M", description: "Entry or extension was removed" }) + ), + + Datatype( + { + name: "AccessControlEntryPrivilegeEnum", type: "enum8", + details: "Proxy View Value" + + "\n" + + "This value implicitly grants View privileges", + xref: { document: "core", section: "9.10.5.2" } + }, + + Field({ + name: "View", id: 0x1, conformance: "M", + description: "Can read and observe all (except Access Control Cluster and as seen by a non-Proxy)" + }), + Field({ + name: "ProxyView", id: 0x2, conformance: "P, M", + description: "Can read and observe all (as seen by a Proxy)" + }), + + Field({ + name: "Operate", id: 0x3, conformance: "M", + description: "View privileges, and can perform the primary function of this Node (except Access Control Cluster)", + details: "This value implicitly grants View privileges", + xref: { document: "core", section: "9.10.5.2.1" } + }), + + Field({ + name: "Manage", id: 0x4, conformance: "M", + description: "Operate privileges, and can modify persistent configuration of this Node (except Access Control Cluster)", + details: "This value implicitly grants Operate & View privileges", + xref: { document: "core", section: "9.10.5.2.2" } + }), + + Field({ + name: "Administer", id: 0x5, conformance: "M", + description: "Manage privileges, and can observe and modify the Access Control Cluster", + details: "This value implicitly grants Manage, Operate, Proxy View & View privileges", + xref: { document: "core", section: "9.10.5.2.3" } + }) + ), + + Datatype( + { name: "AccessRestrictionTypeEnum", type: "enum8", xref: { document: "core", section: "9.10.5.3" } }, + Field({ + name: "AttributeAccessForbidden", id: 0x0, conformance: "M", + description: "Clients on this fabric are currently forbidden from reading and writing an attribute" + }), + Field({ + name: "AttributeWriteForbidden", id: 0x1, conformance: "M", + description: "Clients on this fabric are currently forbidden from writing an attribute" + }), + Field({ + name: "CommandForbidden", id: 0x2, conformance: "M", + description: "Clients on this fabric are currently forbidden from invoking a command" + }), + Field({ + name: "EventForbidden", id: 0x3, conformance: "M", + description: "Clients on this fabric are currently forbidden from reading an event" + }) + ), + + Datatype( + { name: "AccessControlEntryAuthModeEnum", type: "enum8", xref: { document: "core", section: "9.10.5.4" } }, + Field({ name: "Pase", id: 0x1, conformance: "M", description: "Passcode authenticated session" }), + Field({ name: "Case", id: 0x2, conformance: "M", description: "Certificate authenticated session" }), + Field({ name: "Group", id: 0x3, conformance: "M", description: "Group authenticated session" }) + ), + + Datatype( + { name: "AccessControlTargetStruct", type: "struct", xref: { document: "core", section: "9.10.5.5" } }, + Field({ name: "Cluster", id: 0x0, type: "cluster-id", conformance: "M", quality: "X" }), + Field({ name: "Endpoint", id: 0x1, type: "endpoint-no", conformance: "M", quality: "X" }), + Field({ name: "DeviceType", id: 0x2, type: "devtype-id", conformance: "M", quality: "X" }) + ), + + Datatype( + { name: "AccessControlEntryStruct", type: "struct", xref: { document: "core", section: "9.10.5.6" } }, + + Field({ + name: "Privilege", id: 0x1, type: "AccessControlEntryPrivilegeEnum", access: "S", conformance: "M", + + details: "The privilege field shall specify the level of privilege granted by this Access Control Entry." + + "\n" + + "NOTE The Proxy View privilege is provisional." + + "\n" + + "Each privilege builds upon its predecessor, expanding the set of actions that can be performed upon " + + "a Node. Administer is the highest privilege, and is special as it pertains to the administration of " + + "privileges itself, via the Access Control Cluster." + + "\n" + + "When a Node is granted a particular privilege, it is also implicitly granted all logically lower " + + "privilege levels as well. The following diagram illustrates how the higher privilege levels subsume " + + "the lower privilege levels:" + + "\n" + + "Figure 46. Access Control Privilege Levels" + + "\n" + + "Individual clusters shall define whether attributes are readable, writable, or both readable and " + + "writable. Clusters also shall define which privilege is minimally required to be able to perform a " + + "particular read or write action on those attributes, or invoke particular commands. Device type " + + "specifications may further restrict the privilege required." + + "\n" + + "The Access Control Cluster shall require the Administer privilege to observe and modify the Access " + + "Control Cluster itself. The Administer privilege shall NOT be used on Access Control Entries which " + + "use the Group auth mode.", + + xref: { document: "core", section: "9.10.5.6.1" } + }), + + Field({ + name: "AuthMode", id: 0x2, type: "AccessControlEntryAuthModeEnum", access: "S", conformance: "M", + details: "The AuthMode field shall specify the authentication mode required by this Access Control Entry.", + xref: { document: "core", section: "9.10.5.6.2" } + }), + + Field( + { + name: "Subjects", id: 0x3, type: "list", access: "S", conformance: "M", + constraint: "max subjectsPerAccessControlEntry", quality: "X", + + details: "The subjects field shall specify a list of Subject IDs, to which this Access Control Entry grants " + + "access." + + "\n" + + "Device types may impose additional constraints on the minimum number of subjects per Access Control " + + "Entry." + + "\n" + + "An attempt to create an entry with more subjects than the node can support shall result in a " + + "RESOURCE_EXHAUSTED error and the entry shall NOT be created." + + "\n" + + "### Subject ID shall be of type uint64 with semantics depending on the entry’s AuthMode as follows:" + + "\n" + + "Subject Semantics" + + "\n" + + "An empty subjects list indicates a wildcard; that is, this entry shall grant access to any Node " + + "that successfully authenticates via AuthMode. The subjects list shall NOT be empty if the entry’s " + + "AuthMode is PASE." + + "\n" + + "The PASE AuthMode is reserved for future use (see Section 6.6.2.9, “Bootstrapping of the Access " + + "Control Cluster”). An attempt to write an entry with AuthMode set to PASE shall fail with a status " + + "code of CONSTRAINT_ERROR." + + "\n" + + "For PASE authentication, the Passcode ID identifies the required passcode verifier, and shall be 0 " + + "for the default commissioning passcode." + + "\n" + + "For CASE authentication, the Subject ID is a distinguished name within the Operational Certificate " + + "shared during CASE session establishment, the type of which is determined by its range to be one of:" + + "\n" + + " • a Node ID, which identifies the required source node directly (by ID)" + + "\n" + + " • a CASE Authenticated Tag, which identifies the required source node indirectly (by tag)" + + "\n" + + "For Group authentication, the Group ID identifies the required group, as defined in the Group Key " + + "Management Cluster.", + + xref: { document: "core", section: "9.10.5.6.3" } + }, + + Field({ name: "entry", type: "subject-id" }) + ), + + Field( + { + name: "Targets", id: 0x4, type: "list", access: "S", conformance: "M", + constraint: "max targetsPerAccessControlEntry", quality: "X", + + details: "The targets field shall specify a list of AccessControlTargetStruct, which define the clusters on " + + "this Node to which this Access Control Entry grants access." + + "\n" + + "Device types may impose additional constraints on the minimum number of targets per Access Control " + + "Entry." + + "\n" + + "An attempt to create an entry with more targets than the node can support shall result in a " + + "RESOURCE_EXHAUSTED error and the entry shall NOT be created." + + "\n" + + "A single target shall contain at least one field (Cluster, Endpoint, or DeviceType), and shall NOT " + + "contain both an Endpoint field and a DeviceType field." + + "\n" + + "A target grants access based on the presence of fields as follows:" + + "\n" + + "Target Semantics" + + "\n" + + "An empty targets list indicates a wildcard: that is, this entry shall grant access to all cluster " + + "instances on all endpoints on this Node.", + + xref: { document: "core", section: "9.10.5.6.4" } + }, + + Field({ name: "entry", type: "AccessControlTargetStruct" }) + ), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "AccessControlExtensionStruct", type: "struct", xref: { document: "core", section: "9.10.5.7" } }, + + Field({ + name: "Data", id: 0x1, type: "octstr", access: "S", conformance: "M", constraint: "max 128", + + details: "This field may be used by manufacturers to store arbitrary TLV-encoded data related to a fabric’s" + + "\n" + + "Access Control Entries." + + "\n" + + "The contents shall consist of a top-level anonymous list; each list element shall include a " + + "profile-specific tag encoded in fully-qualified form." + + "\n" + + "Administrators may iterate over this list of elements, and interpret selected elements at their " + + "discretion. The content of each element is not specified, but may be coordinated among " + + "manufacturers at their discretion.", + + xref: { document: "core", section: "9.10.5.7.1" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "AccessRestrictionStruct", type: "struct", + details: "This structure describes an access restriction that would be applied to a specific data model " + + "element on a given endpoint/cluster pair (see AccessRestrictionEntryStruct).", + xref: { document: "core", section: "9.10.5.8" } + }, + + Field({ + name: "Type", id: 0x0, type: "AccessRestrictionTypeEnum", conformance: "M", + details: "This field shall indicate the type of restriction, for example, AttributeAccessForbidden.", + xref: { document: "core", section: "9.10.5.8.1" } + }), + + Field({ + name: "Id", id: 0x1, type: "uint32", conformance: "M", quality: "X", + + details: "This field shall indicate the element Manufacturer Extensible Identifier (MEI) associated with the " + + "element type subject to the access restriction, based upon the AccessRestrictionTypeEnum. When the " + + "Type is AttributeAccessForbidden or AttributeWriteForbidden, this value shall be considered of type " + + "attrib-id (i.e. an attribute identifier). When the Type is CommandForbidden, this value shall be " + + "considered of type command-id (i.e. an attribute identifier). When the Type is EventForbidden, this " + + "value shall be considered of type event-id (i.e. an event identifier)." + + "\n" + + "A null value shall indicate the wildcard value for the given value of Type (i.e. all elements " + + "associated with the Type under the associated endpoint and cluster for the containing " + + "AccessRestrictionEntryStruct).", + + xref: { document: "core", section: "9.10.5.8.2" } + }) + ), + + Datatype( + { + name: "AccessRestrictionEntryStruct", type: "struct", + details: "This structure describes a current access restriction on the fabric.", + xref: { document: "core", section: "9.10.5.9" } + }, + + Field({ + name: "Endpoint", id: 0x0, type: "endpoint-no", access: "S", conformance: "M", + details: "This field shall indicate the endpoint having associated access restrictions scoped to the " + + "associated fabric of the list containing the entry.", + xref: { document: "core", section: "9.10.5.9.1" } + }), + + Field({ + name: "Cluster", id: 0x1, type: "cluster-id", access: "S", conformance: "M", + details: "This field shall indicate the cluster having associated access restrictions under the entry’s " + + "Endpoint, scoped to the associated fabric of the list containing the entry.", + xref: { document: "core", section: "9.10.5.9.2" } + }), + + Field( + { + name: "Restrictions", id: 0x2, type: "list", access: "S", conformance: "M", constraint: "min 1", + details: "This field shall indicate the set of restrictions applying to the Cluster under the given Endpoint, " + + "scoped to the associated fabric of the list containing the entry." + + "\n" + + "This list shall NOT be empty.", + xref: { document: "core", section: "9.10.5.9.3" } + }, + + Field({ name: "entry", type: "AccessRestrictionStruct" }) + ), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "CommissioningAccessRestrictionEntryStruct", type: "struct", + details: "This structure describes a current access restriction when there is no accessing fabric.", + xref: { document: "core", section: "9.10.5.10" } + }, + + Field({ + name: "Endpoint", id: 0x0, type: "endpoint-no", conformance: "M", + details: "This field shall indicate the endpoint having associated access restrictions scoped to the " + + "associated fabric of the list containing the entry.", + xref: { document: "core", section: "9.10.5.10.1" } + }), + + Field({ + name: "Cluster", id: 0x1, type: "cluster-id", conformance: "M", + details: "This field shall indicate the cluster having associated access restrictions under the entry’s " + + "Endpoint, scoped to the associated fabric of the list containing the entry.", + xref: { document: "core", section: "9.10.5.10.2" } + }), + + Field( + { + name: "Restrictions", id: 0x2, type: "list", conformance: "M", constraint: "min 1", + details: "This field shall indicate the set of restrictions applying to the Cluster under the given Endpoint, " + + "scoped to the associated fabric of the list containing the entry." + + "\n" + + "This list shall NOT be empty.", + xref: { document: "core", section: "9.10.5.10.3" } + }, + + Field({ name: "entry", type: "AccessRestrictionStruct" }) + ) + ) + ), + + Cluster( + { + name: "BridgedDeviceBasicInformation", id: 0x39, type: "BasicInformation", + classification: "endpoint", pics: "BRBINFO", + + details: "This cluster is a derived cluster of the Basic Information cluster and serves two purposes towards " + + "a Node communicating with a Bridge:" + + "\n" + + " • Indicate that the functionality on the Endpoint where it is placed (and its Parts) is bridged, " + + " and" + + "\n" + + " • Provide a centralized collection of attributes that the Node may collect to aid in conveying " + + " information regarding the Bridged Device to a user, such as the vendor name, the model name, or " + + " user-assigned name." + + "\n" + + "This cluster shall be exposed by a Bridge on the Endpoint representing each Bridged Device. When " + + "the functionality of a Bridged Device is represented using a set of Endpoints, this cluster shall " + + "only be exposed on the Endpoint which is at the top of the hierarchy for the functionality of that " + + "Bridged Device." + + "\n" + + "This cluster shall NOT be used on an endpoint that is not in the Descriptor cluster PartsList of an " + + "endpoint with an Aggregator device type." + + "\n" + + "This cluster has been derived from the Basic Information Cluster, and provides generic information " + + "about the Bridged Device. Not all of the attributes in the Basic Information Cluster are relevant " + + "for a Bridged Device (e.g. ProductID since it is not a Matter device). For other attributes, the " + + "information which is listed as Mandatory for the Basic Information Cluster, may not be available " + + "when the Bridged Device does not provide it to the Bridge, and the Bridge has no other means to " + + "determine it. For such cases where the information for a particular attribute is not available, the " + + "Bridge SHOULD NOT include the attribute in the cluster for this Bridged Device. See below for " + + "Conformance details.", + + xref: { document: "core", section: "9.13" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "9.13.4" } }, + Field({ + name: "BIS", conformance: "O", constraint: "20", description: "BridgedIcdSupport", + details: "Support bridged ICDs." + }) + ), + + Attribute({ name: "DataModelRevision", id: 0x0, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "VendorName", id: 0x1, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "VendorId", id: 0x2, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductName", id: 0x3, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductId", id: 0x4, conformance: "desc", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "NodeLabel", id: 0x5, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "Location", id: 0x6, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "HardwareVersion", id: 0x7, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute( + { name: "HardwareVersionString", id: 0x8, conformance: "O", xref: { document: "core", section: "9.13.5" } } + ), + Attribute({ name: "SoftwareVersion", id: 0x9, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute( + { name: "SoftwareVersionString", id: 0xa, conformance: "O", xref: { document: "core", section: "9.13.5" } } + ), + Attribute({ name: "ManufacturingDate", id: 0xb, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "PartNumber", id: 0xc, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductUrl", id: 0xd, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductLabel", id: 0xe, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "SerialNumber", id: 0xf, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute( + { name: "LocalConfigDisabled", id: 0x10, conformance: "X", xref: { document: "core", section: "9.13.5" } } + ), + + Attribute({ + name: "Reachable", id: 0x11, conformance: "M", + + details: "This attribute shall be used to indicate whether the bridged device is reachable by the bridge, so " + + "a Matter Node which wants to communicate with a bridged device can get an indication that this " + + "might fail (when the attribute is False). Determination of reachability might not be perfect (e.g. " + + "depending on technology employed), so the Matter Node SHOULD be aware of the risk of false " + + "positives and negatives on reachability determination. For example, a bridged device may be marked " + + "as unreachable while it could actually be reached, and vice-versa. Also, detection (and indication) " + + "that a bridged device is not longer reachable may be delayed due to the technique employed (e.g. " + + "detecting that a number of expected messages from the bridged device did not arrive). Also see " + + "event ReachableChanged below.", + + xref: { document: "core", section: "9.13.5.1" } + }), + + Attribute({ + name: "UniqueId", id: 0x12, conformance: "M", + + details: "This attribute shall, for a Bridged Device, be updated when the Bridge is factory reset. If the " + + "bridged device does not provide some unique id (e.g. in the case of bridging from non-Matter " + + "devices, or in case of bridging Matter devices from an earlier revision which were not required to " + + "provide a UniqueID attribute), the bridge shall generate a unique id on behalf of the bridged " + + "device." + + "\n" + + "NOTE The UniqueID attribute was optional in cluster revisions prior to revision 4.", + + xref: { document: "core", section: "9.13.5.2" } + }), + + Attribute({ name: "CapabilityMinima", id: 0x13, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductAppearance", id: 0x14, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute( + { name: "SpecificationVersion", id: 0x15, conformance: "X", xref: { document: "core", section: "9.13.5" } } + ), + Attribute({ name: "MaxPathsPerInvoke", id: 0x16, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Event({ + name: "StartUp", id: 0x0, conformance: "O", priority: "critical", + xref: { document: "core", section: "9.13.7" } + }), + Event({ + name: "ShutDown", id: 0x1, conformance: "O", priority: "critical", + xref: { document: "core", section: "9.13.7" } + }), + + Event( + { + name: "Leave", id: 0x2, conformance: "O", priority: "critical", + + details: "The Leave event SHOULD be generated by the bridge when it detects that the associated device has " + + "left the non-Matter network." + + "\n" + + "NOTE" + + "\n" + + "The FabricIndex field has the X conformance, indicating it shall NOT be present. This event, in the " + + "context of Bridged Device Basic Information cluster, has no usable fields, but the original Basic " + + "Information cluster’s field definition is kept for completeness.", + + xref: { document: "core", section: "9.13.7.1" } + }, + + Field({ name: "FabricIndex", id: 0x0, conformance: "X" }) + ), + + Event({ + name: "ReachableChanged", id: 0x3, conformance: "M", priority: "critical", + details: "This event shall be generated when there is a change in the Reachable attribute. Its purpose is to " + + "provide an indication towards interested parties that the reachability of a bridged device has " + + "changed over its native connectivity technology, so they may take appropriate action." + + "\n" + + "After (re)start of a bridge this event may be generated.", + xref: { document: "core", section: "9.13.7.2" } + }), + + Event( + { + name: "ActiveChanged", id: 0x80, access: "V", conformance: "BIS", priority: "info", + details: "This event (when supported) shall be generated the next time a bridged device becomes active after " + + "a KeepActive command is received." + + "\n" + + "See KeepActive for more details.", + xref: { document: "core", section: "9.13.7.3" } + }, + + Field({ + name: "PromisedActiveDuration", id: 0x0, type: "uint32", conformance: "M", constraint: "desc", + + details: "This field shall indicate the minimum duration, in milliseconds, that the bridged device will " + + "remain active after receiving the initial request from the KeepActive processing steps." + + "\n" + + "If the bridged device is a Matter Intermittently Connected Device, PromisedActiveDuration shall be " + + "set to the PromisedActiveDuration value returned in the StayActiveResponse command." + + "\n" + + "If the bridged device is not a Matter Intermittently Connected Device, the implementation of this " + + "is best-effort since it may interact with non-native protocol.", + + xref: { document: "core", section: "9.13.7.3.1" } + }) + ), + + Command( + { + name: "KeepActive", id: 0x80, access: "O", conformance: "BIS", direction: "request", + response: "status", + + details: "Upon receipt, the server shall attempt to keep the bridged device active for the duration specified " + + "by the command, when the device is next active." + + "\n" + + "The implementation of this is best-effort since it may interact with non-native protocols. However, " + + "several specific protocol requirements are:" + + "\n" + + " • If the bridged device is a Matter Intermittently Connected Device, then the server shall send a " + + " StayActiveRequest command with the StayActiveDuration field set to value of the " + + " StayActiveDuration field in the received command to the bridged device when the bridged device " + + " next sends a checks-in message or subscription report. See Intermittently Connected Devices " + + " Behavior for details on ICD state management." + + "\n" + + "When the bridge detects that the bridged device goes into an active state, an ActiveChanged event " + + "shall be generated." + + "\n" + + "In order to avoid unnecessary power consumption in the bridged device:" + + "\n" + + " • The server shall enter a \"pending active\" state for the associated device when the KeepActive " + + " command is received. The server \"pending active\" state shall expire after the amount of time " + + " defined by the TimeoutMs field, in milliseconds, if no subsequent KeepActive command is " + + " received. When a KeepActive command is received, the \"pending active\" state is set, the " + + " StayActiveDuration is updated to the greater of the new value and the previously stored value, " + + " and the TimeoutMs is updated to the greater of the new value and the remaining time until the " + + " prior \"pending active\" state expires." + + "\n" + + " • The server shall only keep the bridged device active once for a request. (The server shall only " + + " consider the operation performed if an associated ActiveChanged event was generated.)", + + xref: { document: "core", section: "9.13.6.1" } + }, + + Field({ + name: "StayActiveDuration", id: 0x0, type: "uint32", conformance: "M", + + details: "This field shall indicate the duration, in milliseconds, that the device is requested to remain " + + "active, once the device becomes active again." + + "\n" + + "The value of this field may be longer than the value supported by the bridged device and would, " + + "typically, be used by the client to request the server of the bridged device to stay active and " + + "responsive for this period to allow a sequence of message exchanges during that period." + + "\n" + + "The client may slightly overestimate the duration it wants the bridged device to be active for, in " + + "order to account for network delays.", + + xref: { document: "core", section: "9.13.6.1.1" } + }), + + Field({ + name: "TimeoutMs", id: 0x1, type: "uint32", conformance: "M", constraint: "30000 to 3600000", + + details: "This field shall indicate the period, in milliseconds, that the server will wait before the " + + "\"pending active\" state expires. See the KeepActive Command description for details." + + "\n" + + "NOTE" + + "\n" + + "TimeoutMs is a timeout for the request, NOT the time the device will be awake for. The server will " + + "wait for up to TimeoutMs for the device. If after TimeoutMs the ICD" + + "\n" + + "device does NOT check-in, the server will not perform any actions.", + + xref: { document: "core", section: "9.13.6.1.2" } + }) + ) + ), + + Cluster( + { + name: "Actions", id: 0x25, classification: "application", pics: "ACT", + + details: "This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to " + + "expose" + + "\n" + + " • Information about logical grouping of endpoints on the Node (example: lights in a room)" + + "\n" + + " • Information about named actions that can be performed on such a group of endpoints (example: " + + " recall a scene for a group of lights by its name)" + + "\n" + + " • Commands to trigger such actions" + + "\n" + + " • Events to receive feedback on the state of such actions." + + "\n" + + "The information on grouping and available actions is typically provided by the user or Bridge " + + "manufacturer via some means not defined in Matter, and therefore provided as read-only to Nodes. " + + "For example: a manufacturer-provided app allows a user to set up logical grouping and create/assign " + + "scene for such groups." + + "\n" + + "Using this cluster, a Node can learn about such logical grouping, provided actions, and trigger " + + "such actions." + + "\n" + + "While the origin of this cluster stems from use cases with a Bridge, its server side may also be " + + "implemented on any Node which can expose certain grouping, actions or automations to other users." + + "\n" + + "After defining the attributes, commands and events for this cluster, and the associated data types, " + + "several examples are provided to illustrate the capabilities of this cluster." + + "\n" + + "Actions can be defined in a flexible manner to suit the needs of the various nodes implementing " + + "this cluster. For each action, the commands available for that particular action are defined." + + "\n" + + "This cluster can be used to expose only the grouping of endpoints without any actions defined by " + + "populating the EndpointList attribute accordingly and providing an empty list for ActionList." + + "\n" + + "The term 'action' in the description of this cluster should not be confused with the term 'action' " + + "as used in the Interaction Model.", + + xref: { document: "core", section: "9.14" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "ActionList", id: 0x0, type: "list", access: "R V", conformance: "M", constraint: "max 256", + default: [], + details: "The ActionList attribute holds the list of actions. Each entry shall have an unique ActionID, and " + + "its EndpointListID shall exist in the EndpointLists attribute.", + xref: { document: "core", section: "9.14.5.1" } + }, + + Field({ name: "entry", type: "ActionStruct" }) + ), + + Attribute( + { + name: "EndpointLists", id: 0x1, type: "list", access: "R V", conformance: "M", + constraint: "max 256", default: [], + details: "The EndpointLists attribute holds the list of endpoint lists. Each entry shall have an unique " + + "EndpointListID.", + xref: { document: "core", section: "9.14.5.2" } + }, + + Field({ name: "entry", type: "EndpointListStruct" }) + ), + + Attribute( + { + name: "SetupUrl", id: 0x2, type: "string", access: "R V", conformance: "O", constraint: "max 512", + + details: "The SetupURL attribute (when provided) shall indicate a URL; its syntax shall follow the syntax as " + + "specified in RFC 1738, max. 512 ASCII characters and shall use the https scheme. The location " + + "referenced by this URL shall provide additional information for the actions provided:" + + "\n" + + " • When used without suffix, it shall provide information about the various actions which the " + + " cluster provides." + + "\n" + + " ◦ Example: SetupURL could take the value of example://Actions or https://domain.example/ " + + " Matter/bridgev1/Actions for this generic case (access generic info how to use actions " + + " provided by this cluster)." + + "\n" + + " • When used with a suffix of \"/?a=\" and the decimal value of ActionID for one of the actions, it " + + " may provide information about that particular action. This could be a deeplink to " + + " manufacturer-app/website (associated somehow to the server node) with the " + + " information/edit-screen for this action so that the user can view and update details of the " + + " action, e.g. edit the scene, or change the wake-up experience time period." + + "\n" + + " ◦ Example of SetupURL with suffix added: example://Actions/?a=12345 or " + + " https://domain.example/Matter/bridgev1/Actions/?a=12345 for linking to specific info/editing " + + " of the action with ActionID 0x3039.", + + xref: { document: "core", section: "9.14.5.3" } + } + ), + + Event( + { + name: "StateChanged", id: 0x0, access: "V", conformance: "M", priority: "info", + + details: "This event shall be generated when there is a change in the State of an ActionID during the " + + "execution of an action and the most recent command using that ActionID used an InvokeID data field." + + "\n" + + "It provides feedback to the client about the progress of the action." + + "\n" + + "Example: When InstantActionWithTransition is invoked (with an InvokeID data field), two " + + "StateChanged events will be generated:" + + "\n" + + " • one when the transition starts (NewState=Active)" + + "\n" + + " • one when the transition completed (NewState=Inactive)", + + xref: { document: "core", section: "9.14.7.1" } + }, + + Field({ + name: "ActionId", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall be set to the ActionID of the action which has changed state.", + xref: { document: "core", section: "9.14.7.1.1" } + }), + + Field({ + name: "InvokeId", id: 0x1, type: "uint32", conformance: "M", + details: "This field shall be set to the InvokeID which was provided to the most recent command referencing " + + "this ActionID.", + xref: { document: "core", section: "9.14.7.1.2" } + }), + + Field({ + name: "NewState", id: 0x2, type: "ActionStateEnum", conformance: "M", + details: "This field shall be set to state that the action has changed to.", + xref: { document: "core", section: "9.14.7.1.3" } + }) + ), + + Event( + { + name: "ActionFailed", id: 0x1, access: "V", conformance: "M", priority: "info", + + details: "This event shall be generated when there is some error which prevents the action from its normal " + + "planned execution and the most recent command using that ActionID used an InvokeID data field." + + "\n" + + "It provides feedback to the client about the non-successful progress of the action." + + "\n" + + "Example: When InstantActionWithTransition is invoked (with an InvokeID data field), and another " + + "controller changes the state of one or more of the involved endpoints during the transition, thus " + + "interrupting the transition triggered by the action, two events would be generated:" + + "\n" + + " • StateChanged when the transition starts (NewState=Active)" + + "\n" + + " • ActionFailed when the interrupting command occurs (NewState=Inactive, Error=interrupted)" + + "\n" + + "Example: When InstantActionWithTransition is invoked (with an InvokeID data field = 1), and the " + + "same client invokes an InstantAction with (the same or another ActionId and) InvokeID = 2, and this " + + "second command interrupts the transition triggered by the first command, these events would be " + + "generated:" + + "\n" + + " • StateChanged (InvokeID=1, NewState=Active) when the transition starts" + + "\n" + + " • ActionFailed (InvokeID=2, NewState=Inactive, Error=interrupted) when the second command " + + " interrupts the transition" + + "\n" + + " • StateChanged (InvokeID=2, NewState=Inactive) upon the execution of the action for the second " + + " command", + + xref: { document: "core", section: "9.14.7.2" } + }, + + Field({ + name: "ActionId", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall be set to the ActionID of the action which encountered an error.", + xref: { document: "core", section: "9.14.7.2.1" } + }), + + Field({ + name: "InvokeId", id: 0x1, type: "uint32", conformance: "M", + details: "This field shall be set to the InvokeID which was provided to the most recent command referencing " + + "this ActionID.", + xref: { document: "core", section: "9.14.7.2.2" } + }), + + Field({ + name: "NewState", id: 0x2, type: "ActionStateEnum", conformance: "M", + details: "This field shall be set to state that the action is in at the time of generating the event.", + xref: { document: "core", section: "9.14.7.2.3" } + }), + Field({ + name: "Error", id: 0x3, type: "ActionErrorEnum", conformance: "M", + details: "This field shall be set to indicate the reason for non-successful progress of the action.", + xref: { document: "core", section: "9.14.7.2.4" } + }) + ), + + Command( + { + name: "InstantAction", id: 0x0, access: "O", conformance: "desc", direction: "request", + response: "status", + details: "This command triggers an action (state change) on the involved endpoints, in a \"fire and forget\" " + + "manner. Afterwards, the action’s state shall be Inactive." + + "\n" + + "Example: recall a scene on a number of lights.", + xref: { document: "core", section: "9.14.6.1" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }) + ), + + Command( + { + name: "InstantActionWithTransition", id: 0x1, access: "O", conformance: "desc", + direction: "request", response: "status", + + details: "It is recommended that, where possible (e.g., it is not possible for attributes with Boolean data " + + "type), a gradual transition SHOULD take place from the old to the new state over this time period. " + + "However, the exact transition is manufacturer dependent." + + "\n" + + "This command triggers an action (state change) on the involved endpoints, with a specified time to " + + "transition from the current state to the new state. During the transition, the action’s state shall " + + "be Active. Afterwards, the action’s state shall be Inactive." + + "\n" + + "Example: recall a scene on a number of lights, with a specified transition time.", + + xref: { document: "core", section: "9.14.6.2" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }), + Field({ + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", + details: "This field shall indicate the transition time in 1/10th of seconds.", + xref: { document: "core", section: "9.14.6.2.1" } + }) + ), + + Command( + { + name: "StartAction", id: 0x2, access: "O", conformance: "desc", direction: "request", + response: "status", + + details: "This command triggers the commencement of an action on the involved endpoints. Afterwards, the " + + "action’s state shall be Active." + + "\n" + + "Example: start a dynamic lighting pattern (such as gradually rotating the colors around the " + + "setpoints of the scene) on a set of lights." + + "\n" + + "Example: start a sequence of events such as a wake-up experience involving lights moving through " + + "several brightness/color combinations and the window covering gradually opening.", + + xref: { document: "core", section: "9.14.6.3" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }) + ), + + Command( + { + name: "StartActionWithDuration", id: 0x3, access: "O", conformance: "desc", direction: "request", + response: "status", + + details: "This command triggers the commencement of an action on the involved endpoints, and shall change the " + + "action’s state to Active. After the specified Duration, the action will stop, and the action’s " + + "state shall change to Inactive." + + "\n" + + "Example: start a dynamic lighting pattern (such as gradually rotating the colors around the " + + "setpoints of the scene) on a set of lights for 1 hour (Duration=3600).", + + xref: { document: "core", section: "9.14.6.4" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }), + Field({ + name: "Duration", id: 0x2, type: "uint32", conformance: "M", + details: "This field shall indicate the requested duration in seconds.", + xref: { document: "core", section: "9.14.6.4.1" } + }) + ), + + Command( + { + name: "StopAction", id: 0x4, access: "O", conformance: "desc", direction: "request", + response: "status", + details: "This command stops the ongoing action on the involved endpoints. Afterwards, the action’s state " + + "shall be Inactive." + + "\n" + + "Example: stop a dynamic lighting pattern which was previously started with StartAction.", + xref: { document: "core", section: "9.14.6.5" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }) + ), + + Command( + { + name: "PauseAction", id: 0x5, access: "O", conformance: "desc", direction: "request", + response: "status", + details: "This command pauses an ongoing action, and shall change the action’s state to Paused." + + "\n" + + "Example: pause a dynamic lighting effect (the lights stay at their current color) which was " + + "previously started with StartAction.", + xref: { document: "core", section: "9.14.6.6" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }) + ), + + Command( + { + name: "PauseActionWithDuration", id: 0x6, access: "O", conformance: "desc", direction: "request", + response: "status", + + details: "This command pauses an ongoing action, and shall change the action’s state to Paused. After the " + + "specified Duration, the ongoing action will be automatically resumed. which shall change the " + + "action’s state to Active." + + "\n" + + "Example: pause a dynamic lighting effect (the lights stay at their current color) for 10 minutes " + + "(Duration=600)." + + "\n" + + "The difference between Pause/Resume and Disable/Enable is on the one hand semantic (the former is " + + "more of a transitionary nature while the latter is more permanent) and on the other hand these can " + + "be implemented slightly differently in the implementation of the action (e.g. a Pause would be " + + "automatically resumed after some hours or during a nightly reset, while an Disable would remain in " + + "effect until explicitly enabled again).", + + xref: { document: "core", section: "9.14.6.7" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }), + Field({ + name: "Duration", id: 0x2, type: "uint32", conformance: "M", + details: "This field shall indicate the requested duration in seconds.", + xref: { document: "core", section: "9.14.6.7.1" } + }) + ), + + Command( + { + name: "ResumeAction", id: 0x7, access: "O", conformance: "desc", direction: "request", + response: "status", + + details: "This command resumes a previously paused action, and shall change the action’s state to Active." + + "\n" + + "The difference between ResumeAction and StartAction is that ResumeAction will continue the action " + + "from the state where it was paused, while StartAction will start the action from the beginning." + + "\n" + + "Example: resume a dynamic lighting effect (the lights' colors will change gradually, continuing " + + "from the point they were paused).", + + xref: { document: "core", section: "9.14.6.8" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }) + ), + + Command( + { + name: "EnableAction", id: 0x8, access: "O", conformance: "desc", direction: "request", + response: "status", + details: "This command enables a certain action or automation. Afterwards, the action’s state shall be Active." + + "\n" + + "Example: enable a motion sensor to control the lights in an area.", + xref: { document: "core", section: "9.14.6.9" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }) + ), + + Command( + { + name: "EnableActionWithDuration", id: 0x9, access: "O", conformance: "desc", direction: "request", + response: "status", + + details: "This command enables a certain action or automation, and shall change the action’s state to be " + + "Active. After the specified Duration, the action or automation will stop, and the action’s state " + + "shall change to Disabled." + + "\n" + + "Example: enable a \"presence mimicking\" behavior for the lights in your home during a vacation; the " + + "Duration field is used to indicated the length of your absence from home. After that period, the " + + "presence mimicking behavior will no longer control these lights.", + + xref: { document: "core", section: "9.14.6.10" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }), + Field({ + name: "Duration", id: 0x2, type: "uint32", conformance: "M", + details: "This field shall indicate the requested duration in seconds.", + xref: { document: "core", section: "9.14.6.10.1" } + }) + ), + + Command( + { + name: "DisableAction", id: 0xa, access: "O", conformance: "desc", direction: "request", + response: "status", + details: "This command disables a certain action or automation, and shall change the action’s state to " + + "Inactive." + + "\n" + + "Example: disable a motion sensor to no longer control the lights in an area.", + xref: { document: "core", section: "9.14.6.11" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }) + ), + + Command( + { + name: "DisableActionWithDuration", id: 0xb, access: "O", conformance: "desc", direction: "request", + response: "status", + + details: "This command disables a certain action or automation, and shall change the action’s state to " + + "Disabled. After the specified Duration, the action or automation will re-start, and the action’s " + + "state shall change to either Inactive or Active, depending on the actions (see examples 4 and 6)." + + "\n" + + "Example: disable a \"wakeup\" experience for a period of 1 week when going on holiday (to prevent " + + "them from turning on in the morning while you’re not at home). After this period, the wakeup " + + "experience will control the lights as before.", + + xref: { document: "core", section: "9.14.6.12" } + }, + + Field({ name: "ActionId", id: 0x0, type: "uint16", conformance: "M" }), + Field({ name: "InvokeId", id: 0x1, type: "uint32", conformance: "O" }), + Field({ + name: "Duration", id: 0x2, type: "uint32", conformance: "M", + details: "This field shall indicate the requested duration in seconds.", + xref: { document: "core", section: "9.14.6.12.1" } + }) + ), + + Datatype( + { + name: "CommandBits", type: "map16", + details: "Note - The bit allocation of this bitmap shall follow the ID’s of the Commands of this cluster.", + xref: { document: "core", section: "9.14.4.1" } + }, + Field({ name: "InstantAction", constraint: "0", description: "Indicate support for InstantAction command" }), + Field({ + name: "InstantActionWithTransition", constraint: "1", + description: "Indicate support for InstantActionWithTransition command" + }), + Field({ name: "StartAction", constraint: "2", description: "Indicate support for StartAction command" }), + Field({ + name: "StartActionWithDuration", constraint: "3", + description: "Indicate support for StartActionWithDuration command" + }), + Field({ name: "StopAction", constraint: "4", description: "Indicate support for StopAction command" }), + Field({ name: "PauseAction", constraint: "5", description: "Indicate support for PauseAction command" }), + Field({ + name: "PauseActionWithDuration", constraint: "6", + description: "Indicate support for PauseActionWithDuration command" + }), + Field({ name: "ResumeAction", constraint: "7", description: "Indicate support for ResumeAction command" }), + Field({ name: "EnableAction", constraint: "8", description: "Indicate support for EnableAction command" }), + Field({ + name: "EnableActionWithDuration", constraint: "9", + description: "Indicate support for EnableActionWithDuration command" + }), + Field({ name: "DisableAction", constraint: "10", description: "Indicate support for DisableAction command" }), + Field({ + name: "DisableActionWithDuration", constraint: "11", + description: "Indicate support for DisableActionWithDuration command" + }) + ), + + Datatype( + { name: "ActionTypeEnum", type: "enum8", xref: { document: "core", section: "9.14.4.2" } }, + Field({ + name: "Other", id: 0x0, conformance: "M", + description: "Use this only when none of the other values applies" + }), + + Field({ + name: "Scene", id: 0x1, conformance: "M", description: "Bring the endpoints into a certain state", + + details: "Can be used to set a static state of the associated endpoints (typically using InstantAction or " + + "InstantActionWithTransition), or to bring these endpoints into a more dynamic state (typically " + + "using StartAction), where the endpoints would e.g. gradually cycle through certain colors for a " + + "pleasing effect. A voice controller could use \"set\" (to map to InstantAction) or \"play\" (to map to " + + "StartAction) to trig" + + "\n" + + "ger such actions." + + "\n" + + "Example: see examples 1 and 2.", + + xref: { document: "core", section: "9.14.4.2.1" } + }), + + Field({ + name: "Sequence", id: 0x2, conformance: "M", + description: "A sequence of states with a certain time pattern", + details: "Indicates an action which involves a sequence of events/states of the associated endpoints, such as " + + "a wake-up experience." + + "\n" + + "Example: see example 4.", + xref: { document: "core", section: "9.14.4.2.2" } + }), + + Field({ + name: "Automation", id: 0x3, conformance: "M", + description: "Control an automation (e.g. motion sensor controlling lights)", + details: "Indications an automation (e.g. a motion sensor controlling lights, an alarm system) which can " + + "bee.g. started, stopped, paused, resumed. Example: see example 3.", + xref: { document: "core", section: "9.14.4.2.3" } + }), + + Field({ + name: "Exception", id: 0x4, conformance: "M", + description: "Sequence that will run when something doesn’t happen", + details: "Indicates some action which the server will execute when a certain condition (which normally does " + + "not happen) is not met." + + "\n" + + "Example: lock the doors when the server’s system has detected no one is at home while the doors are " + + "in the 'unlocked' state.", + xref: { document: "core", section: "9.14.4.2.4" } + }), + + Field({ + name: "Notification", id: 0x5, conformance: "M", + description: "Use the endpoints to send a message to user", + details: "Indicates an action that can be triggered (e.g. by InstantAction) to notify the user." + + "\n" + + "Example: play a pattern on the lights in the living room if there is someone in the garden in the " + + "evening.", + xref: { document: "core", section: "9.14.4.2.5" } + }), + + Field({ + name: "Alarm", id: 0x6, conformance: "M", description: "Higher priority notification", + details: "Similar to Notification but with a higher priority (and might override other endpoint states which " + + "Type=Notification would not override)." + + "\n" + + "Example: flash all lights in the house when CO sensor triggers.", + xref: { document: "core", section: "9.14.4.2.6" } + }) + ), + + Datatype( + { + name: "ActionStateEnum", type: "enum8", + details: "Note that some of these states are applicable only for certain actions, as determined by their " + + "SupportedCommands.", + xref: { document: "core", section: "9.14.4.3" } + }, + + Field({ name: "Inactive", id: 0x0, conformance: "M", description: "The action is not active" }), + Field({ name: "Active", id: 0x1, conformance: "M", description: "The action is active" }), + Field({ name: "Paused", id: 0x2, conformance: "M", description: "The action has been paused" }), + Field({ name: "Disabled", id: 0x3, conformance: "M", description: "The action has been disabled" }) + ), + + Datatype( + { name: "ActionErrorEnum", type: "enum8", xref: { document: "core", section: "9.14.4.4" } }, + Field({ name: "Unknown", id: 0x0, conformance: "M", description: "Other reason not listed in the row(s) below" }), + Field({ + name: "Interrupted", id: 0x1, conformance: "M", + description: "The action was interrupted by another command or interaction" + }) + ), + + Datatype( + { + name: "EndpointListTypeEnum", type: "enum8", + details: "The Room and Zone values are provided for the cases where a user (or the system on behalf of the " + + "user) has created logical grouping of the endpoints (e.g. bridged devices) based on location.", + xref: { document: "core", section: "9.14.4.5" } + }, + + Field({ + name: "Other", id: 0x0, conformance: "M", description: "Another group of endpoints", + details: "This value is provided for the case of an endpoint list which is tied specifically to this action " + + "i.e. not independently created by the user. For Type=Other the Name may be empty. A Matter " + + "controller would typically not use this for anything else than just to know which endpoints would " + + "be affected by the action.", + xref: { document: "core", section: "9.14.4.5.1" } + }), + + Field({ + name: "Room", id: 0x1, conformance: "M", + description: "User-configured group of endpoints where an endpoint can be in only one room", + details: "Is used for the situation where an endpoint can only be part of one such rooms (e.g. physical " + + "mapping). Using these exposed logical groups, a Matter controller who has a similar grouping " + + "concept can use it to place each endpoint (bridged device) in the right room automatically, without " + + "user having to redo that setup for each device in each system - both at first contact and upon " + + "later updates to the endpoints (e.g. user adds a bridged device or creates a new room).", + xref: { document: "core", section: "9.14.4.5.2" } + }), + + Field({ + name: "Zone", id: 0x2, conformance: "M", + description: "User-configured group of endpoints where an endpoint can be in any number of zones", + + details: "Is a more general concept where an endpoint can be part of multiple zones, e.g. a light in the " + + "living" + + "\n" + + "room can be part of the \"reading corner\" zone (subset of the lights in the living room) but also " + + "part of the \"downstairs\" zone which contains all the lights on a floor, e.g. combining living room, " + + "kitchen and hallway. This indicates that a user has defined this list of endpoints as something " + + "they logically would like to control as a group, so Matter controllers could provide the user with " + + "a way to do as such.", + + xref: { document: "core", section: "9.14.4.5.3" } + }) + ), + + Datatype( + { + name: "ActionStruct", type: "struct", + details: "This data type holds the details of a single action, and contains the data fields below.", + xref: { document: "core", section: "9.14.4.6" } + }, + Field({ + name: "ActionId", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall provide an unique identifier used to identify an action.", + xref: { document: "core", section: "9.14.4.6.1" } + }), + + Field({ + name: "Name", id: 0x1, type: "string", conformance: "M", constraint: "max 128{32}", + details: "This field shall indicate the name (as assigned by the user or automatically by the server) " + + "associated with this action. This can be used for identifying the action to the user by the client. " + + "Example: \"my colorful scene\".", + xref: { document: "core", section: "9.14.4.6.2" } + }), + + Field({ + name: "Type", id: 0x2, type: "ActionTypeEnum", conformance: "M", + details: "This field shall indicate the type of action. The value of Type of an action, along with its " + + "SupportedCommands can be used by the client in its UX or logic to determine how to present or use " + + "such action. See ActionTypeEnum for details and examples.", + xref: { document: "core", section: "9.14.4.6.3" } + }), + + Field({ + name: "EndpointListId", id: 0x3, type: "uint16", conformance: "M", + details: "This field shall provide a reference to the associated endpoint list, which specifies the endpoints " + + "on this Node which will be impacted by this ActionID.", + xref: { document: "core", section: "9.14.4.6.4" } + }), + + Field({ + name: "SupportedCommands", id: 0x4, type: "CommandBits", conformance: "M", constraint: "0 to 4095", + details: "This field is a bitmap which shall be used to indicate which of the cluster’s commands are " + + "supported for this particular action, with a bit set to 1 for each supported command according to " + + "the table below. Other bits shall be set to 0.", + xref: { document: "core", section: "9.14.4.6.5" } + }), + + Field({ + name: "State", id: 0x5, type: "ActionStateEnum", conformance: "M", + details: "This field shall indicate the current state of this action.", + xref: { document: "core", section: "9.14.4.6.6" } + }) + ), + + Datatype( + { + name: "EndpointListStruct", type: "struct", + details: "This data type holds the details of a single endpoint list, which relates to a set of endpoints " + + "that have some logical relation, and contains the data fields below.", + xref: { document: "core", section: "9.14.4.7" } + }, + + Field({ + name: "EndpointListId", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall provide an unique identifier used to identify the endpoint list.", + xref: { document: "core", section: "9.14.4.7.1" } + }), + + Field({ + name: "Name", id: 0x1, type: "string", conformance: "M", constraint: "max 128{32}", + details: "This field shall indicate the name (as assigned by the user or automatically by the server) " + + "associated with the set of endpoints in this list. This can be used for identifying the action to " + + "the user by the client. Example: \"living room\".", + xref: { document: "core", section: "9.14.4.7.2" } + }), + + Field({ + name: "Type", id: 0x2, type: "EndpointListTypeEnum", conformance: "M", + details: "This field shall indicate the type of endpoint list, see EndpointListTypeEnum.", + xref: { document: "core", section: "9.14.4.7.3" } + }), + + Field( + { + name: "Endpoints", id: 0x3, type: "list", conformance: "M", constraint: "max 256", + details: "This field shall provide a list of endpoint numbers.", + xref: { document: "core", section: "9.14.4.7.4" } + }, + Field({ name: "entry", type: "endpoint-no" }) + ) + ) + ), + + Cluster( + { + name: "ProxyDiscovery", id: 0x43, classification: "node", pics: "PXDSC", + details: "This cluster contains commands needed to do proxy discovery as defined in the Section 9.15.7.3, " + + "“Step 2: Proxy Discovery” and Section 9.15.7.4, “Step 3: Proxy Response” steps of the overall " + + "Section 9.15.7, “Proxy Discovery & Assignment Flow”.", + xref: { document: "core", section: "9.15.12" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Command( + { + name: "ProxyDiscoverRequest", id: 0x0, access: "O", conformance: "M", direction: "request", + details: "This command is used during proxy discovery, as specified in Section 9.15.7, “Proxy Discovery & " + + "Assignment Flow”.", + xref: { document: "core", section: "9.15.12.4.1" } + }, + + Field({ + name: "SourceNodeId", id: 0x0, type: "node-id", conformance: "M", + details: "This is the Node ID of the source for which a client seeks to find a Proxy.", + xref: { document: "core", section: "9.15.12.4.1.1" } + }), + + Field({ + name: "NumAttributePaths", id: 0x1, type: "uint16", conformance: "M", constraint: "desc", + details: "The number of attribute paths the client will have in the subscription request. This is a " + + "heuristic/hint to allow a Proxy to better ascertain whether it can support the ensuing subscription.", + xref: { document: "core", section: "9.15.12.4.1.2" } + }), + + Field({ + name: "NumEventPaths", id: 0x2, type: "uint16", conformance: "M", constraint: "desc", + details: "The number of event paths the client will have in the subscription request. This is a " + + "heuristic/hint to allow a Proxy to better ascertain whether it can support the ensuing subscription.", + xref: { document: "core", section: "9.15.12.4.1.3" } + }) + ), + + Command( + { + name: "ProxyDiscoverResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command is used during proxy discovery, as specified in Section 9.15.7, “Proxy Discovery & " + + "Assignment Flow”.", + xref: { document: "core", section: "9.15.12.4.2" } + }, + + Field({ + name: "SourceNodeId", id: 0x0, type: "node-id", conformance: "M", + details: "This is the Node ID of the source the proxy can proxy for. This shall match the node id in the " + + "corresponding Proxy Discover Request Command message.", + xref: { document: "core", section: "9.15.12.4.2.1" } + }), + + Field({ + name: "NumHopsToSource", id: 0x1, type: "uint16", conformance: "M", constraint: "desc", + + details: "If the proxy currently subscribes to the source (either directly or indirectly), this indicates the " + + "number of hops to the source. Sensible values start at 1, with 1 being used for a proxy that " + + "subscribes directly to the source. If the proxy is not subscribed directly to the source, this " + + "value shall be one greater than the NumHopsToSource for the given Node ID of the proxy it is " + + "subscribed to." + + "\n" + + "0 indicates that the proxy currently does not have a subscription to the source.", + + xref: { document: "core", section: "9.15.12.4.2.2" } + }), + + Field({ + name: "AvailableCapacity", id: 0x2, type: "uint16", conformance: "M", constraint: "desc", + details: "A number indicating the number of Cluster Attribute Paths the proxy has space for support. This " + + "allows for an absolute comparison of different memory capacities of candidate proxies by the client " + + "in selecting the best possible candidate.", + xref: { document: "core", section: "9.15.12.4.2.3" } + }) + ) + ), + + Cluster( + { + name: "ProxyConfiguration", id: 0x42, classification: "node", pics: "PXCFG", + details: "This cluster provides a means for a proxy-capable device to be told the set of Nodes it shall proxy.", + xref: { document: "core", section: "9.15.13" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "ConfigurationList", id: 0x0, type: "list", access: "RW", conformance: "M", default: [], + quality: "N", + details: "List of proxy configurations. There shall NOT be multiple entries in this list for the same fabric.", + xref: { document: "core", section: "9.15.13.5.1" } + }, + + Field({ name: "entry", type: "ConfigurationStruct" }) + ), + + Datatype( + { name: "ConfigurationStruct", type: "struct", xref: { document: "core", section: "9.15.13.4.1" } }, + + Field({ + name: "ProxyAllNodes", id: 0x1, type: "bool", access: "RW", conformance: "M", constraint: "desc", + default: false, + details: "This field shall be set to true to indicate to the proxy that it shall proxy all nodes. When true, " + + "the SourceList attribute is ignored.", + xref: { document: "core", section: "9.15.13.4.1.1" } + }), + + Field( + { + name: "SourceList", id: 0x2, type: "list", access: "RW", conformance: "M", constraint: "desc", + default: [], + details: "When ProxyAllNodes is false, this list contains the set of Node IDs of sources that this proxy " + + "shall specifically proxy.", + xref: { document: "core", section: "9.15.13.4.1.2" } + }, + + Field({ name: "entry", type: "node-id" }) + ) + ) + ), + + Cluster( + { + name: "ValidProxies", id: 0x44, classification: "node", pics: "PXVALID", + details: "This cluster provides a means for a device to be told of the valid set of possible proxies that can " + + "proxy subscriptions on its behalf as per Section 9.15.7, “Proxy Discovery & Assignment Flow”.", + xref: { document: "core", section: "9.15.14" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "ValidProxyList", id: 0x0, type: "list", access: "RW", conformance: "M", default: [], + quality: "N F", + details: "List of valid proxies that can proxy this Node. Each entry in this list is fabric-scoped.", + xref: { document: "core", section: "9.15.14.5.1" } + }, + + Field({ name: "entry", type: "ValidProxyStruct" }) + ), + + Command({ + name: "GetValidProxiesRequest", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "GetValidProxiesResponse", + details: "This command is used during proxy discovery, as specified in Section 9.15.7, “Proxy Discovery & " + + "Assignment Flow”.", + xref: { document: "core", section: "9.15.14.6.1" } + }), + + Command( + { + name: "GetValidProxiesResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command is used during proxy discovery, as specified in Section 9.15.7, “Proxy Discovery & " + + "Assignment Flow”.", + xref: { document: "core", section: "9.15.14.6.2" } + }, + + Field( + { name: "ProxyNodeIdList", id: 0x0, type: "list", conformance: "M" }, + Field({ name: "entry", type: "node-id" }) + ) + ), + + Datatype( + { + name: "ValidProxyStruct", type: "struct", + details: "Encapsulates the Node ID of a Valid Proxy.", + xref: { document: "core", section: "9.15.14.4.1" } + }, + Field({ name: "NodeId", id: 0x1, type: "node-id", access: "RW", conformance: "M" }) + ) + ), + + Cluster( + { + name: "IcdManagement", id: 0x46, classification: "node", pics: "ICDM", + details: "ICD Management Cluster enables configuration of the ICD’s behavior and ensuring that listed clients " + + "can be notified when an intermittently connected device, ICD, is available for communication." + + "\n" + + "The cluster implements the requirements of the Check-In Protocol that enables the ICD Check-In use " + + "case.", + xref: { document: "core", section: "9.17" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "9.17.4" } }, + + Field({ + name: "CIP", conformance: "LITS, O", constraint: "0", description: "CheckInProtocolSupport", + details: "When this feature is supported, the device shall support all the associated commands and attributes " + + "to properly support the Check-In Protocol.", + xref: { document: "core", section: "9.17.4.1" } + }), + + Field({ + name: "UAT", conformance: "LITS, O", constraint: "1", description: "UserActiveModeTrigger", + details: "This feature is supported if and only if the device has a user active mode trigger.", + xref: { document: "core", section: "9.17.4.2" } + }), + Field({ + name: "LITS", conformance: "O", constraint: "2", description: "LongIdleTimeSupport", + details: "This feature is supported if and only the device is a Long Idle Time ICD.", + xref: { document: "core", section: "9.17.4.3" } + }), + + Field({ + name: "DSLS", conformance: "[LITS]", constraint: "3", description: "DynamicSitLitSupport", + details: "This feature is supported if and only if the device can switch between SIT and LIT operating modes " + + "even if it has a valid registered client. See the dynamic SIT / LIT operating mode switching for " + + "more details.", + xref: { document: "core", section: "9.17.4.4" } + }) + ), + + Attribute({ + name: "IdleModeDuration", id: 0x0, type: "uint32", access: "R V", conformance: "M", + constraint: "1 to 64800", default: 1, quality: "F", + details: "Indicates the maximum interval in seconds the server can stay in idle mode. The IdleModeDuration " + + "shall NOT be smaller than the ActiveModeDuration.", + xref: { document: "core", section: "9.17.6.1" } + }), + + Attribute({ + name: "ActiveModeDuration", id: 0x1, type: "uint32", access: "R V", conformance: "M", default: 300, + quality: "F", + details: "Indicates the minimum interval in milliseconds the server typically will stay in active mode after " + + "initial transition out of idle mode. The ActiveModeDuration does not include the " + + "ActiveModeThreshold.", + xref: { document: "core", section: "9.17.6.2" } + }), + + Attribute({ + name: "ActiveModeThreshold", id: 0x2, type: "uint16", access: "R V", conformance: "M", default: 300, + quality: "F", + details: "Indicates the minimum amount of time in milliseconds the server typically will stay active after " + + "network activity when in active mode.", + xref: { document: "core", section: "9.17.6.3" } + }), + + Attribute( + { + name: "RegisteredClients", id: 0x3, type: "list", access: "R F A", conformance: "CIP", + constraint: "desc", default: [], quality: "N", + details: "This attribute shall contain all clients registered to receive notification if their subscription " + + "is lost. The maximum number of entries that can be in the list shall be ClientsSupportedPerFabric " + + "for each fabric supported on the server, as indicated by the value of the SupportedFabrics " + + "attribute in the Operational Credentials cluster.", + xref: { document: "core", section: "9.17.6.4" } + }, + + Field({ name: "entry", type: "MonitoringRegistrationStruct" }) + ), + + Attribute({ + name: "IcdCounter", id: 0x4, type: "uint32", access: "R A", conformance: "CIP", default: 0, + quality: "N C", + details: "This attribute returns the value of the ICD Counter.", + xref: { document: "core", section: "9.17.6.5" } + }), + + Attribute({ + name: "ClientsSupportedPerFabric", id: 0x5, type: "uint16", access: "R V", conformance: "CIP", + constraint: "min 1", default: 1, quality: "F", + details: "Indicates the maximum number of entries that the server is able to store for each fabric in the " + + "RegisteredClients attribute.", + xref: { document: "core", section: "9.17.6.6" } + }), + + Attribute({ + name: "UserActiveModeTriggerHint", id: 0x6, type: "UserActiveModeTriggerBitmap", access: "R V", + conformance: "UAT", constraint: "desc", default: 0, quality: "F", + + details: "Indicates which user action(s) will trigger the ICD to switch to Active mode. If the attribute " + + "indicates support for a trigger that is dependent on the UserActiveModeTriggerInstruction in the " + + "UserActiveModeTriggerHint table, the UserActiveModeTriggerInstruction attribute shall be " + + "implemented and shall provide the required information, unless specified otherwise in the " + + "requirement column of the UserActiveModeTriggerHint table." + + "\n" + + "ActuateSensorLightsBlink, ResetButtonLightsBlink and SetupButtonLightsBlink (i.e. bits 7, 9 and 14) " + + "have a dependency on the UserActiveModeTriggerInstruction attribute but do not require the " + + "attribute to be present." + + "\n" + + "### An ICD can indicate multiple ways of being put into Active Mode by setting multiple bits in the " + + "bitmap at the same time. However, a device shall NOT set more than one bit which has a dependency " + + "on the UserActiveModeTriggerInstruction attribute.", + + xref: { document: "core", section: "9.17.6.7" } + }), + + Attribute({ + name: "UserActiveModeTriggerInstruction", id: 0x7, type: "string", access: "R V", + conformance: "desc", constraint: "max 128", default: "", quality: "F", + + details: "The meaning of the attribute is dependent upon the UserActiveModeTriggerHint attribute value, and " + + "the conformance is in indicated in the \"dependency\" column in UserActiveModeTriggerHint table. The " + + "UserActiveModeTriggerInstruction attribute may give additional information on how to transition the " + + "device to Active Mode. If the attribute is present, the value shall be encoded as a valid UTF-8 " + + "string with a maximum length of 128 bytes. If the UserActiveModeTriggerHint has the " + + "ActuateSensorSeconds, ActuateSensorTimes, ResetButtonSeconds, ResetButtonTimes, SetupButtonSeconds " + + "or SetupButtonTimes set, the string shall consist solely of an encoding of N as a decimal unsigned " + + "integer using the ASCII digits 0-9, and without leading zeros." + + "\n" + + "For example, given UserActiveModeTriggerHint=\"2048\", ResetButtonTimes is set which indicates \"Press " + + "Reset Button for N seconds\". Therefore, a value of UserActiveModeTriggerInstruction=\"10\" would " + + "indicate that N is 10 in that context." + + "\n" + + "When CustomInstruction is set by the UserActiveModeTriggerHint attribute, indicating presence of a " + + "custom string, the ICD SHOULD perform localization (translation to user’s preferred language, as " + + "indicated in the Device’s currently configured locale). The Custom Instruction option SHOULD NOT be " + + "used by an ICD that does not have knowledge of the user’s language preference." + + "\n" + + "When the UserActiveModeTriggerHint key indicates a light to blink (ActuateSensorLightsBlink, " + + "ResetButtonLightsBlink or SetupButtonLightsBlink), information on color of light may be made " + + "available via the UserActiveModeTriggerInstruction attribute. When using such color indication in " + + "the UserActiveModeTriggerInstruction attribute, the string shall consist of exactly 6 hexadecimal " + + "digits using the ASCII characters 0-F and encoding the RGB color value as used in HTML encodings.", + + xref: { document: "core", section: "9.17.6.8" } + }), + + Attribute({ + name: "OperatingMode", id: 0x8, type: "OperatingModeEnum", access: "R V", conformance: "LITS", + details: "Indicates the operating mode of the ICD as specified in the OperatingModeEnum." + + "\n" + + " • If the ICD is operating as a LIT ICD, OperatingMode shall be LIT." + + "\n" + + " • If the ICD is operating as a SIT ICD, OperatingMode shall be SIT.", + xref: { document: "core", section: "9.17.6.9" } + }), + + Attribute({ + name: "MaximumCheckInBackoff", id: 0x9, type: "uint32", access: "R V", conformance: "CIP", + constraint: "idleModeDuration to 64800", default: 1, quality: "F", + details: "Indicates the maximum time in seconds between two Check-In messages when back-off is active. The " + + "MaximumCheckInBackoff shall NOT be smaller than the IdleModeDuration." + + "\n" + + "If the MaximumCheckInBackoff is equal to the IdleModeDuration, it means the ICD does notback- off.", + xref: { document: "core", section: "9.17.6.10" } + }), + + Command( + { + name: "RegisterClient", id: 0x0, access: "F M", conformance: "CIP", direction: "request", + response: "RegisterClientResponse", + details: "This command allows a client to register itself with the ICD to be notified when the device is " + + "available for communication.", + xref: { document: "core", section: "9.17.7.1" } + }, + + Field({ + name: "CheckInNodeId", id: 0x0, type: "node-id", conformance: "M", + details: "This field shall provide the node ID to which a Check-In message will be sent if there are no " + + "active subscriptions matching MonitoredSubject.", + xref: { document: "core", section: "9.17.7.1.1" } + }), + + Field({ + name: "MonitoredSubject", id: 0x1, type: "subject-id", conformance: "M", + details: "This field shall provide the monitored subject ID.", + xref: { document: "core", section: "9.17.7.1.2" } + }), + + Field({ + name: "Key", id: 0x2, type: "octstr", conformance: "M", constraint: "16", + details: "This field shall provide the shared secret between the client and the ICD to encrypt the Check-In " + + "message.", + xref: { document: "core", section: "9.17.7.1.3" } + }), + + Field({ + name: "VerificationKey", id: 0x3, type: "octstr", conformance: "O", constraint: "16", + + details: "This field shall provide the verification key. The verification key represents the key already " + + "stored on the server. The verification key provided in this field shall be used by the server to " + + "guarantee that a client with manage permissions can only modify entries that contain a Key equal to " + + "the verification key. The verification key shall be provided for clients with manage permissions. " + + "The verification key SHOULD NOT be provided by clients with administrator permissions for the " + + "server cluster. The verification key shall be ignored by the server if it is provided by a client " + + "with administrator permissions for the server cluster.", + + xref: { document: "core", section: "9.17.7.1.4" } + }), + + Field({ + name: "ClientType", id: 0x4, type: "ClientTypeEnum", conformance: "M", + details: "This field shall provide the client type of the client registering.", + xref: { document: "core", section: "9.17.7.1.5" } + }) + ), + + Command( + { + name: "RegisterClientResponse", id: 0x1, conformance: "CIP", direction: "response", + details: "This command shall be sent by the ICD Management Cluster server in response to a successful " + + "RegisterClient command.", + xref: { document: "core", section: "9.17.7.2" } + }, + + Field({ name: "IcdCounter", id: 0x0, type: "uint32", conformance: "M" }) + ), + + Command( + { + name: "UnregisterClient", id: 0x2, access: "F M", conformance: "CIP", direction: "request", + response: "status", + details: "This command allows a client to unregister itself with the ICD. Example: a client that is leaving " + + "the network (e.g. running on a phone which is leaving the home) can (and should) remove its " + + "subscriptions and send this UnregisterClient command before leaving to prevent the burden on the " + + "ICD of an absent client.", + xref: { document: "core", section: "9.17.7.3" } + }, + + Field({ + name: "CheckInNodeId", id: 0x0, type: "node-id", conformance: "M", + details: "This field shall provide the registered client node ID to remove from storage.", + xref: { document: "core", section: "9.17.7.3.1" } + }), + + Field({ + name: "VerificationKey", id: 0x1, type: "octstr", conformance: "O", constraint: "16", + + details: "This field shall provide the verification key associated with the CheckInNodeID to remove from " + + "storage. The verification key represents the key already stored on the server. The verification key " + + "provided in this field shall be used by the server to guarantee that a client with manage " + + "permissions can only remove entries that contain a Key equal to the stored key. The verification " + + "key shall be provided for clients with manage permissions. The verification key SHOULD NOT be " + + "provided by clients with administrator permissions for the server cluster. The verification key " + + "shall be ignored by the server if it is provided by a client with administrator permissions for the " + + "server cluster.", + + xref: { document: "core", section: "9.17.7.3.2" } + }) + ), + + Command( + { + name: "StayActiveRequest", id: 0x3, access: "O", conformance: "LITS, O", direction: "request", + response: "StayActiveResponse", + + details: "This command allows a client to request that the server stays in active mode for at least a given " + + "time duration (in milliseconds) from when this command is received." + + "\n" + + "This StayActiveDuration may be longer than the ActiveModeThreshold value and would, typically, be " + + "used by the client to request the server to stay active and responsive for this period to allow a " + + "sequence of message exchanges during that period. The client may slightly overestimate the duration " + + "it wants the ICD to be active for, in order to account for network delays.", + + xref: { document: "core", section: "9.17.7.4" } + }, + + Field({ name: "StayActiveDuration", id: 0x0, type: "uint32", conformance: "M" }) + ), + + Command( + { + name: "StayActiveResponse", id: 0x4, conformance: "LITS, O", direction: "response", + details: "This message shall be sent by the ICD in response to the StayActiveRequest command and shall " + + "contain the computed duration (in milliseconds) that the ICD intends to stay active for.", + xref: { document: "core", section: "9.17.7.5" } + }, + + Field({ + name: "PromisedActiveDuration", id: 0x0, type: "uint32", conformance: "M", constraint: "desc", + + details: "This field shall provide the actual duration that the ICD server can stay active from the time it " + + "receives the StayActiveRequest command." + + "\n" + + "### Minimum Value for PromisedActiveDuration" + + "\n" + + "The minimum value of the PromisedActiveDuration field shall be equal to either 30000 milliseconds " + + "or StayActiveDuration (from the received StayActiveRequest command), whichever is smaller.", + + xref: { document: "core", section: "9.17.7.5.1" } + }) + ), + + Datatype( + { + name: "UserActiveModeTriggerBitmap", type: "map32", + details: "See the UserActiveModeTriggerHint table for requirements associated to each bit.", + xref: { document: "core", section: "9.17.5.1" } + }, + Field({ name: "PowerCycle", constraint: "0", description: "Power Cycle to transition the device to ActiveMode" }), + Field({ + name: "SettingsMenu", constraint: "1", + description: "Settings menu on the device informs how to transition the device to ActiveMode" + }), + Field({ + name: "CustomInstruction", constraint: "2", + description: "Custom Instruction on how to transition the device to ActiveMode" + }), + Field({ + name: "DeviceManual", constraint: "3", + description: "Device Manual informs how to transition the device to ActiveMode" + }), + Field({ + name: "ActuateSensor", constraint: "4", + description: "Actuate Sensor to transition the device to ActiveMode" + }), + Field({ + name: "ActuateSensorSeconds", constraint: "5", + description: "Actuate Sensor for N seconds to transition the device to ActiveMode" + }), + Field({ + name: "ActuateSensorTimes", constraint: "6", + description: "Actuate Sensor N times to transition the device to ActiveMode" + }), + Field({ + name: "ActuateSensorLightsBlink", constraint: "7", + description: "Actuate Sensor until light blinks to transition the device to ActiveMode" + }), + Field({ + name: "ResetButton", constraint: "8", + description: "Press Reset Button to transition the device to ActiveMode" + }), + Field({ + name: "ResetButtonLightsBlink", constraint: "9", + description: "Press Reset Button until light blinks to transition the device to ActiveMode" + }), + Field({ + name: "ResetButtonSeconds", constraint: "10", + description: "Press Reset Button for N seconds to transition the device to ActiveMode" + }), + Field({ + name: "ResetButtonTimes", constraint: "11", + description: "Press Reset Button N times to transition the device to ActiveMode" + }), + Field({ + name: "SetupButton", constraint: "12", + description: "Press Setup Button to transition the device to ActiveMode" + }), + Field({ + name: "SetupButtonSeconds", constraint: "13", + description: "Press Setup Button for N seconds to transition the device to ActiveMode" + }), + Field({ + name: "SetupButtonLightsBlink", constraint: "14", + description: "Press Setup Button until light blinks to transition the device to ActiveMode" + }), + Field({ + name: "SetupButtonTimes", constraint: "15", + description: "Press Setup Button N times to transition the device to ActiveMode" + }), + Field({ + name: "AppDefinedButton", constraint: "16", + description: "Press the N Button to transition the device to ActiveMode" + }) + ), + + Datatype( + { name: "ClientTypeEnum", type: "enum8", xref: { document: "core", section: "9.17.5.1.1" } }, + Field({ + name: "Permanent", id: 0x0, conformance: "M", + description: "The client is typically resident, always-on, fixed infrastructure in the home." + }), + Field({ + name: "Ephemeral", id: 0x1, conformance: "M", + description: "The client is mobile or non-resident or not always-on and may not always be available in the home." + }) + ), + + Datatype( + { name: "OperatingModeEnum", type: "enum8", xref: { document: "core", section: "9.17.5.2" } }, + Field({ name: "Sit", id: 0x0, conformance: "M", description: "ICD is operating as a Short Idle Time ICD." }), + Field({ name: "Lit", id: 0x1, conformance: "M", description: "ICD is operating as a Long Idle Time ICD." }) + ), + + Datatype( + { name: "MonitoringRegistrationStruct", type: "struct", xref: { document: "core", section: "9.17.5.3" } }, + + Field({ + name: "CheckInNodeId", id: 0x1, type: "node-id", access: "S", conformance: "M", quality: "N", + details: "This field shall indicate the NodeID of the Node to which Check-In messages will be sent when the " + + "MonitoredSubject is not subscribed.", + xref: { document: "core", section: "9.17.5.3.1" } + }), + + Field({ + name: "MonitoredSubject", id: 0x2, type: "subject-id", access: "S", conformance: "M", quality: "N", + + details: "This field shall indicate the monitored Subject ID. This field shall be used to determine if a " + + "particular client has an active subscription for the given entry. The MonitoredSubject, when it is " + + "a NodeID, may be the same as the CheckInNodeID. The MonitoredSubject gives the registering client " + + "the flexibility of having a different CheckInNodeID from the MonitoredSubject. A subscription shall " + + "count as an active subscription for this entry if:" + + "\n" + + " • It is on the associated fabric of this entry, and" + + "\n" + + " • The subject of this entry matches the ISD of the SubscriptionRequest message that created the " + + " subscription. Matching shall be determined using the subject_matches function defined in the " + + " Access Control Privilege Granting Algorithm." + + "\n" + + "For example, if the MonitoredSubject is Node ID 0x1111_2222_3333_AAAA, and one of the subscribers " + + "to the server on the entry’s associated fabric bears that Node ID, then the entry matches." + + "\n" + + "Another example is if the MonitoredSubject has the value 0xFFFF_FFFD_AA12_0002, and one of the" + + "\n" + + "subscribers to the server on the entry’s associated fabric bears the CASE Authenticated TAG value " + + "0xAA12 and the version 0x0002 or higher within its NOC, then the entry matches.", + + xref: { document: "core", section: "9.17.5.3.2" } + }), + + Field({ name: "Key", id: 0x3, access: "F", conformance: "D" }), + + Field({ + name: "ClientType", id: 0x4, type: "ClientTypeEnum", access: "S", conformance: "M", default: 0, + quality: "N", + details: "This field shall indicate the client’s type to inform the ICD of the availability for communication " + + "of the client.", + xref: { document: "core", section: "9.17.5.4" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) + ), + + Cluster( + { + name: "EcosystemInformation", id: 0x750, classification: "endpoint", pics: "ECOINFO", + + details: "The Ecosystem Information Cluster provides extended device information for all the logical devices " + + "represented by a Bridged Node. The Ecosystem Information Cluster presents the view of device name " + + "and location metadata for presentation by a client of the cluster to a user. This cluster is " + + "intended to support Fabric Synchronization and be present on an endpoint with the BridgedNode " + + "device type listed in the DeviceTypeList of the endpoint’s Descriptor cluster." + + "\n" + + "This augments the Bridged Device Basic Information Cluster in the following ways:" + + "\n" + + " • The Ecosystem Information Cluster adds support for providing a name and location for individual " + + " endpoints. (The endpoints do not need to be present on the Bridge for their name and location " + + " information to be present.)" + + "\n" + + " • The Ecosystem Information Cluster adds metadata to support conflict resolution between multiple " + + " sources of the name and location data." + + "\n" + + " • The Ecosystem Information Cluster supports user control for the presence of the name and " + + " location information by specifying more restricted access." + + "\n" + + "A client SHOULD use the information provided by the Ecosystem Information Cluster to help the user " + + "organize and interact with their devices. Some examples may include:" + + "\n" + + " • Directly organizing and labeling the devices in a client’s user interface." + + "\n" + + " • Providing hints in the user interface, which can assist the user in organizing and labeling " + + " their devices." + + "\n" + + "For the purposes of the Ecosystem Information Cluster section, an instance of the Ecosystem " + + "Information Cluster will be referred to as an \"instance\".", + + xref: { document: "core", section: "9.18" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Datatype( + { name: "EcosystemDeviceStruct", type: "struct", xref: { document: "core", section: "9.18.4.1" } }, + + Field({ + name: "DeviceName", id: 0x0, type: "string", access: "S", conformance: "O", constraint: "max 64", + details: "This field shall indicate the device’s name, which is provided externally if the user consents. " + + "(For example, provided by the user in an ecosystem specific interface.)", + xref: { document: "core", section: "9.18.4.1.1" } + }), + + Field({ + name: "DeviceNameLastEdit", id: 0x1, type: "epoch-us", access: "S", conformance: "desc", default: 0, + details: "This field shall be present and set if the DeviceName field is present." + + "\n" + + "This field shall indicate the timestamp of when the DeviceName was last modified.", + xref: { document: "core", section: "9.18.4.1.2" } + }), + + Field({ + name: "BridgedEndpoint", id: 0x2, type: "endpoint-no", access: "S", conformance: "desc", + constraint: "desc", + details: "This field shall indicate the endpoint this EcosystemDeviceStruct is associated with on this Bridge." + + "\n" + + "This field shall be present and set to a valid endpoint if the device is accessible through the " + + "bridge.", + xref: { document: "core", section: "9.18.4.1.3" } + }), + + Field({ + name: "OriginalEndpoint", id: 0x3, type: "endpoint-no", access: "S", conformance: "desc", + constraint: "desc", + details: "This field shall indicate the endpoint this EcosystemDeviceStruct is associated with on the " + + "original device represented by this bridge’s Bridged Node. If this bridge is receiving the device " + + "from another bridge, then the OriginalEndpoint field value would be the same on both bridges. This " + + "field shall be present and set to a valid endpoint on the original device if that device is a " + + "Matter device.", + xref: { document: "core", section: "9.18.4.1.4" } + }), + + Field( + { + name: "DeviceTypes", id: 0x4, type: "list", access: "S", conformance: "M", constraint: "desc", + details: "This field shall indicate all of the DeviceTypes within the DeviceTypeList in the Descriptor " + + "Cluster associated with this EcosystemDeviceStruct entry." + + "\n" + + "This field shall contain a list of valid device type ids.", + xref: { document: "core", section: "9.18.4.1.5" } + }, + + Field({ name: "entry", type: "Descriptor.DeviceTypeStruct" }) + ), + + Field( + { + name: "UniqueLocationIDs", id: 0x5, type: "list", access: "S", conformance: "M", + constraint: "max 64[max 64]", + details: "This field shall specify the EcosystemLocationStruct entries in the LocationDirectory attribute " + + "associated with this EcosystemDeviceStruct.", + xref: { document: "core", section: "9.18.4.1.6" } + }, + + Field({ name: "entry", type: "string" }) + ), + + Field({ + name: "UniqueLocationIDsLastEdit", id: 0x6, type: "epoch-us", access: "S", conformance: "M", + default: 0, + + details: "This field shall indicate the timestamp of when the UniqueLocationIDs was last modified." + + "\n" + + "NOTE" + + "\n" + + "If multiple server instances update the UniqueLocationIDs field at the same time, it is possible " + + "one of the updates will be missed. This is considered an acceptable limitation to reduce the " + + "complexity of the design. Since this is meant to be provided from user input, it is unlikely these " + + "signals would be happening at one time.", + + xref: { document: "core", section: "9.18.4.1.7" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "EcosystemLocationStruct", type: "struct", xref: { document: "core", section: "9.18.4.2" } }, + + Field({ + name: "UniqueLocationId", id: 0x0, type: "string", access: "S", conformance: "M", + constraint: "max 64", + + details: "This field shall indicate a unique identifier for a specific Ecosystem Information Cluster server " + + "instance representing the location independent of its LocationDescriptor field." + + "\n" + + "UniqueLocationID can be used by the client to determine if the change is a relocation of the device " + + "or just a renaming of the location." + + "\n" + + "No guarantees are given for consistency of the ID between server instances. The same location may " + + "be represented by different IDs on different Ecosystem Information Cluster server instances, so " + + "only the history from a single server instance should be considered when evaluating a change." + + "\n" + + "UniqueLocationID shall be changed when the LocationDescriptor changes from one existing location to " + + "another location as a result of an external interaction. (For example, the user changes the " + + "location assignment.)" + + "\n" + + "UniqueLocationID shall NOT be changed when the LocationDescriptor changes name, but still " + + "represents the same location. (For example, the user renames a room.)" + + "\n" + + "UniqueLocationID shall be changed when LocationDescriptor changes as a result of another Ecosystem " + + "Information Cluster server instance changing and the UniqueLocationID on the remote server instance " + + "also changes." + + "\n" + + "UniqueLocationID shall NOT be changed when LocationDescriptor changes as a result of another " + + "Ecosystem Information Cluster server instance changing and the UniqueLocationID on the remote " + + "server instance does not change.", + + xref: { document: "core", section: "9.18.4.2.1" } + }), + + Field({ + name: "LocationDescriptor", id: 0x1, type: "locationdesc", access: "S", conformance: "M", + + details: "This field shall indicate the location (e.g. living room, driveway) and associated metadata that is " + + "provided externally if the user consents. (For example, provided by the user in an ecosystem " + + "specific interface.)" + + "\n" + + "\"Location\" in this context is typically used by the user’s grouping into rooms, areas or other " + + "logical groupings of how devices are used. So a device might be part of multiple such \"Locations\"s.", + + xref: { document: "core", section: "9.18.4.2.2" } + }), + + Field({ + name: "LocationDescriptorLastEdit", id: 0x2, type: "epoch-us", access: "S", conformance: "M", + default: 0 + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) + ), + + Cluster( + { + name: "BasicInformation", id: 0x28, classification: "node", pics: "BINFO", + details: "This cluster provides attributes and events for determining basic information about Nodes, which " + + "supports both Commissioning and operational determination of Node characteristics, such as Vendor " + + "ID, Product ID and serial number, which apply to the whole Node.", + xref: { document: "core", section: "11.1" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute({ + name: "DataModelRevision", id: 0x0, type: "uint16", access: "R V", conformance: "M", + constraint: "desc", quality: "F", + details: "This attribute shall be set to the revision number of the Data Model against which the Node is " + + "certified. The value of this attribute shall be one of the valid values listed in Section 7.1.1, " + + "“Revision History”.", + xref: { document: "core", section: "11.1.5.1" } + }), + + Attribute({ + name: "VendorName", id: 0x1, type: "string", access: "R V", conformance: "M", constraint: "max 32", + quality: "F", + details: "This attribute shall specify a human readable (displayable) name of the vendor for the Node.", + xref: { document: "core", section: "11.1.5.2" } + }), + + Attribute({ + name: "VendorId", id: 0x2, type: "vendor-id", access: "R V", conformance: "M", quality: "F", + details: "This attribute shall specify the Vendor ID.", + xref: { document: "core", section: "11.1.5.3" } + }), + + Attribute({ + name: "ProductName", id: 0x3, type: "string", access: "R V", conformance: "M", constraint: "max 32", + quality: "F", + details: "This attribute shall specify a human readable (displayable) name of the model for the Node such as " + + "the model number (or other identifier) assigned by the vendor.", + xref: { document: "core", section: "11.1.5.4" } + }), + + Attribute({ + name: "ProductId", id: 0x4, type: "uint16", access: "R V", conformance: "M", quality: "F", + details: "This attribute shall specify the Product ID assigned by the vendor that is unique to the specific " + + "product of the Node.", + xref: { document: "core", section: "11.1.5.5" } + }), + + Attribute({ + name: "NodeLabel", id: 0x5, type: "string", access: "RW VM", conformance: "M", constraint: "max 32", + default: "", quality: "N", + details: "Indicates a user defined name for the Node. This attribute SHOULD be set during initial " + + "commissioning and may be updated by further reconfigurations.", + xref: { document: "core", section: "11.1.5.6" } + }), + + Attribute({ + name: "Location", id: 0x6, type: "string", access: "RW VA", conformance: "M", constraint: "2", + default: "XX", quality: "N", + + details: "This attribute shall be an ISO 3166-1 alpha-2 code to represent the country, dependent territory, " + + "or special area of geographic interest in which the Node is located at the time of the attribute " + + "being set. This attribute shall be set during initial commissioning (unless already set) and may be " + + "updated by further reconfigurations. This attribute may affect some regulatory aspects of the " + + "Node’s operation, such as radio transmission power levels in given spectrum allocation bands if " + + "technologies where this is applicable are used. The Location’s region code shall be interpreted in " + + "a case-insensitive manner. If the Node cannot understand the location code with which it was " + + "configured, or the location code has not yet been configured, it shall configure itself in a " + + "region- agnostic manner as determined by the vendor, avoiding region-specific assumptions as much " + + "as is practical. The special value XX shall indicate that region-agnostic mode is used.", + + xref: { document: "core", section: "11.1.5.7" } + }), + + Attribute({ + name: "HardwareVersion", id: 0x7, type: "uint16", access: "R V", conformance: "M", default: 0, + quality: "F", + details: "This attribute shall specify the version number of the hardware of the Node. The meaning of its " + + "value, and the versioning scheme, are vendor defined.", + xref: { document: "core", section: "11.1.5.8" } + }), + + Attribute({ + name: "HardwareVersionString", id: 0x8, type: "string", access: "R V", conformance: "M", + constraint: "1 to 64", quality: "F", + details: "This attribute shall specify the version number of the hardware of the Node. The meaning of its " + + "value, and the versioning scheme, are vendor defined. The HardwareVersionString attribute shall be " + + "used to provide a more user-friendly value than that represented by the HardwareVersion attribute.", + xref: { document: "core", section: "11.1.5.9" } + }), + + Attribute({ + name: "SoftwareVersion", id: 0x9, type: "uint32", access: "R V", conformance: "M", + constraint: "desc", default: 0, quality: "F", + + details: "This attribute shall contain the current version number for the software running on this Node." + + "\n" + + "The version number can be compared using a total ordering to determine if a version is logically " + + "newer than another one. A larger value of SoftwareVersion is newer than a lower value, from the " + + "perspective of software updates (see Section 11.20.3.3, “Availability of Software Images”). Nodes " + + "may query this field to determine the currently running version of software on another given Node.", + + xref: { document: "core", section: "11.1.5.10" } + }), + + Attribute({ + name: "SoftwareVersionString", id: 0xa, type: "string", access: "R V", conformance: "M", + constraint: "1 to 64", quality: "F", + + details: "This attribute shall contain a current human-readable representation for the software running on " + + "the Node. This version information may be conveyed to users. The maximum length of the " + + "SoftwareVersionString attribute is 64 bytes of UTF-8 characters. The contents SHOULD only use " + + "simple 7-bit ASCII alphanumeric and punctuation characters, so as to simplify the conveyance of the " + + "value to a variety of cultures." + + "\n" + + "Examples of version strings include \"1.0\", \"1.2.3456\", \"1.2-2\", \"1.0b123\", \"1.2_3\".", + + xref: { document: "core", section: "11.1.5.11" } + }), + + Attribute({ + name: "ManufacturingDate", id: 0xb, type: "string", access: "R V", conformance: "O", + constraint: "8 to 16", quality: "F", + details: "This attribute shall specify the date that the Node was manufactured. The first 8 characters shall " + + "specify the date of manufacture of the Node in international date notation according to ISO 8601, " + + "i.e., YYYYMMDD, e.g., 20060814. The final 8 characters may include country, factory, line, shift or " + + "other related information at the option of the vendor. The format of this information is vendor " + + "defined.", + xref: { document: "core", section: "11.1.5.12" } + }), + + Attribute({ + name: "PartNumber", id: 0xc, type: "string", access: "R V", conformance: "O", constraint: "max 32", + quality: "F", + + details: "This attribute shall specify a human-readable (displayable) vendor assigned part number for the " + + "Node whose meaning and numbering scheme is vendor defined." + + "\n" + + "Multiple products (and hence PartNumbers) can share a ProductID. For instance, there may be " + + "different packaging (with different PartNumbers) for different regions; also different colors of a " + + "product might share the ProductID but may have a different PartNumber.", + + xref: { document: "core", section: "11.1.5.13" } + }), + + Attribute({ + name: "ProductUrl", id: 0xd, type: "string", access: "R V", conformance: "O", constraint: "max 256", + quality: "F", + details: "This attribute shall specify a link to a product specific web page. The specified URL SHOULD " + + "resolve to a maintained web page available for the lifetime of the product. The syntax of this " + + "attribute shall follow the syntax as specified in RFC 1738 and shall use the https scheme. The " + + "maximum length of this attribute is 256 ASCII characters.", + xref: { document: "core", section: "11.1.5.14" } + }), + + Attribute({ + name: "ProductLabel", id: 0xe, type: "string", access: "R V", conformance: "O", + constraint: "max 64", quality: "F", + details: "This attribute shall specify a vendor specific human readable (displayable) product label. The " + + "ProductLabel attribute may be used to provide a more user-friendly value than that represented by " + + "the ProductName attribute. The ProductLabel attribute SHOULD NOT include the name of the vendor as " + + "defined within the VendorName attribute.", + xref: { document: "core", section: "11.1.5.15" } + }), + + Attribute({ + name: "SerialNumber", id: 0xf, type: "string", access: "R V", conformance: "O", + constraint: "max 32", quality: "F", + details: "This attribute shall specify a human readable (displayable) serial number.", + xref: { document: "core", section: "11.1.5.16" } + }), + + Attribute({ + name: "LocalConfigDisabled", id: 0x10, type: "bool", access: "RW VM", conformance: "O", + default: false, quality: "N", + details: "This attribute shall allow a local Node configuration to be disabled. When this attribute is set to " + + "True the Node shall disable the ability to configure the Node through an on-Node user interface. " + + "The value of the LocalConfigDisabled attribute shall NOT in any way modify, disable, or otherwise " + + "affect the user’s ability to trigger a factory reset on the Node.", + xref: { document: "core", section: "11.1.5.17" } + }), + + Attribute({ + name: "Reachable", id: 0x11, type: "bool", access: "R V", conformance: "O", default: true, + details: "This attribute (when used) shall indicate whether the Node can be reached. For a native Node this " + + "is implicitly True (and its use is optional)." + + "\n" + + "Its main use case is in the derived Bridged Device Basic Information cluster where it is used to " + + "indicate whether the bridged device is reachable by the bridge over the non-native network.", + xref: { document: "core", section: "11.1.5.18" } + }), + + Attribute({ + name: "UniqueId", id: 0x12, type: "string", access: "R V", conformance: "M", constraint: "max 32", + quality: "F", + + details: "Indicates a unique identifier for the device, which is constructed in a manufacturer specific " + + "manner." + + "\n" + + "It may be constructed using a permanent device identifier (such as device MAC address) as basis. In " + + "order to prevent tracking," + + "\n" + + " • it SHOULD NOT be identical to (or easily derived from) such permanent device identifier" + + "\n" + + " • it shall be updated when the device is factory reset" + + "\n" + + " • it shall NOT be identical to the SerialNumber attribute" + + "\n" + + " • it shall NOT be printed on the product or delivered with the product" + + "\n" + + "The value does not need to be human readable, since it is intended for machine to machine (M2M) " + + "communication." + + "\n" + + "NOTE" + + "\n" + + "NOTE" + + "\n" + + "The conformance of the UniqueID attribute was optional in cluster revisions prior to revision 4." + + "\n" + + "This UniqueID attribute shall NOT be the same as the Persistent Unique ID which is used in the " + + "Rotating Device Identifier mechanism.", + + xref: { document: "core", section: "11.1.5.19" } + }), + + Attribute({ + name: "CapabilityMinima", id: 0x13, type: "CapabilityMinimaStruct", access: "R V", conformance: "M", + quality: "F", + + details: "This attribute shall provide the minimum guaranteed value for some system-wide resource " + + "capabilities that are not otherwise cluster-specific and do not appear elsewhere. This attribute " + + "may be used by clients to optimize communication with Nodes by allowing them to use more than the " + + "strict minimum values required by this specification, wherever available." + + "\n" + + "The values supported by the server in reality may be larger than the values provided in this " + + "attribute, such as if a server is not resource-constrained at all. However, clients SHOULD only " + + "rely on the amounts provided in this attribute." + + "\n" + + "Note that since the fixed values within this attribute may change over time, both increasing and " + + "decreasing, as software versions change for a given Node, clients SHOULD take care not to assume" + + "\n" + + "forever unchanging values and SHOULD NOT cache this value permanently at Commissioning time.", + + xref: { document: "core", section: "11.1.5.20" } + }), + + Attribute({ + name: "ProductAppearance", id: 0x14, type: "ProductAppearanceStruct", access: "R V", + conformance: "O", quality: "F", + details: "This attribute shall provide information about the appearance of the product, which could be useful " + + "to a user trying to locate or identify the node.", + xref: { document: "core", section: "11.1.5.21" } + }), + + Attribute({ + name: "SpecificationVersion", id: 0x15, type: "uint32", access: "R V", conformance: "M", + constraint: "desc", default: 0, quality: "F", + + details: "This attribute shall contain the current version number for the specification version this Node was " + + "certified against. The version number can be compared using a total ordering to determine if a " + + "version is logically newer than another one. A larger value of SpecificationVersion is newer than a " + + "lower value." + + "\n" + + "Nodes may query this field to determine the currently supported version of the specification on " + + "another given Node." + + "\n" + + "The format of this number is segmented as its four component bytes. Bit positions for the fields " + + "are as follows:" + + "\n" + + "For example, a SpecificationVersion value of 0x0102AA00 is composed of 4 version components, " + + "representing a version 1.2.170.0." + + "\n" + + "In the example above:" + + "\n" + + " • Major version is the uppermost byte (0x01)." + + "\n" + + " • Minor version is the following byte (0x02)." + + "\n" + + " • Patch version is 170/0xAA." + + "\n" + + " • Reserved1 value is 0." + + "\n" + + "The initial revision (1.0) of this specification (1.0) was 0x01000000. Matter Spring 2024 release " + + "(1.3) was 0x01030000." + + "\n" + + "If the SpecificationVersion is absent or zero, such as in Basic Information cluster revisions prior " + + "to Revision 3, the specification version cannot be properly inferred unless other heuristics are " + + "employed." + + "\n" + + "Comparison of SpecificationVersion shall always include the total value over 32 bits, without " + + "masking reserved parts.", + + xref: { document: "core", section: "11.1.5.22" } + }), + + Attribute({ + name: "MaxPathsPerInvoke", id: 0x16, type: "uint16", access: "R V", conformance: "M", + constraint: "min 1", default: 1, quality: "F", + + details: "Indicates the maximum number of elements in a single InvokeRequests list (see Section 8.8.2, " + + "“Invoke Request Action”) that the Node is able to process. Note that since this attribute may " + + "change over time, both increasing and decreasing, as software versions change for a given Node, " + + "clients SHOULD take care not to assume forever unchanging values and SHOULD NOT cache this value " + + "permanently at Commissioning time." + + "\n" + + "If the MaxPathsPerInvoke attribute is absent or zero, such as in Basic Information cluster " + + "revisions prior to Revision 3, clients shall assume a value of 1.", + + xref: { document: "core", section: "11.1.5.23" } + }), + + Event( + { + name: "StartUp", id: 0x0, access: "V", conformance: "M", priority: "critical", + details: "The StartUp event shall be generated by a Node as soon as reasonable after completing a boot or " + + "reboot process. The StartUp event SHOULD be the first Data Model event recorded by the Node after " + + "it completes a boot or reboot process.", + xref: { document: "core", section: "11.1.6.1" } + }, + + Field({ + name: "SoftwareVersion", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall be set to the same value as the one available in the SoftwareVersion attribute.", + xref: { document: "core", section: "11.1.6.1.1" } + }) + ), + + Event({ + name: "ShutDown", id: 0x1, access: "V", conformance: "O", priority: "critical", + details: "The ShutDown event SHOULD be generated by a Node prior to any orderly shutdown sequence on a " + + "best-effort basis. When a ShutDown event is generated, it SHOULD be the last Data Model event " + + "recorded by the Node. This event SHOULD be delivered urgently to current subscribers on a best- " + + "effort basis. Any subsequent incoming interactions to the Node may be dropped until the completion " + + "of a future boot or reboot process.", + xref: { document: "core", section: "11.1.6.2" } + }), + + Event( + { + name: "Leave", id: 0x2, access: "V", conformance: "O", priority: "info", + + details: "The Leave event SHOULD be generated by a Node prior to permanently leaving a given Fabric, such as " + + "when the RemoveFabric command is invoked for a given fabric, or triggered by factory reset or some " + + "other manufacturer specific action to disable or reset the operational data in the Node. When a " + + "Leave event is generated, it SHOULD be assumed that the fabric recorded in the event is no longer " + + "usable, and subsequent interactions targeting that fabric will most likely fail." + + "\n" + + "Upon receipt of Leave Event on a subscription, the receiving Node may update other nodes in the " + + "fabric by removing related bindings, access control list entries and other data referencing the " + + "leaving Node.", + + xref: { document: "core", section: "11.1.6.3" } + }, + + Field({ + name: "FabricIndex", id: 0x0, type: "fabric-idx", conformance: "M", constraint: "1 to 254", + details: "This field shall contain the local Fabric Index of the fabric which the node is about to leave.", + xref: { document: "core", section: "11.1.6.3.1" } + }) + ), + + Event( + { + name: "ReachableChanged", id: 0x3, access: "V", conformance: "desc", priority: "info", + details: "This event shall be supported if and only if the Reachable attribute is supported." + + "\n" + + "This event (when supported) shall be generated when there is a change in the Reachable attribute." + + "\n" + + "Its main use case is in the derived Bridged Device Basic Information cluster.", + xref: { document: "core", section: "11.1.6.4" } + }, + + Field({ + name: "ReachableNewValue", id: 0x0, type: "bool", conformance: "M", + details: "This field shall indicate the value of the Reachable attribute after it was changed.", + xref: { document: "core", section: "11.1.6.4.1" } + }) + ), + + Datatype( + { + name: "ProductFinishEnum", type: "enum8", + details: "The data type of ProductFinishEnum is derived from enum8.", + xref: { document: "core", section: "11.1.4.1" } + }, + Field({ + name: "Other", id: 0x0, conformance: "M", + description: "Product has some other finish not listed below." + }), + Field({ name: "Matte", id: 0x1, conformance: "M", description: "Product has a matte finish." }), + Field({ name: "Satin", id: 0x2, conformance: "M", description: "Product has a satin finish." }), + Field({ name: "Polished", id: 0x3, conformance: "M", description: "Product has a polished or shiny finish." }), + Field({ name: "Rugged", id: 0x4, conformance: "M", description: "Product has a rugged finish." }), + Field({ name: "Fabric", id: 0x5, conformance: "M", description: "Product has a fabric finish." }) + ), + + Datatype( + { + name: "ColorEnum", type: "enum8", + details: "The data type of ColorEnum is derived from enum8.", + xref: { document: "core", section: "11.1.4.2" } + }, + Field({ name: "Black", id: 0x0, conformance: "M", description: "Approximately RGB #000000." }), + Field({ name: "Navy", id: 0x1, conformance: "M", description: "Approximately RGB #000080." }), + Field({ name: "Green", id: 0x2, conformance: "M", description: "Approximately RGB #008000." }), + Field({ name: "Teal", id: 0x3, conformance: "M", description: "Approximately RGB #008080." }), + Field({ name: "Maroon", id: 0x4, conformance: "M", description: "Approximately RGB #800080." }), + Field({ name: "Purple", id: 0x5, conformance: "M", description: "Approximately RGB #800080." }), + Field({ name: "Olive", id: 0x6, conformance: "M", description: "Approximately RGB #808000." }), + Field({ name: "Gray", id: 0x7, conformance: "M", description: "Approximately RGB #808080." }), + Field({ name: "Blue", id: 0x8, conformance: "M", description: "Approximately RGB #0000FF." }), + Field({ name: "Lime", id: 0x9, conformance: "M", description: "Approximately RGB #00FF00." }), + Field({ name: "Aqua", id: 0xa, conformance: "M", description: "Approximately RGB #00FFFF." }), + Field({ name: "Red", id: 0xb, conformance: "M", description: "Approximately RGB #FF0000." }), + Field({ name: "Fuchsia", id: 0xc, conformance: "M", description: "Approximately RGB #FF00FF." }), + Field({ name: "Yellow", id: 0xd, conformance: "M", description: "Approximately RGB #FFFF00." }), + Field({ name: "White", id: 0xe, conformance: "M", description: "Approximately RGB #FFFFFF." }), + Field({ name: "Nickel", id: 0xf, conformance: "M", description: "Typical hardware \"Nickel\" color." }), + Field({ name: "Chrome", id: 0x10, conformance: "M", description: "Typical hardware \"Chrome\" color." }), + Field({ name: "Brass", id: 0x11, conformance: "M", description: "Typical hardware \"Brass\" color." }), + Field({ name: "Copper", id: 0x12, conformance: "M", description: "Typical hardware \"Copper\" color." }), + Field({ name: "Silver", id: 0x13, conformance: "M", description: "Typical hardware \"Silver\" color." }), + Field({ name: "Gold", id: 0x14, conformance: "M", description: "Typical hardware \"Gold\" color." }) + ), + + Datatype( + { + name: "ProductAppearanceStruct", type: "struct", + details: "This structure provides a description of the product’s appearance.", + xref: { document: "core", section: "11.1.4.3" } + }, + Field({ + name: "Finish", id: 0x0, type: "ProductFinishEnum", conformance: "M", + details: "This field shall indicate the visible finish of the product.", + xref: { document: "core", section: "11.1.4.3.1" } + }), + + Field({ + name: "PrimaryColor", id: 0x1, type: "ColorEnum", conformance: "M", quality: "X", + details: "This field indicates the representative color of the visible parts of the product. If the product " + + "has no representative color, the field shall be null.", + xref: { document: "core", section: "11.1.4.3.2" } + }) + ), + + Datatype( + { + name: "CapabilityMinimaStruct", type: "struct", + details: "This structure provides constant values related to overall global capabilities of this Node, that " + + "are not cluster-specific.", + xref: { document: "core", section: "11.1.4.4" } + }, + + Field({ + name: "CaseSessionsPerFabric", id: 0x0, type: "uint16", conformance: "M", constraint: "min 3", + default: 3, + details: "This field shall indicate the actual minimum number of concurrent CASE sessions that are supported " + + "per fabric." + + "\n" + + "This value shall NOT be smaller than the required minimum indicated in Section 4.14.2.8, “Minimal " + + "Number of CASE Sessions”.", + xref: { document: "core", section: "11.1.4.4.1" } + }), + + Field({ + name: "SubscriptionsPerFabric", id: 0x1, type: "uint16", conformance: "M", constraint: "min 3", + default: 3, + details: "This field shall indicate the actual minimum number of concurrent subscriptions supported per " + + "fabric." + + "\n" + + "This value shall NOT be smaller than the required minimum indicated in Section 8.5.1, “Subscribe " + + "Transaction”.", + xref: { document: "core", section: "11.1.4.4.2" } + }) + ) + ), + + Cluster( + { + name: "GroupKeyManagement", id: 0x3f, classification: "node", pics: "GRPKEY", + + details: "The Group Key Management cluster manages group keys for the node. The cluster is scoped to the node " + + "and is a singleton for the node. This cluster maintains a list of groups supported by the node. " + + "Each group list entry supports a single group, with a single group ID and single group key. " + + "Duplicate groups are not allowed in the list. Additions or removal of a group entry are performed " + + "via modifications of the list. Such modifications require Administer privilege." + + "\n" + + "Each group entry includes a membership list of zero of more endpoints that are members of the group " + + "on the node. Modification of this membership list is done via the Groups cluster, which is" + + "\n" + + "scoped to an endpoint. Please see the System Model specification for more information on groups.", + + xref: { document: "core", section: "11.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.2.4" } }, + Field({ + name: "CS", conformance: "P", constraint: "0", description: "CacheAndSync", + details: "The ability to support CacheAndSync security policy and MCSP." + }) + ), + + Attribute( + { + name: "GroupKeyMap", id: 0x0, type: "list", access: "RW F VM", conformance: "M", constraint: "desc", + default: [], quality: "N", + details: "This attribute is a list of GroupKeyMapStruct entries. Each entry associates a logical Group Id " + + "with a particular group key set.", + xref: { document: "core", section: "11.2.6.1" } + }, + + Field({ name: "entry", type: "GroupKeyMapStruct" }) + ), + + Attribute( + { + name: "GroupTable", id: 0x1, type: "list", access: "R F V", conformance: "M", constraint: "desc", + default: [], + + details: "This attribute is a list of GroupInfoMapStruct entries. Each entry provides read-only information " + + "about how a given logical Group ID maps to a particular set of endpoints, and a name for the group." + + "\n" + + "The content of this attribute reflects data managed via the Groups cluster (see AppClusters), and " + + "is in general terms referred to as the 'node-wide Group Table'." + + "\n" + + "The GroupTable shall NOT contain any entry whose GroupInfoMapStruct has an empty Endpoints list. If " + + "a RemoveGroup or RemoveAllGroups command causes the removal of a group mapping from its last mapped " + + "endpoint, the entire GroupTable entry for that given GroupId shall be removed.", + + xref: { document: "core", section: "11.2.6.2" } + }, + + Field({ name: "entry", type: "GroupInfoMapStruct" }) + ), + + Attribute({ + name: "MaxGroupsPerFabric", id: 0x2, type: "uint16", access: "R V", conformance: "M", default: 0, + quality: "F", + details: "Indicates the maximum number of groups that this node supports per fabric. The value of this " + + "attribute shall be set to be no less than the required minimum supported groups as specified in " + + "Group Limits. The length of the GroupKeyMap and GroupTable list attributes shall NOT exceed the " + + "value of the MaxGroupsPerFabric attribute multiplied by the number of supported fabrics.", + xref: { document: "core", section: "11.2.6.3" } + }), + + Attribute({ + name: "MaxGroupKeysPerFabric", id: 0x3, type: "uint16", access: "R V", conformance: "M", + constraint: "1 to 65535", default: 1, quality: "F", + details: "Indicates the maximum number of group key sets this node supports per fabric. The value of this " + + "attribute shall be set according to the minimum number of group key sets to support as specified in " + + "Group Limits.", + xref: { document: "core", section: "11.2.6.4" } + }), + + Command( + { + name: "KeySetWrite", id: 0x0, access: "F A", conformance: "M", direction: "request", + response: "status", + + details: "This command is used by Administrators to set the state of a given Group Key Set, including " + + "atomically updating the state of all epoch keys." + + "\n" + + "Effect on Receipt" + + "\n" + + "The following validations shall be done against the content of the GroupKeySet field:" + + "\n" + + " • If the EpochKey0 field is null or its associated EpochStartTime0 field is null, then this " + + " command shall fail with an INVALID_COMMAND status code responded to the client." + + "\n" + + " • If the EpochKey0 field’s length is not exactly 16 bytes, then this command shall fail with a " + + " CONSTRAINT_ERROR status code responded to the client." + + "\n" + + " • If the EpochStartTime0 is set to 0, then this command shall fail with an INVALID_COMMAND status " + + " code responded to the client. Note that internally, a GroupKeySetStruct’s EpochStartTime0 may " + + " be set to zero, due to the behavior of the AddNOC command which synthesizes a GroupKeySetStruct " + + " (see IPKValue). However, the value 0 is illegal in the GroupKeySet field sent by a client." + + "\n" + + " • If the EpochKey1 field is not null, then the EpochKey0 field shall NOT be null. Otherwise this " + + " command shall fail with an INVALID_COMMAND status code responded to the client." + + "\n" + + " • If the EpochKey1 field is not null, and the field’s length is not exactly 16 bytes, then this " + + " command shall fail with a CONSTRAINT_ERROR status code responded to the client." + + "\n" + + " • If the EpochKey1 field is not null, its associated EpochStartTime1 field shall NOT be null and " + + " shall contain a later epoch start time than the epoch start time found in the EpochStartTime0 " + + " field. Otherwise this command shall fail with an INVALID_COMMAND status code responded to the " + + " client." + + "\n" + + " • If exactly one of the EpochKey1 or EpochStartTime1 is null, rather than both being null, or " + + " neither being null, then this command shall fail with an INVALID_COMMAND status code responded " + + " to the client." + + "\n" + + " • If the EpochKey2 field is not null, then the EpochKey1 and EpochKey0 fields shall NOT be null. " + + " Otherwise this command shall fail with an INVALID_COMMAND status code responded to the client." + + "\n" + + " • If the EpochKey2 field is not null, and the field’s length is not exactly 16 bytes, then this " + + " command shall fail with a CONSTRAINT_ERROR status code responded to the client." + + "\n" + + " • If the EpochKey2 field is not null, its associated EpochStartTime2 field shall NOT be null and " + + " shall contain a later epoch start time than the epoch start time found in the EpochStartTime1 " + + " field. Otherwise this command shall fail with an INVALID_COMMAND status code responded to the " + + " client." + + "\n" + + " • If exactly one of the EpochKey2 or EpochStartTime2 is null, rather than both being null, or " + + " neither being null, then this command shall fail with an INVALID_COMMAND status code responded " + + " to the client." + + "\n" + + "If there exists a Group Key Set associated with the accessing fabric which has the same " + + "GroupKeySetID as that provided in the GroupKeySet field, then the contents of that group key set " + + "shall be" + + "\n" + + "replaced. A replacement shall be done by executing the equivalent of entirely removing the previous " + + "Group Key Set with the given GroupKeySetID, followed by an addition of a Group Key Set with the " + + "provided configuration. Otherwise, if the GroupKeySetID did not match an existing entry, a new " + + "Group Key Set associated with the accessing fabric shall be created with the provided data. The " + + "Group Key Set shall be written to non-volatile storage." + + "\n" + + "Upon completion, this command shall send a status code back to the initiator:" + + "\n" + + " • If the Group Key Set was properly installed or updated on the Node, the status code shall be " + + " set to SUCCESS." + + "\n" + + " • If there are insufficient resources on the receiver to store an additional Group Key Set, the " + + " status code shall be set to RESOURCE_EXHAUSTED (see group key limits);" + + "\n" + + " • Otherwise, this status code shall be set to FAILURE.", + + xref: { document: "core", section: "11.2.7.1" } + }, + + Field({ name: "GroupKeySet", id: 0x0, type: "GroupKeySetStruct", conformance: "M" }) + ), + + Command( + { + name: "KeySetRead", id: 0x1, access: "F A", conformance: "M", direction: "request", + response: "KeySetReadResponse", + + details: "This command is used by Administrators to read the state of a given Group Key Set." + + "\n" + + "Effect on Receipt" + + "\n" + + "If there exists a Group Key Set associated with the accessing fabric which has the same " + + "GroupKeySetID as that provided in the GroupKeySetID field, then the contents of that Group Key Set " + + "shall be sent in a KeySetReadResponse command, but with the EpochKey0, EpochKey1 and EpochKey2 " + + "fields replaced by null." + + "\n" + + "Otherwise, if the GroupKeySetID does not refer to a Group Key Set associated with the accessing " + + "fabric, then this command shall fail with a NOT_FOUND status code.", + + xref: { document: "core", section: "11.2.7.2" } + }, + + Field({ name: "GroupKeySetId", id: 0x0, type: "uint16", conformance: "M" }) + ), + + Command( + { + name: "KeySetReadResponse", id: 0x2, conformance: "M", direction: "response", + details: "This command shall be generated in response to the KeySetRead command, if a valid Group Key Set was " + + "found. It shall contain the configuration of the requested Group Key Set, with the EpochKey0, " + + "EpochKey1 and EpochKey2 key contents replaced by null.", + xref: { document: "core", section: "11.2.7.3" } + }, + + Field({ name: "GroupKeySet", id: 0x0, type: "GroupKeySetStruct", conformance: "M" }) + ), + + Command( + { + name: "KeySetRemove", id: 0x3, access: "F A", conformance: "M", direction: "request", + response: "status", + + details: "This command is used by Administrators to remove all state of a given Group Key Set." + + "\n" + + "Effect on Receipt" + + "\n" + + "If there exists a Group Key Set associated with the accessing fabric which has the same " + + "GroupKeySetID as that provided in the GroupKeySetID field, then the contents of that Group Key Set " + + "shall be removed, including all epoch keys it contains." + + "\n" + + "If there exist any entries for the accessing fabric within the GroupKeyMap attribute that refer to " + + "the GroupKeySetID just removed, then these entries shall be removed from that list." + + "\n" + + "This command shall fail with an INVALID_COMMAND status code back to the initiator if the " + + "GroupKeySetID being removed is 0, which is the Key Set associated with the Identity Protection Key " + + "(IPK). The only method to remove the IPK is usage of the RemoveFabric command or any operation " + + "which causes the equivalent of a RemoveFabric to occur by side-effect." + + "\n" + + "This command shall send a SUCCESS status code back to the initiator on success, or NOT_FOUND if the " + + "GroupKeySetID requested did not exist.", + + xref: { document: "core", section: "11.2.7.4" } + }, + + Field({ name: "GroupKeySetId", id: 0x0, type: "uint16", conformance: "M" }) + ), + + Command( + { + name: "KeySetReadAllIndices", id: 0x4, access: "F A", conformance: "M", direction: "request", + response: "KeySetReadAllIndicesResponse", + + details: "This command is used by Administrators to query a list of all Group Key Sets associated with the " + + "accessing fabric." + + "\n" + + "Effect on Receipt" + + "\n" + + "Upon receipt, this command shall iterate all stored GroupKeySetStruct associated with the accessing " + + "fabric and generate a KeySetReadAllIndicesResponse command containing the list of GroupKeySetID " + + "values from those structs.", + + xref: { document: "core", section: "11.2.7.5" } + }, + + Field({ name: "DoNotUse", id: 0x0, conformance: "X" }) + ), + + Command( + { + name: "KeySetReadAllIndicesResponse", id: 0x5, conformance: "M", direction: "response", + details: "This command shall be generated in response to KeySetReadAllIndices and it shall contain the list " + + "of GroupKeySetID for all Group Key Sets associated with the scoped Fabric.", + xref: { document: "core", section: "11.2.7.6" } + }, + + Field( + { + name: "GroupKeySetIDs", id: 0x0, type: "list", conformance: "M", + details: "This field references the set of group keys that generate operational group keys for use with the " + + "accessing fabric." + + "\n" + + "Each entry in GroupKeySetIDs is a GroupKeySetID field.", + xref: { document: "core", section: "11.2.7.6.1" } + }, + + Field({ name: "entry", type: "uint16" }) + ) + ), + + Datatype( + { name: "GroupKeySecurityPolicyEnum", type: "enum8", xref: { document: "core", section: "11.2.5.1" } }, + Field({ + name: "TrustFirst", id: 0x0, conformance: "M", + description: "Message counter synchronization using trust-first" + }), + Field({ + name: "CacheAndSync", id: 0x1, conformance: "CS", + description: "Message counter synchronization using cache-and-sync" + }) + ), + + Datatype( + { name: "GroupKeyMulticastPolicyEnum", type: "enum8", xref: { document: "core", section: "11.2.5.2" } }, + + Field({ + name: "PerGroupId", id: 0x0, conformance: "M", + description: "Indicates filtering of multicast messages for a specific Group ID", + details: "The 16-bit Group Identifier of the Multicast Address shall be the Group ID of the group.", + xref: { document: "core", section: "11.2.5.2.1" } + }), + + Field({ + name: "AllNodes", id: 0x1, conformance: "M", + description: "Indicates not filtering of multicast messages", + details: "The 16-bit Group Identifier of the Multicast Address shall be 0xFFFF.", + xref: { document: "core", section: "11.2.5.2.2" } + }) + ), + + Datatype( + { name: "GroupKeyMapStruct", type: "struct", xref: { document: "core", section: "11.2.5.3" } }, + Field({ + name: "GroupId", id: 0x1, type: "group-id", access: "F", conformance: "M", + details: "This field uniquely identifies the group within the scope of the given Fabric.", + xref: { document: "core", section: "11.2.5.3.1" } + }), + + Field({ + name: "GroupKeySetId", id: 0x2, type: "uint16", access: "F", conformance: "M", + constraint: "1 to 65535", + details: "This field references the set of group keys that generate operational group keys for use with this " + + "group, as specified in Section 4.17.3.5.1, “Group Key Set ID”." + + "\n" + + "A GroupKeyMapStruct shall NOT accept GroupKeySetID of 0, which is reserved for the IPK.", + xref: { document: "core", section: "11.2.5.3.2" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "GroupKeySetStruct", type: "struct", xref: { document: "core", section: "11.2.5.4" } }, + + Field({ + name: "GroupKeySetId", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall provide the fabric-unique index for the associated group key set, as specified in " + + "Section 4.17.3.5.1, “Group Key Set ID”.", + xref: { document: "core", section: "11.2.5.4.1" } + }), + + Field({ + name: "GroupKeySecurityPolicy", id: 0x1, type: "GroupKeySecurityPolicyEnum", access: "S", + conformance: "M", + details: "This field shall provide the security policy for an operational group key set." + + "\n" + + "When CacheAndSync is not supported in the FeatureMap of this cluster, any action attempting to set " + + "CacheAndSync in the GroupKeySecurityPolicy field shall fail with an INVALID_COMMAND error.", + xref: { document: "core", section: "11.2.5.4.2" } + }), + + Field({ + name: "EpochKey0", id: 0x2, type: "octstr", access: "S", conformance: "M", constraint: "16", + quality: "X", + details: "This field, if not null, shall be the root credential used in the derivation of an operational " + + "group key for epoch slot 0 of the given group key set. If EpochKey0 is not null, EpochStartTime0 " + + "shall NOT be null.", + xref: { document: "core", section: "11.2.5.4.3" } + }), + + Field({ + name: "EpochStartTime0", id: 0x3, type: "epoch-us", access: "S", conformance: "M", quality: "X", + details: "This field, if not null, shall define when EpochKey0 becomes valid as specified by Section 4.17.3, " + + "“Epoch Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation.", + xref: { document: "core", section: "11.2.5.4.4" } + }), + + Field({ + name: "EpochKey1", id: 0x4, type: "octstr", access: "S", conformance: "M", constraint: "16", + quality: "X", + details: "This field, if not null, shall be the root credential used in the derivation of an operational " + + "group key for epoch slot 1 of the given group key set. If EpochKey1 is not null, EpochStartTime1 " + + "shall NOT be null.", + xref: { document: "core", section: "11.2.5.4.5" } + }), + + Field({ + name: "EpochStartTime1", id: 0x5, type: "epoch-us", access: "S", conformance: "M", quality: "X", + details: "This field, if not null, shall define when EpochKey1 becomes valid as specified by Section 4.17.3, " + + "“Epoch Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation.", + xref: { document: "core", section: "11.2.5.4.6" } + }), + + Field({ + name: "EpochKey2", id: 0x6, type: "octstr", access: "S", conformance: "M", constraint: "16", + quality: "X", + details: "This field, if not null, shall be the root credential used in the derivation of an operational " + + "group key for epoch slot 2 of the given group key set. If EpochKey2 is not null, EpochStartTime2 " + + "shall NOT be null.", + xref: { document: "core", section: "11.2.5.4.7" } + }), + + Field({ + name: "EpochStartTime2", id: 0x7, type: "epoch-us", access: "S", conformance: "M", quality: "X", + details: "This field, if not null, shall define when EpochKey2 becomes valid as specified by Section 4.17.3, " + + "“Epoch Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation.", + xref: { document: "core", section: "11.2.5.4.8" } + }), + + Field({ + name: "GroupKeyMulticastPolicy", id: 0x8, type: "GroupKeyMulticastPolicyEnum", access: "S", + conformance: "P, M", + + details: "This field specifies how the IPv6 Multicast Address shall be formed for groups using this " + + "operational group key set." + + "\n" + + "The PerGroupID method maximizes filtering of multicast messages, so that receiving nodes receive " + + "only multicast messages for groups to which they are subscribed." + + "\n" + + "The AllNodes method minimizes the number of multicast addresses to which a receiver node needs to " + + "subscribe." + + "\n" + + "NOTE" + + "\n" + + "Support for GroupKeyMulticastPolicy is provisional. Correct default behavior is that implied by " + + "value PerGroupID.", + + xref: { document: "core", section: "11.2.5.4.9" } + }) + ), + + Datatype( + { name: "GroupInfoMapStruct", type: "struct", xref: { document: "core", section: "11.2.5.5" } }, + Field({ + name: "GroupId", id: 0x1, type: "group-id", access: "F", conformance: "M", + details: "This field uniquely identifies the group within the scope of the given Fabric.", + xref: { document: "core", section: "11.2.5.5.1" } + }), + + Field( + { + name: "Endpoints", id: 0x2, type: "list", access: "F", conformance: "M", constraint: "min 1", + details: "This field provides the list of Endpoint IDs on the Node to which messages to this group shall be " + + "forwarded.", + xref: { document: "core", section: "11.2.5.5.2" } + }, + + Field({ name: "entry", type: "endpoint-no" }) + ), + + Field({ + name: "GroupName", id: 0x3, type: "string", access: "F", conformance: "O", constraint: "max 16", + details: "This field provides a name for the group. This field shall contain the last GroupName written for a " + + "given GroupId on any Endpoint via the Groups cluster.", + xref: { document: "core", section: "11.2.5.5.3" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) + ), + + Cluster( + { + name: "LocalizationConfiguration", id: 0x2b, classification: "node", pics: "LCFG", + + details: "Nodes should be expected to be deployed to any and all regions of the world. These global regions " + + "may have differing common languages, units of measurements, and numerical formatting standards. As " + + "such, Nodes that visually or audibly convey information need a mechanism by which they can be " + + "configured to use a user’s preferred language, units, etc." + + "\n" + + "This cluster supports an interface to a Node. It provides attributes for determining and " + + "configuring localization information that a Node shall utilize when conveying values to a user.", + + xref: { document: "core", section: "11.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "ActiveLocale", id: 0x0, type: "string", access: "RW VM", conformance: "M", + constraint: "max 35", quality: "N", + + details: "The ActiveLocale attribute shall represent the locale that the Node is currently configured to use " + + "when conveying information. The ActiveLocale attribute shall be a Language Tag as defined by BCP47. " + + "The ActiveLocale attribute shall have a default value assigned by the Vendor and shall be a value " + + "contained within the SupportedLocales attribute." + + "\n" + + "An attempt to write a value to ActiveLocale that is not present in SupportedLocales shall result in " + + "a CONSTRAINT_ERROR error.", + + xref: { document: "core", section: "11.3.4.1" } + }), + + Attribute( + { + name: "SupportedLocales", id: 0x1, type: "list", access: "R V", conformance: "M", + constraint: "max 32[max 35]", quality: "F", + details: "The SupportedLocales attribute shall represent a list of locale strings that are valid values for " + + "the ActiveLocale attribute. The list shall NOT contain any duplicate entries. The ordering of items " + + "within the list SHOULD NOT express any meaning.", + xref: { document: "core", section: "11.3.4.2" } + }, + + Field({ name: "entry", type: "string" }) + ) + ), + + Cluster( + { + name: "TimeFormatLocalization", id: 0x2c, classification: "node", pics: "LTIME", + + details: "Nodes should be expected to be deployed to any and all regions of the world. These global regions " + + "may have differing preferences for how dates and times are conveyed. As such, Nodes that visually " + + "or audibly convey time information need a mechanism by which they can be configured to use a user’s " + + "preferred format." + + "\n" + + "This cluster supports an interface to a Node. It provides attributes for determining and " + + "configuring time and date formatting information that a Node shall utilize when conveying values to " + + "a user.", + + xref: { document: "core", section: "11.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.4.4" } }, + Field({ + name: "CALFMT", constraint: "0", description: "CalendarFormat", + details: "The Node can be configured to use different calendar formats when conveying values to a user." + }) + ), + + Attribute({ + name: "HourFormat", id: 0x0, type: "HourFormatEnum", access: "RW VM", conformance: "M", + quality: "N", + + details: "Indicates the format that the Node is currently configured to use when conveying the hour unit of " + + "time." + + "\n" + + "If not UseActiveLocale, this value shall take priority over any unit implied through the " + + "ActiveLocale attribute." + + "\n" + + "If UseActiveLocale, any unit implied through the ActiveLocale attribute is used as the hour format, " + + "and if ActiveLocale is not present, the hour format is unknown.", + + xref: { document: "core", section: "11.4.6.1" } + }), + + Attribute({ + name: "ActiveCalendarType", id: 0x1, type: "CalendarTypeEnum", access: "RW VM", + conformance: "CALFMT", quality: "N", + + details: "Indicates the calendar format that the Node is currently configured to use when conveying dates." + + "\n" + + "If not UseActiveLocale, this value shall take priority over any unit implied through the " + + "ActiveLocale attribute." + + "\n" + + "If UseActiveLocale, any unit implied through the ActiveLocale attribute is used as the calendar " + + "type, and if ActiveLocale is not present, the calendar type is unknown.", + + xref: { document: "core", section: "11.4.6.2" } + }), + + Attribute( + { + name: "SupportedCalendarTypes", id: 0x2, type: "list", access: "R V", conformance: "CALFMT", + constraint: "desc", quality: "F", + details: "Indicates a list of CalendarTypeEnum values that are supported by the Node. The list shall NOT " + + "contain any duplicate entries. The ordering of items within the list SHOULD NOT express any " + + "meaning. The maximum length of the SupportedCalendarTypes list shall be equivalent to the number of " + + "enumerations within CalendarTypeEnum.", + xref: { document: "core", section: "11.4.6.3" } + }, + + Field({ name: "entry", type: "CalendarTypeEnum" }) + ), + + Datatype( + { name: "HourFormatEnum", type: "enum8", xref: { document: "core", section: "11.4.5.1" } }, + Field({ name: "12Hr", id: 0x0, conformance: "M", description: "Time conveyed with a 12-hour clock" }), + Field({ name: "24Hr", id: 0x1, conformance: "M", description: "Time conveyed with a 24-hour clock" }), + Field({ name: "UseActiveLocale", id: 0xff, conformance: "M", description: "Use active locale clock" }) + ), + + Datatype( + { name: "CalendarTypeEnum", type: "enum8", xref: { document: "core", section: "11.4.5.2" } }, + Field({ + name: "Buddhist", id: 0x0, conformance: "O.a+", + description: "Dates conveyed using the Buddhist calendar" + }), + Field({ name: "Chinese", id: 0x1, conformance: "O.a+", description: "Dates conveyed using the Chinese calendar" }), + Field({ name: "Coptic", id: 0x2, conformance: "O.a+", description: "Dates conveyed using the Coptic calendar" }), + Field({ + name: "Ethiopian", id: 0x3, conformance: "O.a+", + description: "Dates conveyed using the Ethiopian calendar" + }), + Field({ + name: "Gregorian", id: 0x4, conformance: "O.a+", + description: "Dates conveyed using the Gregorian calendar" + }), + Field({ name: "Hebrew", id: 0x5, conformance: "O.a+", description: "Dates conveyed using the Hebrew calendar" }), + Field({ name: "Indian", id: 0x6, conformance: "O.a+", description: "Dates conveyed using the Indian calendar" }), + Field({ name: "Islamic", id: 0x7, conformance: "O.a+", description: "Dates conveyed using the Islamic calendar" }), + Field({ + name: "Japanese", id: 0x8, conformance: "O.a+", + description: "Dates conveyed using the Japanese calendar" + }), + Field({ name: "Korean", id: 0x9, conformance: "O.a+", description: "Dates conveyed using the Korean calendar" }), + Field({ name: "Persian", id: 0xa, conformance: "O.a+", description: "Dates conveyed using the Persian calendar" }), + Field({ + name: "Taiwanese", id: 0xb, conformance: "O.a+", + description: "Dates conveyed using the Taiwanese calendar" + }), + Field({ + name: "UseActiveLocale", id: 0xff, conformance: "O.a+", + description: "calendar implied from active locale" + }) + ) + ), + + Cluster( + { + name: "UnitLocalization", id: 0x2d, classification: "node", pics: "LUNIT", + + details: "Nodes should be expected to be deployed to any and all regions of the world. These global regions " + + "may have differing preferences for the units in which values are conveyed in communication to a " + + "user. As such, Nodes that visually or audibly convey measurable values to the user need a mechanism " + + "by which they can be configured to use a user’s preferred unit." + + "\n" + + "This cluster supports an interface to a Node. It provides attributes for determining and " + + "configuring the units that a Node shall utilize when conveying values in communication to a user.", + + xref: { document: "core", section: "11.5" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.5.4" } }, + Field({ + name: "TEMP", constraint: "0", description: "TemperatureUnit", + details: "The Node can be configured to use different units of temperature when conveying values to a user." + }) + ), + + Attribute({ + name: "TemperatureUnit", id: 0x0, type: "TempUnitEnum", access: "RW VM", conformance: "TEMP", + quality: "N", + details: "The TemperatureUnit attribute shall indicate the unit for the Node to use only when conveying " + + "temperature in communication to the user. If provided, this value shall take priority over any unit " + + "implied through the ActiveLocale Attribute.", + xref: { document: "core", section: "11.5.6.1" } + }), + + Datatype( + { name: "TempUnitEnum", type: "enum8", xref: { document: "core", section: "11.5.5.1" } }, + Field({ name: "Fahrenheit", id: 0x0, conformance: "M", description: "Temperature conveyed in Fahrenheit" }), + Field({ name: "Celsius", id: 0x1, conformance: "M", description: "Temperature conveyed in Celsius" }), + Field({ name: "Kelvin", id: 0x2, conformance: "M", description: "Temperature conveyed in Kelvin" }) + ) + ), + + Cluster( + { + name: "PowerSourceConfiguration", id: 0x2e, classification: "node", pics: "PSCFG", + details: "This cluster is used to describe the configuration and capabilities of a Device’s power system. It " + + "provides an ordering overview as well as linking to the one or more endpoints each supporting a " + + "Power Source cluster.", + xref: { document: "core", section: "11.6" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "Sources", id: 0x0, type: "list", access: "R V", conformance: "M", constraint: "max 6", + quality: "N", + + details: "This list shall contain the set of all power sources capable of participating in the power system " + + "of this Node. Each entry in the list shall be the endpoint number of an endpoint having a Power " + + "Source cluster, which corresponds to a physical power source. The endpoint number shall be unique " + + "within the list." + + "\n" + + "The order of power sources on a Node is defined by the Order attribute of its associated Power " + + "Source cluster provided on the endpoint. List entries shall be sorted in increasing order, that is, " + + "an entry with a lower order shall have a lower index than any entry with a higher order. Multiple " + + "entries may have the same order, there are no restrictions on their relative sorting.", + + xref: { document: "core", section: "11.6.4.1" } + }, + + Field({ name: "entry", type: "endpoint-no" }) + ) + ), + + Cluster( + { + name: "PowerSource", id: 0x2f, classification: "node", pics: "PS", + details: "This cluster is used to describe the configuration and capabilities of a physical power source that " + + "provides power to one or more endpoints on a node. In case the node has multiple power sources, " + + "each shall be described by its own cluster instance. Each instance of this cluster may be " + + "associated with one or more endpoints or the entire node.", + xref: { document: "core", section: "11.7" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.7.4" } }, + Field({ + name: "WIRED", conformance: "O.a", constraint: "0", description: "Wired", + details: "A wired power source" + }), + Field({ + name: "BAT", conformance: "O.a", constraint: "1", description: "Battery", + details: "A battery power source" + }), + Field({ + name: "RECHG", conformance: "[BAT]", constraint: "2", description: "Rechargeable", + details: "A rechargeable battery power source" + }), + Field({ + name: "REPLC", conformance: "[BAT]", constraint: "3", description: "Replaceable", + details: "A replaceable battery power source" + }) + ), + + Attribute({ + name: "Status", id: 0x0, type: "PowerSourceStatusEnum", access: "R V", conformance: "M", + constraint: "desc", + details: "Indicates the participation of this power source in providing power to the Node as specified in " + + "PowerSourceStatusEnum.", + xref: { document: "core", section: "11.7.7.1" } + }), + + Attribute({ + name: "Order", id: 0x1, type: "uint8", access: "R V", conformance: "M", quality: "N", + + details: "Indicates the relative preference with which the Node will select this source to provide power. A " + + "source with a lower order shall be selected by the Node to provide power before any other source " + + "with a higher order, if the lower order source is available (see Status)." + + "\n" + + "Note, Order is read-only and therefore NOT intended to allow clients control over power source " + + "selection.", + + xref: { document: "core", section: "11.7.7.2" } + }), + + Attribute({ + name: "Description", id: 0x2, type: "string", access: "R V", conformance: "M", constraint: "max 60", + quality: "F", + details: "This attribute shall provide a user-facing description of this source, used to distinguish it from " + + "other power sources, e.g. \"DC Power\", \"Primary Battery\" or \"Battery back-up\". This attribute shall " + + "NOT be used to convey information such as battery form factor, or chemistry.", + xref: { document: "core", section: "11.7.7.3" } + }), + + Attribute({ + name: "WiredAssessedInputVoltage", id: 0x3, type: "uint32", access: "R V", conformance: "[WIRED]", + quality: "X C", + details: "Indicates the assessed RMS or DC voltage currently provided by the hard-wired source, in mV " + + "(millivolts). A value of NULL shall indicate the Node is currently unable to assess the value. If " + + "the wired source is not connected, but the Node is still able to assess a value, then the assessed " + + "value may be reported.", + xref: { document: "core", section: "11.7.7.4" } + }), + + Attribute({ + name: "WiredAssessedInputFrequency", id: 0x4, type: "uint16", access: "R V", conformance: "[WIRED]", + quality: "X C", + details: "Indicates the assessed frequency of the voltage, currently provided by the hard-wired source, in " + + "Hz. A value of NULL shall indicate the Node is currently unable to assess the value. If the wired " + + "source is not connected, but the Node is still able to assess a value, then the assessed value may " + + "be reported.", + xref: { document: "core", section: "11.7.7.5" } + }), + + Attribute({ + name: "WiredCurrentType", id: 0x5, type: "WiredCurrentTypeEnum", access: "R V", + conformance: "WIRED", constraint: "desc", quality: "F", + details: "Indicates the type of current the Node expects to be provided by the hard- wired source as " + + "specified in WiredCurrentTypeEnum.", + xref: { document: "core", section: "11.7.7.6" } + }), + + Attribute({ + name: "WiredAssessedCurrent", id: 0x6, type: "uint32", access: "R V", conformance: "[WIRED]", + quality: "X C", + details: "Indicates the assessed instantaneous current draw of the Node on the hard- wired source, in mA " + + "(milliamps). A value of NULL shall indicate the Node is currently unable to assess the value. If " + + "the wired source is not connected, but the Node is still able to assess a value, then the assessed " + + "value may be reported.", + xref: { document: "core", section: "11.7.7.7" } + }), + + Attribute({ + name: "WiredNominalVoltage", id: 0x7, type: "uint32", access: "R V", conformance: "[WIRED]", + quality: "F", + details: "Indicates the nominal voltage, printed as part of the Node’s regulatory compliance label in mV " + + "(millivolts), expected to be provided by the hard-wired source.", + xref: { document: "core", section: "11.7.7.8" } + }), + + Attribute({ + name: "WiredMaximumCurrent", id: 0x8, type: "uint32", access: "R V", conformance: "[WIRED]", + quality: "F", + details: "Indicates the maximum current, printed as part of the Node’s regulatory compliance label in mA " + + "(milliamps), expected to be provided by the hard-wired source.", + xref: { document: "core", section: "11.7.7.9" } + }), + + Attribute({ + name: "WiredPresent", id: 0x9, type: "bool", access: "R V", conformance: "[WIRED]", + details: "Indicates if the Node detects that the hard-wired power source is properly connected.", + xref: { document: "core", section: "11.7.7.10" } + }), + + Attribute( + { + name: "ActiveWiredFaults", id: 0xa, type: "list", access: "R V", conformance: "[WIRED]", + constraint: "max 8", + + details: "Indicates the set of wired faults currently detected by the Node on this power source. This set is " + + "represented as a list of WiredFaultEnum. When the Node detects a fault has been raised, the " + + "appropriate WiredFaultEnum value shall be added to this list, provided it is not already present. " + + "This list shall NOT contain more than one instance of a specific WiredFaultEnum value. When the " + + "Node detects all conditions contributing to a fault have been cleared, the corresponding " + + "WiredFaultEnum value shall be removed from this list. An empty list shall indicate there are " + + "currently no active faults. The order of this list SHOULD have no significance. Clients interested " + + "in monitoring changes in active faults may subscribe to this attribute, or they may subscribe to " + + "WiredFaultChange.", + + xref: { document: "core", section: "11.7.7.11" } + }, + + Field({ name: "entry", type: "WiredFaultEnum" }) + ), + + Attribute({ + name: "BatVoltage", id: 0xb, type: "uint32", access: "R V", conformance: "[BAT]", quality: "X C", + details: "Indicates the currently measured output voltage of the battery in mV (millivolts). A value of NULL " + + "shall indicate the Node is currently unable to assess the value.", + xref: { document: "core", section: "11.7.7.12" } + }), + + Attribute({ + name: "BatPercentRemaining", id: 0xc, type: "uint8", access: "R V", conformance: "[BAT]", + constraint: "max 200", quality: "X Q", + + details: "Indicates the estimated percentage of battery charge remaining until the battery will no longer be " + + "able to provide power to the Node. Values are expressed in half percent units, ranging from 0 to " + + "200. E.g. a value of 48 is equivalent to 24%. A value of NULL shall indicate the Node is currently " + + "unable to assess the value." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds, or" + + "\n" + + " • When it changes from null to any other value and vice versa." + + "\n" + + "Since reporting consumes power, devices SHOULD be careful not to over-report.", + + xref: { document: "core", section: "11.7.7.13" } + }), + + Attribute({ + name: "BatTimeRemaining", id: 0xd, type: "uint32", access: "R V", conformance: "[BAT]", + quality: "X Q", + + details: "Indicates the estimated time in seconds before the battery will no longer be able to provide power " + + "to the Node. A value of NULL shall indicate the Node is currently unable to assess the value." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds, or" + + "\n" + + " • When it changes from null to any other value and vice versa." + + "\n" + + "Since reporting consumes power, devices SHOULD be careful not to over-report.", + + xref: { document: "core", section: "11.7.7.14" } + }), + + Attribute({ + name: "BatChargeLevel", id: 0xe, type: "BatChargeLevelEnum", access: "R V", conformance: "BAT", + constraint: "desc", + details: "Indicates a coarse ranking of the charge level of the battery, used to indicate when intervention " + + "is required as specified in BatChargeLevelEnum.", + xref: { document: "core", section: "11.7.7.15" } + }), + + Attribute({ + name: "BatReplacementNeeded", id: 0xf, type: "bool", access: "R V", conformance: "BAT", + details: "Indicates if the battery needs to be replaced. Replacement may be simple routine maintenance, such " + + "as with a single use, non-rechargeable cell. Replacement, however, may also indicate end of life, " + + "or serious fault with a rechargeable or even non-replaceable cell.", + xref: { document: "core", section: "11.7.7.16" } + }), + + Attribute({ + name: "BatReplaceability", id: 0x10, type: "BatReplaceabilityEnum", access: "R V", + conformance: "BAT", quality: "F", + details: "Indicates the replaceability of the battery as specified in BatReplaceabilityEnum.", + xref: { document: "core", section: "11.7.7.17" } + }), + + Attribute({ + name: "BatPresent", id: 0x11, type: "bool", access: "R V", conformance: "[BAT]", + details: "Indicates whether the Node detects that the batteries are properly installed.", + xref: { document: "core", section: "11.7.7.18" } + }), + + Attribute( + { + name: "ActiveBatFaults", id: 0x12, type: "list", access: "R V", conformance: "[BAT]", + constraint: "max 8", + + details: "Indicates the set of battery faults currently detected by the Node on this power source. This set " + + "is represented as a list of BatFaultEnum. When the Node detects a fault has been raised, the " + + "appropriate BatFaultEnum value shall be added to this list, provided it is not already present. " + + "This list shall NOT contain more than one instance of a specific BatFaultEnum value. When the Node " + + "detects all conditions contributing to a fault have been cleared, the corresponding BatFaultEnum " + + "value shall be removed from this list. An empty list shall indicate there are currently no active " + + "faults. The order of this list SHOULD have no significance. Clients interested in monitoring " + + "changes in active faults may subscribe to this attribute, or they may subscribe to Bat" + + "\n" + + "FaultChange.", + + xref: { document: "core", section: "11.7.7.19" } + }, + + Field({ name: "entry", type: "BatFaultEnum" }) + ), + + Attribute({ + name: "BatReplacementDescription", id: 0x13, type: "string", access: "R V", conformance: "REPLC", + constraint: "max 60", quality: "F", + details: "This attribute shall provide a user-facing description of this battery, which SHOULD contain " + + "information required to identify a replacement, such as form factor, chemistry or preferred " + + "manufacturer.", + xref: { document: "core", section: "11.7.7.20" } + }), + + Attribute({ + name: "BatCommonDesignation", id: 0x14, type: "BatCommonDesignationEnum", access: "R V", + conformance: "[REPLC]", constraint: "desc", quality: "F", + details: "Indicates the ID of the common or colloquial designation of the battery, as specified in " + + "BatCommonDesignationEnum.", + xref: { document: "core", section: "11.7.7.21" } + }), + + Attribute({ + name: "BatAnsiDesignation", id: 0x15, type: "string", access: "R V", conformance: "[REPLC]", + constraint: "max 20", quality: "F", + details: "Indicates the string representing the ANSI designation for the battery as specified in ANSI C18.", + xref: { document: "core", section: "11.7.7.22" } + }), + + Attribute({ + name: "BatIecDesignation", id: 0x16, type: "string", access: "R V", conformance: "[REPLC]", + constraint: "max 20", quality: "F", + details: "Indicates the string representing the IEC designation for the battery as specified in IEC 60086.", + xref: { document: "core", section: "11.7.7.23" } + }), + + Attribute({ + name: "BatApprovedChemistry", id: 0x17, type: "BatApprovedChemistryEnum", access: "R V", + conformance: "[REPLC]", constraint: "desc", quality: "F", + details: "Indicates the ID of the preferred chemistry of the battery source as specified in " + + "BatApprovedChemistryEnum.", + xref: { document: "core", section: "11.7.7.24" } + }), + + Attribute({ + name: "BatCapacity", id: 0x18, type: "uint32", access: "R V", conformance: "[REPLC | RECHG]", + quality: "F", + details: "Indicates the preferred minimum charge capacity rating in mAh of individual, user- or " + + "factory-serviceable battery cells or packs in the battery source.", + xref: { document: "core", section: "11.7.7.25" } + }), + + Attribute({ + name: "BatQuantity", id: 0x19, type: "uint8", access: "R V", conformance: "REPLC", quality: "F", + details: "Indicates the quantity of individual, user- or factory-serviceable battery cells or packs in the " + + "battery source.", + xref: { document: "core", section: "11.7.7.26" } + }), + + Attribute({ + name: "BatChargeState", id: 0x1a, type: "BatChargeStateEnum", access: "R V", conformance: "RECHG", + constraint: "desc", + details: "Indicates the current state of the battery source with respect to charging as specified in " + + "BatChargeStateEnum.", + xref: { document: "core", section: "11.7.7.27" } + }), + + Attribute({ + name: "BatTimeToFullCharge", id: 0x1b, type: "uint32", access: "R V", conformance: "[RECHG]", + quality: "X Q", + + details: "Indicates the estimated time in seconds before the battery source will be at full charge. A value " + + "of NULL shall indicate the Node is currently unable to assess the value." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds, or" + + "\n" + + " • When it changes from null to any other value and vice versa." + + "\n" + + "Since reporting consumes power, devices SHOULD be careful not to over-report.", + + xref: { document: "core", section: "11.7.7.28" } + }), + + Attribute({ + name: "BatFunctionalWhileCharging", id: 0x1c, type: "bool", access: "R V", conformance: "RECHG", + details: "Indicates whether the Node can remain operational while the battery source is charging.", + xref: { document: "core", section: "11.7.7.29" } + }), + + Attribute({ + name: "BatChargingCurrent", id: 0x1d, type: "uint32", access: "R V", conformance: "[RECHG]", + quality: "X C", + details: "Indicates assessed current in mA (milliamps) presently supplied to charge the battery source. A " + + "value of NULL shall indicate the Node is currently unable to assess the value.", + xref: { document: "core", section: "11.7.7.30" } + }), + + Attribute( + { + name: "ActiveBatChargeFaults", id: 0x1e, type: "list", access: "R V", conformance: "[RECHG]", + constraint: "max 16", + + details: "Indicates the set of charge faults currently detected by the Node on this power source. This set is " + + "represented as a list of BatChargeFaultEnum. When the Node detects a fault has been raised, the " + + "appropriate BatChargeFaultEnum value shall be added to this list, provided it is not already " + + "present. This list shall NOT contain more than one instance of a specific BatChargeFaultEnum value. " + + "When the Node detects all conditions contributing to a fault have been cleared, the corresponding " + + "BatChargeFaultEnum value shall be removed from this list. An empty list shall indicate there are " + + "currently no active faults. The order of this list SHOULD have no significance. Clients interested " + + "in monitoring changes in active faults may subscribe to this attribute, or they may subscribe to " + + "the BatFaultChange event.", + + xref: { document: "core", section: "11.7.7.31" } + }, + + Field({ name: "entry", type: "BatChargeFaultEnum" }) + ), + + Attribute( + { + name: "EndpointList", id: 0x1f, type: "list", access: "R V", conformance: "M", + + details: "Indicates a list of endpoints that are powered by the source defined by this cluster. Multiple " + + "instances of this cluster may list the same endpoint, because it is possible for power for an " + + "endpoint to come from multiple sources. In that case the Order attribute indicates their priority." + + "\n" + + "For each power source on a node, there shall only be one instance of this cluster." + + "\n" + + "A cluster instance with an empty list shall indicate that the power source is for the entire node, " + + "which includes all endpoints." + + "\n" + + "A cluster instance with a non-empty list shall include the endpoint, upon which the cluster " + + "instance resides." + + "\n" + + "The above rules allow that some endpoints can have an unknown power source, and therefore would not " + + "be indicated by any instance of this cluster." + + "\n" + + "Empty list examples" + + "\n" + + "Typically, there is one power source for the node. Also common is mains power for the node with " + + "battery backup power for the node. In both these common cases, for each cluster instance described, " + + "the list is empty." + + "\n" + + "Populated list example" + + "\n" + + "A node has a mains power source with Order as 0 (zero), but some application endpoints (not all) " + + "have a battery back up source with Order as 1, which means this list is empty for the Power Source " + + "cluster associated with the mains power, because it indicates the entire node, but the Power Source " + + "cluster instance associated with the battery backup would list the endpoints that have a battery " + + "backup.", + + xref: { document: "core", section: "11.7.7.32" } + }, + + Field({ name: "entry", type: "endpoint-no" }) + ), + + Event( + { + name: "WiredFaultChange", id: 0x0, access: "V", conformance: "[WIRED]", priority: "info", + details: "The WiredFaultChange Event shall be generated when the set of wired faults currently detected by " + + "the Node on this wired power source changes. This event shall correspond to a change in value of " + + "ActiveWiredFaults.", + xref: { document: "core", section: "11.7.8.1" } + }, + + Field( + { + name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 8", default: [], + details: "This field shall represent the set of faults currently detected, as per ActiveWiredFaults.", + xref: { document: "core", section: "11.7.8.1.1" } + }, + Field({ name: "entry", type: "WiredFaultEnum" }) + ), + + Field( + { + name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 8", default: [], + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "ActiveWiredFaults.", + xref: { document: "core", section: "11.7.8.1.2" } + }, + + Field({ name: "entry", type: "WiredFaultEnum" }) + ) + ), + + Event( + { + name: "BatFaultChange", id: 0x1, access: "V", conformance: "[BAT]", priority: "info", + details: "The BatFaultChange Event shall be generated when the set of battery faults currently detected by " + + "the Node on this battery power source changes. This event shall correspond to a change in value of " + + "ActiveBatFaults.", + xref: { document: "core", section: "11.7.8.2" } + }, + + Field( + { + name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 8", default: [], + details: "This field shall represent the set of faults currently detected, as per ActiveBatFaults.", + xref: { document: "core", section: "11.7.8.2.1" } + }, + Field({ name: "entry", type: "BatFaultEnum" }) + ), + + Field( + { + name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 8", default: [], + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "ActiveBatFaults.", + xref: { document: "core", section: "11.7.8.2.2" } + }, + + Field({ name: "entry", type: "BatFaultEnum" }) + ) + ), + + Event( + { + name: "BatChargeFaultChange", id: 0x2, access: "V", conformance: "[RECHG]", priority: "info", + details: "The BatChargeFaultChange Event shall be generated when the set of charge faults currently detected " + + "by the Node on this battery power source changes. This event shall correspond to a change in value " + + "of ActiveBatChargeFaults.", + xref: { document: "core", section: "11.7.8.3" } + }, + + Field( + { + name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 16", default: [], + details: "This field shall represent the set of faults currently detected, as per ActiveBatChargeFaults.", + xref: { document: "core", section: "11.7.8.3.1" } + }, + Field({ name: "entry", type: "BatChargeFaultEnum" }) + ), + + Field( + { + name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 16", default: [], + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "ActiveBatChargeFaults.", + xref: { document: "core", section: "11.7.8.3.2" } + }, + + Field({ name: "entry", type: "BatChargeFaultEnum" }) + ) + ), + + Datatype( + { name: "WiredFaultEnum", type: "enum8", xref: { document: "core", section: "11.7.6.1" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "The Node detects an unspecified fault on this wired power source." + }), + Field({ + name: "OverVoltage", id: 0x1, conformance: "M", + description: "The Node detects the supplied voltage is above maximum supported value for this wired power source." + }), + Field({ + name: "UnderVoltage", id: 0x2, conformance: "M", + description: "The Node detects the supplied voltage is below maximum supported value for this wired power source." + }) + ), + + Datatype( + { name: "BatFaultEnum", type: "enum8", xref: { document: "core", section: "11.7.6.2" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "The Node detects an unspecified fault on this battery power source." + }), + Field({ + name: "OverTemp", id: 0x1, conformance: "M", + description: "The Node detects the temperature of this battery power source is above ideal operating conditions." + }), + Field({ + name: "UnderTemp", id: 0x2, conformance: "M", + description: "The Node detects the temperature of this battery power source is below ideal operating conditions." + }) + ), + + Datatype( + { name: "BatChargeFaultEnum", type: "enum8", xref: { document: "core", section: "11.7.6.3" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "The Node detects an unspecified fault on this battery source." + }), + Field({ + name: "AmbientTooHot", id: 0x1, conformance: "M", + description: "The Node detects the ambient temperature is above the nominal range for this battery source." + }), + Field({ + name: "AmbientTooCold", id: 0x2, conformance: "M", + description: "The Node detects the ambient temperature is below the nominal range for this battery source." + }), + Field({ + name: "BatteryTooHot", id: 0x3, conformance: "M", + description: "The Node detects the temperature of this battery source is above the nominal range." + }), + Field({ + name: "BatteryTooCold", id: 0x4, conformance: "M", + description: "The Node detects the temperature of this battery source is below the nominal range." + }), + Field({ + name: "BatteryAbsent", id: 0x5, conformance: "M", + description: "The Node detects this battery source is not present." + }), + Field({ + name: "BatteryOverVoltage", id: 0x6, conformance: "M", + description: "The Node detects this battery source is over voltage." + }), + Field({ + name: "BatteryUnderVoltage", id: 0x7, conformance: "M", + description: "The Node detects this battery source is under voltage." + }), + Field({ + name: "ChargerOverVoltage", id: 0x8, conformance: "M", + description: "The Node detects the charger for this battery source is over voltage." + }), + Field({ + name: "ChargerUnderVoltage", id: 0x9, conformance: "M", + description: "The Node detects the charger for this battery source is under voltage." + }), + Field({ + name: "SafetyTimeout", id: 0xa, conformance: "M", + description: "The Node detects a charging safety timeout for this battery source." + }) + ), + + Datatype( + { name: "PowerSourceStatusEnum", type: "enum8", xref: { document: "core", section: "11.7.6.4" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "Indicate the source status is not specified" + }), + Field({ + name: "Active", id: 0x1, conformance: "M", + description: "Indicate the source is available and currently supplying power" + }), + Field({ + name: "Standby", id: 0x2, conformance: "M", + description: "Indicate the source is available, but is not currently supplying power" + }), + Field({ + name: "Unavailable", id: 0x3, conformance: "M", + description: "Indicate the source is not currently available to supply power" + }) + ), + + Datatype( + { name: "WiredCurrentTypeEnum", type: "enum8", xref: { document: "core", section: "11.7.6.5" } }, + Field({ name: "Ac", id: 0x0, conformance: "M", description: "Indicates AC current" }), + Field({ name: "Dc", id: 0x1, conformance: "M", description: "Indicates DC current" }) + ), + + Datatype( + { name: "BatChargeLevelEnum", type: "enum8", xref: { document: "core", section: "11.7.6.6" } }, + Field({ name: "Ok", id: 0x0, conformance: "M", description: "Charge level is nominal" }), + Field({ + name: "Warning", id: 0x1, conformance: "M", + description: "Charge level is low, intervention may soon be required." + }), + Field({ + name: "Critical", id: 0x2, conformance: "M", + description: "Charge level is critical, immediate intervention is required" + }) + ), + + Datatype( + { name: "BatReplaceabilityEnum", type: "enum8", xref: { document: "core", section: "11.7.6.7" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "The replaceability is unspecified or unknown." + }), + Field({ name: "NotReplaceable", id: 0x1, conformance: "M", description: "The battery is not replaceable." }), + Field({ + name: "UserReplaceable", id: 0x2, conformance: "M", + description: "The battery is replaceable by the user or customer." + }), + Field({ + name: "FactoryReplaceable", id: 0x3, conformance: "M", + description: "The battery is replaceable by an authorized factory technician." + }) + ), + + Datatype( + { name: "BatCommonDesignationEnum", type: "enum16", xref: { document: "core", section: "11.7.6.8" } }, + Field({ name: "Unspecified", id: 0x0, conformance: "M", description: "Common type is unknown or unspecified" }), + Field({ name: "Aaa", id: 0x1, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Aa", id: 0x2, conformance: "M", description: "Common type is as specified" }), + Field({ name: "C", id: 0x3, conformance: "M", description: "Common type is as specified" }), + Field({ name: "D", id: 0x4, conformance: "M", description: "Common type is as specified" }), + Field({ name: "4V5", id: 0x5, conformance: "M", description: "Common type is as specified" }), + Field({ name: "6V0", id: 0x6, conformance: "M", description: "Common type is as specified" }), + Field({ name: "9V0", id: 0x7, conformance: "M", description: "Common type is as specified" }), + Field({ name: "12Aa", id: 0x8, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Aaaa", id: 0x9, conformance: "M", description: "Common type is as specified" }), + Field({ name: "A", id: 0xa, conformance: "M", description: "Common type is as specified" }), + Field({ name: "B", id: 0xb, conformance: "M", description: "Common type is as specified" }), + Field({ name: "F", id: 0xc, conformance: "M", description: "Common type is as specified" }), + Field({ name: "N", id: 0xd, conformance: "M", description: "Common type is as specified" }), + Field({ name: "No6", id: 0xe, conformance: "M", description: "Common type is as specified" }), + Field({ name: "SubC", id: 0xf, conformance: "M", description: "Common type is as specified" }), + Field({ name: "A23", id: 0x10, conformance: "M", description: "Common type is as specified" }), + Field({ name: "A27", id: 0x11, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Ba5800", id: 0x12, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Duplex", id: 0x13, conformance: "M", description: "Common type is as specified" }), + Field({ name: "4Sr44", id: 0x14, conformance: "M", description: "Common type is as specified" }), + Field({ name: "523", id: 0x15, conformance: "M", description: "Common type is as specified" }), + Field({ name: "531", id: 0x16, conformance: "M", description: "Common type is as specified" }), + Field({ name: "15V0", id: 0x17, conformance: "M", description: "Common type is as specified" }), + Field({ name: "22V5", id: 0x18, conformance: "M", description: "Common type is as specified" }), + Field({ name: "30V0", id: 0x19, conformance: "M", description: "Common type is as specified" }), + Field({ name: "45V0", id: 0x1a, conformance: "M", description: "Common type is as specified" }), + Field({ name: "67V5", id: 0x1b, conformance: "M", description: "Common type is as specified" }), + Field({ name: "J", id: 0x1c, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Cr123A", id: 0x1d, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Cr2", id: 0x1e, conformance: "M", description: "Common type is as specified" }), + Field({ name: "2Cr5", id: 0x1f, conformance: "M", description: "Common type is as specified" }), + Field({ name: "CrP2", id: 0x20, conformance: "M", description: "Common type is as specified" }), + Field({ name: "CrV3", id: 0x21, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr41", id: 0x22, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr43", id: 0x23, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr44", id: 0x24, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr45", id: 0x25, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr48", id: 0x26, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr54", id: 0x27, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr55", id: 0x28, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr57", id: 0x29, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr58", id: 0x2a, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr59", id: 0x2b, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr60", id: 0x2c, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr63", id: 0x2d, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr64", id: 0x2e, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr65", id: 0x2f, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr66", id: 0x30, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr67", id: 0x31, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr68", id: 0x32, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr69", id: 0x33, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr516", id: 0x34, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr731", id: 0x35, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Sr712", id: 0x36, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Lr932", id: 0x37, conformance: "M", description: "Common type is as specified" }), + Field({ name: "A5", id: 0x38, conformance: "M", description: "Common type is as specified" }), + Field({ name: "A10", id: 0x39, conformance: "M", description: "Common type is as specified" }), + Field({ name: "A13", id: 0x3a, conformance: "M", description: "Common type is as specified" }), + Field({ name: "A312", id: 0x3b, conformance: "M", description: "Common type is as specified" }), + Field({ name: "A675", id: 0x3c, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Ac41E", id: 0x3d, conformance: "M", description: "Common type is as specified" }), + Field({ name: "10180", id: 0x3e, conformance: "M", description: "Common type is as specified" }), + Field({ name: "10280", id: 0x3f, conformance: "M", description: "Common type is as specified" }), + Field({ name: "10440", id: 0x40, conformance: "M", description: "Common type is as specified" }), + Field({ name: "14250", id: 0x41, conformance: "M", description: "Common type is as specified" }), + Field({ name: "14430", id: 0x42, conformance: "M", description: "Common type is as specified" }), + Field({ name: "14500", id: 0x43, conformance: "M", description: "Common type is as specified" }), + Field({ name: "14650", id: 0x44, conformance: "M", description: "Common type is as specified" }), + Field({ name: "15270", id: 0x45, conformance: "M", description: "Common type is as specified" }), + Field({ name: "16340", id: 0x46, conformance: "M", description: "Common type is as specified" }), + Field({ name: "Rcr123A", id: 0x47, conformance: "M", description: "Common type is as specified" }), + Field({ name: "17500", id: 0x48, conformance: "M", description: "Common type is as specified" }), + Field({ name: "17670", id: 0x49, conformance: "M", description: "Common type is as specified" }), + Field({ name: "18350", id: 0x4a, conformance: "M", description: "Common type is as specified" }), + Field({ name: "18500", id: 0x4b, conformance: "M", description: "Common type is as specified" }), + Field({ name: "18650", id: 0x4c, conformance: "M", description: "Common type is as specified" }), + Field({ name: "19670", id: 0x4d, conformance: "M", description: "Common type is as specified" }), + Field({ name: "25500", id: 0x4e, conformance: "M", description: "Common type is as specified" }), + Field({ name: "26650", id: 0x4f, conformance: "M", description: "Common type is as specified" }), + Field({ name: "32600", id: 0x50, conformance: "M", description: "Common type is as specified" }) + ), + + Datatype( + { name: "BatApprovedChemistryEnum", type: "enum16", xref: { document: "core", section: "11.7.6.9" } }, + Field({ name: "Unspecified", id: 0x0, conformance: "M", description: "Cell chemistry is unspecified or unknown" }), + Field({ name: "Alkaline", id: 0x1, conformance: "M", description: "Cell chemistry is alkaline" }), + Field({ + name: "LithiumCarbonFluoride", id: 0x2, conformance: "M", + description: "Cell chemistry is lithium carbon fluoride" + }), + Field({ + name: "LithiumChromiumOxide", id: 0x3, conformance: "M", + description: "Cell chemistry is lithium chromium oxide" + }), + Field({ + name: "LithiumCopperOxide", id: 0x4, conformance: "M", + description: "Cell chemistry is lithium copper oxide" + }), + Field({ + name: "LithiumIronDisulfide", id: 0x5, conformance: "M", + description: "Cell chemistry is lithium iron disulfide" + }), + Field({ + name: "LithiumManganeseDioxide", id: 0x6, conformance: "M", + description: "Cell chemistry is lithium manganese dioxide" + }), + Field({ + name: "LithiumThionylChloride", id: 0x7, conformance: "M", + description: "Cell chemistry is lithium thionyl chloride" + }), + Field({ name: "Magnesium", id: 0x8, conformance: "M", description: "Cell chemistry is magnesium" }), + Field({ name: "MercuryOxide", id: 0x9, conformance: "M", description: "Cell chemistry is mercury oxide" }), + Field({ name: "NickelOxyhydride", id: 0xa, conformance: "M", description: "Cell chemistry is nickel oxyhydride" }), + Field({ name: "SilverOxide", id: 0xb, conformance: "M", description: "Cell chemistry is silver oxide" }), + Field({ name: "ZincAir", id: 0xc, conformance: "M", description: "Cell chemistry is zinc air" }), + Field({ name: "ZincCarbon", id: 0xd, conformance: "M", description: "Cell chemistry is zinc carbon" }), + Field({ name: "ZincChloride", id: 0xe, conformance: "M", description: "Cell chemistry is zinc chloride" }), + Field({ + name: "ZincManganeseDioxide", id: 0xf, conformance: "M", + description: "Cell chemistry is zinc manganese dioxide" + }), + Field({ name: "LeadAcid", id: 0x10, conformance: "M", description: "Cell chemistry is lead acid" }), + Field({ + name: "LithiumCobaltOxide", id: 0x11, conformance: "M", + description: "Cell chemistry is lithium cobalt oxide" + }), + Field({ name: "LithiumIon", id: 0x12, conformance: "M", description: "Cell chemistry is lithium ion" }), + Field({ + name: "LithiumIonPolymer", id: 0x13, conformance: "M", + description: "Cell chemistry is lithium ion polymer" + }), + Field({ + name: "LithiumIronPhosphate", id: 0x14, conformance: "M", + description: "Cell chemistry is lithium iron phosphate" + }), + Field({ name: "LithiumSulfur", id: 0x15, conformance: "M", description: "Cell chemistry is lithium sulfur" }), + Field({ name: "LithiumTitanate", id: 0x16, conformance: "M", description: "Cell chemistry is lithium titanate" }), + Field({ name: "NickelCadmium", id: 0x17, conformance: "M", description: "Cell chemistry is nickel cadmium" }), + Field({ name: "NickelHydrogen", id: 0x18, conformance: "M", description: "Cell chemistry is nickel hydrogen" }), + Field({ name: "NickelIron", id: 0x19, conformance: "M", description: "Cell chemistry is nickel iron" }), + Field({ + name: "NickelMetalHydride", id: 0x1a, conformance: "M", + description: "Cell chemistry is nickel metal hydride" + }), + Field({ name: "NickelZinc", id: 0x1b, conformance: "M", description: "Cell chemistry is nickel zinc" }), + Field({ name: "SilverZinc", id: 0x1c, conformance: "M", description: "Cell chemistry is silver zinc" }), + Field({ name: "SodiumIon", id: 0x1d, conformance: "M", description: "Cell chemistry is sodium ion" }), + Field({ name: "SodiumSulfur", id: 0x1e, conformance: "M", description: "Cell chemistry is sodium sulfur" }), + Field({ name: "ZincBromide", id: 0x1f, conformance: "M", description: "Cell chemistry is zinc bromide" }), + Field({ name: "ZincCerium", id: 0x20, conformance: "M", description: "Cell chemistry is zinc cerium" }) + ), + + Datatype( + { name: "BatChargeStateEnum", type: "enum8", xref: { document: "core", section: "11.7.6.10" } }, + Field({ name: "Unknown", id: 0x0, conformance: "M", description: "Unable to determine the charging state" }), + Field({ name: "IsCharging", id: 0x1, conformance: "M", description: "The battery is charging" }), + Field({ name: "IsAtFullCharge", id: 0x2, conformance: "M", description: "The battery is at full charge" }), + Field({ name: "IsNotCharging", id: 0x3, conformance: "M", description: "The battery is not charging" }) + ) + ), + + Cluster( + { + name: "PowerTopology", id: 0x9c, classification: "application", pics: "PWRTL", + details: "The Power Topology Cluster provides a mechanism for expressing how power is flowing between " + + "endpoints.", + xref: { document: "core", section: "11.8" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.8.4" } }, + Field({ + name: "NODE", conformance: "O.a", constraint: "0", description: "NodeTopology", + details: "This endpoint provides or consumes power to/from the entire node" + }), + Field({ + name: "TREE", conformance: "O.a", constraint: "1", description: "TreeTopology", + details: "This endpoint provides or consumes power to/from itself and its child endpoints" + }), + Field({ + name: "SET", conformance: "O.a", constraint: "2", description: "SetTopology", + details: "This endpoint provides or consumes power to/from a specified set of endpoints" + }), + Field({ + name: "DYPF", conformance: "[SET]", constraint: "3", description: "DynamicPowerFlow", + details: "The specified set of endpoints may change" + }) + ), + + Attribute( + { + name: "AvailableEndpoints", id: 0x0, type: "list", access: "R V", conformance: "SET", + constraint: "max 20", quality: "F", + details: "Indicates the list of endpoints capable of providing power to and/or consuming power from the " + + "endpoint hosting this server.", + xref: { document: "core", section: "11.8.5.1" } + }, + + Field({ name: "entry", type: "endpoint-no" }) + ), + + Attribute( + { + name: "ActiveEndpoints", id: 0x1, type: "list", access: "R V", conformance: "DYPF", + constraint: "max 20", quality: "N", + details: "Indicates the current list of endpoints currently providing or consuming power to or from the " + + "endpoint hosting this server. This list shall be a subset of the value of the AvailableEndpoints " + + "attribute.", + xref: { document: "core", section: "11.8.5.2" } + }, + + Field({ name: "entry", type: "endpoint-no" }) + ) + ), + + Cluster( + { + name: "NetworkCommissioning", id: 0x31, classification: "node", pics: "CNET", + + details: "Network commissioning is part of the overall Node commissioning. The main goal of Network " + + "Commissioning Cluster is to associate a Node with or manage a Node’s one or more network " + + "interfaces. These network interfaces can include the following types." + + "\n" + + " • Wi-Fi (IEEE 802.11-2020)" + + "\n" + + " • Ethernet (802.3)" + + "\n" + + " • Thread (802.15.4)" + + "\n" + + "An instance of the Network Commissioning Cluster only applies to a single network interface " + + "instance present. An interface, in this context, is a unique entity that can have an IPv6 address " + + "assigned to it and ingress and egress IP packets.", + + xref: { document: "core", section: "11.9" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.9.4" } }, + Field({ + name: "WI", conformance: "O.a", constraint: "0", description: "WiFiNetworkInterface", + details: "Wi-Fi related features" + }), + Field({ + name: "TH", conformance: "O.a", constraint: "1", description: "ThreadNetworkInterface", + details: "Thread related features" + }), + Field({ + name: "ET", conformance: "O.a", constraint: "2", description: "EthernetNetworkInterface", + details: "Ethernet related features" + }) + ), + + Attribute({ + name: "MaxNetworks", id: 0x0, type: "uint8", access: "R A", conformance: "M", constraint: "min 1", + quality: "F", + details: "This shall indicate the maximum number of network configuration entries that can be added, based on " + + "available device resources. The length of the Networks attribute shall be less than or equal to " + + "this value.", + xref: { document: "core", section: "11.9.6.1" } + }), + + Attribute( + { + name: "Networks", id: 0x1, type: "list", access: "R A", conformance: "M", + constraint: "max maxNetworks", default: [], + + details: "Indicates the network configurations that are usable on the network interface represented by this " + + "cluster server instance." + + "\n" + + "The order of configurations in the list reflects precedence. That is, any time the Node attempts to " + + "connect to the network it shall attempt to do so using the configurations in Networks Attribute in " + + "the order as they appear in the list." + + "\n" + + "The order of list items shall only be modified by the AddOrUpdateThreadNetwork, " + + "AddOrUpdateWiFiNetwork and ReorderNetwork commands. In other words, the list shall be stable over " + + "time, unless mutated externally." + + "\n" + + "Ethernet networks shall be automatically populated by the cluster server. Ethernet Network " + + "Commissioning Cluster instances shall always have exactly one NetworkInfoStruct instance in their " + + "Networks attribute. There shall be no way to add, update or remove Ethernet network configurations " + + "to those Cluster instances.", + + xref: { document: "core", section: "11.9.6.2" } + }, + + Field({ name: "entry", type: "NetworkInfoStruct" }) + ), + + Attribute({ + name: "ScanMaxTimeSeconds", id: 0x2, type: "uint8", access: "R V", conformance: "WI | TH", + constraint: "desc", quality: "F", + details: "Indicates the maximum duration taken, in seconds, by the network interface on this cluster server " + + "instance to provide scan results." + + "\n" + + "See ScanNetworks for usage.", + xref: { document: "core", section: "11.9.6.3" } + }), + + Attribute({ + name: "ConnectMaxTimeSeconds", id: 0x3, type: "uint8", access: "R V", conformance: "WI | TH", + constraint: "desc", quality: "F", + + details: "Indicates the maximum duration taken, in seconds, by the network interface on this cluster server " + + "instance to report a successful or failed network connection indication. This maximum time shall " + + "account for all operations needed until a successful network connection is" + + "\n" + + "deemed to have occurred, including, for example, obtaining IP addresses, or the execution of " + + "necessary internal retries.", + + xref: { document: "core", section: "11.9.6.4" } + }), + + Attribute({ + name: "InterfaceEnabled", id: 0x4, type: "bool", access: "RW VA", conformance: "M", default: true, + quality: "N", + + details: "Indicates whether the associated network interface is enabled or not. By default all network " + + "interfaces SHOULD be enabled during initial commissioning (InterfaceEnabled set to true)." + + "\n" + + "It is undefined what happens if InterfaceEnabled is written to false on the same interface as that " + + "which is used to write the value. In that case, it is possible that the Administrator would have to " + + "await expiry of the fail-safe, and associated recovery of network configuration to prior safe " + + "values, before being able to communicate with the node again (see ArmFailSafe)." + + "\n" + + "It may be possible to disable Ethernet interfaces but it is implementation-defined. If not " + + "supported, a write to this attribute with a value of false shall fail with a status of " + + "INVALID_ACTION. When disabled, an Ethernet interface would longer employ media detection. That is, " + + "a simple unplug and replug of the cable shall NOT re-enable the interface." + + "\n" + + "On Ethernet-only Nodes, there shall always be at least one of the Network Commissioning server " + + "cluster instances with InterfaceEnabled set to true.", + + xref: { document: "core", section: "11.9.6.5" } + }), + + Attribute({ + name: "LastNetworkingStatus", id: 0x5, type: "NetworkCommissioningStatusEnum", access: "R A", + conformance: "M", default: null, quality: "X", + + details: "Indicates the status of the last attempt either scan or connect to an operational network, using " + + "this interface, whether by invocation of the ConnectNetwork command or by autonomous connection " + + "after loss of connectivity or during initial establishment. If no such attempt was made, or no " + + "network configurations exist in the Networks attribute, then this attribute shall be set to null." + + "\n" + + "This attribute is present to assist with error recovery during Network commissioning and to assist " + + "in non-concurrent networking commissioning flows.", + + xref: { document: "core", section: "11.9.6.6" } + }), + + Attribute({ + name: "LastNetworkId", id: 0x6, type: "octstr", access: "R A", conformance: "M", + constraint: "1 to 32", default: null, quality: "X", + + details: "Indicates the NetworkID used in the last attempt to connect to an operational network, using this " + + "interface, whether by invocation of the ConnectNetwork command or by autonomous connection after " + + "loss of connectivity or during initial establishment. If no such attempt was made, or no network " + + "configurations exist in the Networks attribute, then this attribute shall be set to null." + + "\n" + + "If a network configuration is removed from the Networks attribute using the RemoveNetwork command " + + "after a connection attempt, this field may indicate a NetworkID that is no longer configured on the " + + "Node." + + "\n" + + "This attribute is present to assist with error recovery during Network commissioning and to assist " + + "in non-concurrent networking commissioning flows.", + + xref: { document: "core", section: "11.9.6.7" } + }), + + Attribute({ + name: "LastConnectErrorValue", id: 0x7, type: "int32", access: "R A", conformance: "M", + default: null, quality: "X", + + details: "Indicates the ErrorValue used in the last failed attempt to connect to an operational network, " + + "using this interface, whether by invocation of the ConnectNetwork command or by autonomous " + + "connection after loss of connectivity or during initial establishment. If no such attempt was made, " + + "or no network configurations exist in the Networks attribute, then this attribute shall be set to " + + "null." + + "\n" + + "If the last connection succeeded, as indicated by a value of Success in the LastNetworkingStatus " + + "attribute, then this field shall be set to null." + + "\n" + + "This attribute is present to assist with error recovery during Network commissioning and to assist " + + "in non-concurrent networking commissioning flows.", + + xref: { document: "core", section: "11.9.6.8" } + }), + + Attribute( + { + name: "SupportedWiFiBands", id: 0x8, type: "list", access: "R V", conformance: "WI", + constraint: "min 1", quality: "F", + details: "Indicates all the frequency bands supported by the Wi-Fi interface configured by the cluster " + + "instance.", + xref: { document: "core", section: "11.9.6.9" } + }, + + Field({ name: "entry", type: "WiFiBandEnum" }) + ), + + Attribute({ + name: "SupportedThreadFeatures", id: 0x9, type: "ThreadCapabilitiesBitmap", access: "R V", + conformance: "TH", quality: "F", + + details: "Indicates all of the Thread features supported by the Thread interface configured by the cluster " + + "instance." + + "\n" + + "This attribute is primarily used to determine the most important general capabilities of the Thread " + + "interface associated with the cluster instance, as opposed to the current runtime dynamic " + + "configuration. Note that most run-time details of the actual Thread interface are found in the " + + "Thread Network Diagnostics cluster, if supported.", + + xref: { document: "core", section: "11.9.6.10" } + }), + + Attribute({ + name: "ThreadVersion", id: 0xa, type: "uint16", access: "R V", conformance: "TH", quality: "F", + details: "Indicates the Thread version supported by the Thread interface configured by the cluster instance." + + "\n" + + "The format shall match the value mapping found in the \"Version TLV\" section of Thread " + + "specification. For example, Thread 1.3.0 would have ThreadVersion set to 4.", + xref: { document: "core", section: "11.9.6.11" } + }), + + Command( + { + name: "ScanNetworks", id: 0x0, access: "A", conformance: "WI | TH", direction: "request", + response: "ScanNetworksResponse", + + details: "This command shall scan on the Cluster instance’s associated network interface for either of:" + + "\n" + + " • All available networks (non-directed scanning)" + + "\n" + + " • Specific networks (directed scanning)" + + "\n" + + "Scanning for available networks detects all networks of the type corresponding to the cluster " + + "server instance’s associated network interface that are possible to join, such as all visible Wi-Fi " + + "access points for Wi-Fi cluster server instances, all Thread PANs for Thread cluster server " + + "instances, within bounds of the maximum response size." + + "\n" + + "Scanning for a specific network (i.e. directed scanning) takes place if a network identifier (e.g. " + + "Wi-Fi SSID) is provided in the command arguments. Directed scanning shall restrict the result set " + + "to the specified network only." + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "The client shall NOT expect the server to be done scanning and have responded with " + + "ScanNetworksResponse before ScanMaxTimeSeconds seconds have elapsed. Enough transport time " + + "affordances for retries SHOULD be expected before a client determines the operation to have " + + "timed-out." + + "\n" + + "This command shall fail with a status code of BUSY if the server determines that it will fail to " + + "reliably send a response due to changes of networking interface configuration at runtime for the " + + "interface over which the command was invoked, or if it is currently unable to proceed with such an " + + "operation." + + "\n" + + "For Wi-Fi-supporting servers (WI feature) the server shall always honor directed scans, and attempt " + + "to provide all matching BSSID which are reachable on the bands which would otherwise be attempted " + + "if a ConnectNetwork having the specified SSID were to take place. This command is useful for " + + "clients to determine reachability capabilities as seen by the server’s own radios." + + "\n" + + "For Wi-Fi-supporting servers the server shall always scan on all bands supported by the interface " + + "associated with the cluster instance on which the command was invoked." + + "\n" + + "If the command was invoked over the same link whose configuration is managed by a given server " + + "cluster instance, there may be an impact on other communication from the invoking client, as well " + + "as other clients, while the network interface is processing the scan. Clients SHOULD NOT use this " + + "command unless actively in the process of re-configuring network connectivity.", + + xref: { document: "core", section: "11.9.7.1" } + }, + + Field({ + name: "Ssid", id: 0x0, type: "octstr", conformance: "[WI]", constraint: "1 to 32", default: null, + quality: "X", + details: "This field, if present, shall contain the SSID for a directed scan of that particular Wi-Fi SSID. " + + "Otherwise, if the field is absent, or if it is null, this shall indicate scanning of all BSSID in " + + "range. This field shall be ignored for ScanNetworks invocations on non-Wi-Fi server instances.", + xref: { document: "core", section: "11.9.7.1.1" } + }), + + Field({ + name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", + details: "The Breadcrumb field, if present, shall be used to atomically set the Breadcrumb attribute in the " + + "General Commissioning cluster on success of the associated command. If the command fails, the " + + "Breadcrumb attribute in the General Commissioning cluster shall be left unchanged.", + xref: { document: "core", section: "11.9.7.1.2" } + }) + ), + + Command( + { + name: "ScanNetworksResponse", id: 0x1, conformance: "WI | TH", direction: "response", + + details: "This command shall contain the status of the last ScanNetworks command, and the associated scan " + + "results if the operation was successful." + + "\n" + + "Results are valid only if NetworkingStatus is Success." + + "\n" + + "Before generating a ScanNetworksResponse, the server shall set the LastNetworkingStatus attribute " + + "value to the NetworkingStatus matching the response.", + + xref: { document: "core", section: "11.9.7.2" } + }, + + Field({ + name: "NetworkingStatus", id: 0x0, type: "NetworkCommissioningStatusEnum", conformance: "M", + constraint: "desc", + + details: "The NetworkingStatus field shall indicate the status of the last scan operation, taking one of " + + "these values:" + + "\n" + + " • Success: Scanning succeeded." + + "\n" + + " • NetworkNotFound: No instance of an explicitly-provided network identifier was found during the " + + " scan. This error cannot occur if no network identifier was provided, such as when scanning for " + + " all available networks." + + "\n" + + " • OutOfRange: Network identifier was invalid (e.g. empty, too long, etc)." + + "\n" + + " • RegulatoryError: Could not scan on any bands due to lack of regulatory configuration." + + "\n" + + " • UnknownError: An internal error occurred during scanning.", + + xref: { document: "core", section: "11.9.7.2.1" } + }), + + Field({ + name: "DebugText", id: 0x1, type: "string", conformance: "O", constraint: "max 512", + details: "This field, if present and non-empty, may contain error information which may be communicated to " + + "the user in case the NetworkingStatus was not Success. Its purpose is to help developers in " + + "troubleshooting errors and may go into logs or crash reports.", + xref: { document: "core", section: "11.9.7.2.2" } + }), + + Field( + { + name: "WiFiScanResults", id: 0x2, type: "list", conformance: "WI", constraint: "desc", + + details: "If NetworkingStatus was Success, this field shall contain the Wi-Fi network scan results. The list " + + "may be empty if none were found in range on the bands supported by the interface, or if directed " + + "scanning had been used and the desired SSID was not found in range." + + "\n" + + "The maximum number of results present in the result list supported may depend on memory and may " + + "contain a subset of possibilities, to avoid memory exhaustion on the cluster server and avoid " + + "crossing the maximum command response size supported (see Section 4.4.4, “Message Size " + + "Requirements”)." + + "\n" + + "The order in which results are reported is implementation-specific. Results SHOULD be reported in " + + "decreasing RSSI order, even if RSSI is not reported in the response, to maximize the likelihood " + + "that most likely to be reachable elements are included within the size limits of the response.", + + xref: { document: "core", section: "11.9.7.2.3" } + }, + + Field({ name: "entry", type: "WiFiInterfaceScanResultStruct" }) + ), + + Field( + { + name: "ThreadScanResults", id: 0x3, type: "list", conformance: "TH", constraint: "desc", + + details: "If NetworkingStatus was Success, this field shall contain the Thread network scan results. The list " + + "may be empty if none were found in range on the bands supported by the interface." + + "\n" + + "The maximum number of results present in the result list supported may depend on memory and may " + + "contain a subset of possibilities, to avoid memory exhaustion on the cluster server and avoid " + + "crossing the maximum command response size supported (see Section 4.4.4, “Message Size " + + "Requirements”)." + + "\n" + + "The order in which results are reported is implementation-specific. Results SHOULD be reported in " + + "decreasing LQI order, to maximize the likelihood that most likely to be reachable elements are " + + "included within the size limits of the response.", + + xref: { document: "core", section: "11.9.7.2.4" } + }, + + Field({ name: "entry", type: "ThreadInterfaceScanResultStruct" }) + ) + ), + + Command( + { + name: "AddOrUpdateWiFiNetwork", id: 0x2, access: "A", conformance: "WI", direction: "request", + response: "NetworkConfigResponse", + + details: "This command shall be used to add or modify Wi-Fi network configurations." + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "The Credentials associated with the network are not readable after execution of this command, as " + + "they do not appear in the Networks attribute, for security reasons." + + "\n" + + "If this command contains a ClientIdentifier, and the Networks list does not contain an entry with a " + + "matching ClientIdentifier, then this command shall fail with a status of NOT_FOUND." + + "\n" + + "See Section 11.9.7.5, “Common processing of AddOrUpdateWiFiNetwork and AddOrUpdateThreadNetwork” " + + "for behavior of addition/update.", + + xref: { document: "core", section: "11.9.7.3" } + }, + + Field({ + name: "Ssid", id: 0x0, type: "octstr", conformance: "M", constraint: "max 32", + details: "This field shall contain the SSID to which to attempt connection. Specific BSSID selection is not " + + "supported by this cluster.", + xref: { document: "core", section: "11.9.7.3.1" } + }), + + Field({ + name: "Credentials", id: 0x1, type: "octstr", conformance: "M", constraint: "max 64", + + details: "Credentials is the passphrase or PSK for the network (if any is needed)." + + "\n" + + "Security type, cipher and credential format (passphrase or PSK) shall be contextually auto- " + + "selected during execution of the ConnectNetwork Command and during subsequent operational state " + + "network connections, based on the most secure Wi-Fi security type available within beacons and " + + "probe responses for the set of all discovered BSSIDs for the configured SSID. The type of PSK or " + + "passphrase used shall be inferred based on the length and contents of the Credentials field " + + "provided, matching the security type chosen." + + "\n" + + "Valid Credentials length are:" + + "\n" + + " • 0 bytes: Unsecured (open) connection" + + "\n" + + " • 5 bytes: WEP-64 passphrase" + + "\n" + + " • 10 hexadecimal ASCII characters: WEP-64 40-bit hex raw PSK" + + "\n" + + " • 13 bytes: WEP-128 passphrase" + + "\n" + + " • 26 hexadecimal ASCII characters: WEP-128 104-bit hex raw PSK" + + "\n" + + " • 8..63 bytes: WPA/WPA2/WPA3 passphrase" + + "\n" + + " • 64 bytes: WPA/WPA2/WPA3 raw hex PSK" + + "\n" + + "These lengths shall be contextually interpreted based on the security type of the BSSID where " + + "connection will occur." + + "\n" + + "When the length of Credentials and available set of BSSID admits more than one option, such as the " + + "presence of both WPA2 and WPA security type within the result set, WPA2 shall be considered more " + + "secure." + + "\n" + + "Note that it may occur that a station cannot connect to a particular access point with higher " + + "security and selects a lower security connectivity type if the link quality is deemed to be too low " + + "to achieve successful operation, or if all retry attempts fail.", + + xref: { document: "core", section: "11.9.7.3.2" } + }), + + Field({ + name: "Breadcrumb", id: 0x2, type: "uint64", conformance: "O", + details: "See Breadcrumb for usage.", + xref: { document: "core", section: "11.9.7.3.3" } + }) + ), + + Command( + { + name: "AddOrUpdateThreadNetwork", id: 0x3, access: "A", conformance: "TH", direction: "request", + response: "NetworkConfigResponse", + + details: "This command shall be used to add or modify Thread network configurations." + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "See Section 11.9.7.5, “Common processing of AddOrUpdateWiFiNetwork and AddOrUpdateThreadNetwork” " + + "for behavior of addition/update." + + "\n" + + "The XPAN ID in the OperationalDataset serves as the NetworkID for the network configuration to be " + + "added or updated." + + "\n" + + "If the Networks attribute does not contain an entry with the same NetworkID as the one provided in " + + "the OperationalDataset, the operation shall be considered an addition, otherwise, it shall be " + + "considered an update.", + + xref: { document: "core", section: "11.9.7.4" } + }, + + Field({ + name: "OperationalDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254", + details: "The OperationalDataset field shall contain the Thread Network Parameters, including channel, PAN " + + "ID, and Extended PAN ID." + + "\n" + + "The encoding for the OperationalDataset field is defined in the Thread specification. The client " + + "shall pass the OperationalDataset as an opaque octet string.", + xref: { document: "core", section: "11.9.7.4.1" } + }), + + Field({ + name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", + details: "See Breadcrumb for usage.", + xref: { document: "core", section: "11.9.7.4.2" } + }) + ), + + Command( + { + name: "RemoveNetwork", id: 0x4, access: "A", conformance: "WI | TH", direction: "request", + response: "NetworkConfigResponse", + + details: "This command shall remove the network configuration from the Cluster if there was already a network " + + "configuration with the same NetworkID. The relative order of the entries in the Networks" + + "\n" + + "attribute shall remain unchanged, except for the removal of the requested network configuration." + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "If the Networks attribute does not contain a matching entry, the command shall immediately respond " + + "with NetworkConfigResponse having NetworkingStatus status field set to NetworkIdNotFound." + + "\n" + + "On success, the NetworkConfigResponse command shall have its NetworkIndex field set to the 0- based " + + "index of the entry in the Networks attribute that was just removed, and a NetworkingStatus status " + + "field set to Success.", + + xref: { document: "core", section: "11.9.7.6" } + }, + + Field({ + name: "NetworkId", id: 0x0, type: "octstr", conformance: "M", constraint: "1 to 32", + details: "This field shall contain the NetworkID for the entry to remove: the SSID for Wi-Fi and XPAN ID for " + + "Thread.", + xref: { document: "core", section: "11.9.7.6.1" } + }), + + Field({ + name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", + details: "See Breadcrumb for usage.", + xref: { document: "core", section: "11.9.7.6.2" } + }) + ), + + Command( + { + name: "NetworkConfigResponse", id: 0x5, conformance: "WI | TH", direction: "response", + + details: "This response command relates status information for some commands which require it as their " + + "response command. See each individual cluster server command for the situations that may cause a " + + "NetworkingStatus different than Success." + + "\n" + + "Before generating a NetworkConfigResponse, the server shall set the LastNetworkingStatus attribute " + + "value to the NetworkingStatus matching the response." + + "\n" + + "Before generating a NetworkConfigResponse, the server shall set the LastNetworkID attribute value " + + "to the NetworkID that was used in the command for which an invocation caused the response to be " + + "generated.", + + xref: { document: "core", section: "11.9.7.7" } + }, + + Field({ + name: "NetworkingStatus", id: 0x0, type: "NetworkCommissioningStatusEnum", conformance: "M", + constraint: "desc", + + details: "The NetworkingStatus field shall indicate the status of the last operation attempting to modify the " + + "Networks attribute configuration, taking one of these values:" + + "\n" + + " • Success: Operation succeeded." + + "\n" + + " • OutOfRange: Network identifier was invalid (e.g. empty, too long, etc)." + + "\n" + + " • BoundsExceeded: Adding this network configuration would exceed the limit defined by MaxNetworks." + + "\n" + + " • NetworkIdNotFound: The network identifier was expected to be found, but was not found among the " + + " added network configurations in Networks attribute." + + "\n" + + " • UnknownError: An internal error occurred during the operation.", + + xref: { document: "core", section: "11.9.7.7.1" } + }), + + Field({ + name: "DebugText", id: 0x1, type: "string", conformance: "O", constraint: "max 512", + details: "See DebugText for usage.", + xref: { document: "core", section: "11.9.7.7.2" } + }), + + Field({ + name: "NetworkIndex", id: 0x2, type: "uint8", conformance: "O", constraint: "max maxNetworks - 1", + details: "When the NetworkingStatus is Success, this field shall be present. It shall contain the 0-based " + + "index of the entry in the Networks attribute that was last added, updated or removed successfully " + + "by the associated request command.", + xref: { document: "core", section: "11.9.7.7.3" } + }) + ), + + Command( + { + name: "ConnectNetwork", id: 0x6, access: "A", conformance: "WI | TH", direction: "request", + response: "ConnectNetworkResponse", + + details: "This command shall attempt to connect to a network whose configuration was previously added by " + + "either the AddOrUpdateWiFiNetwork or AddOrUpdateThreadNetwork commands. Network is identified by " + + "its NetworkID." + + "\n" + + "This command shall fail with a BUSY status code returned to the initiator if the server is " + + "currently unable to proceed with such an operation, such as if it is currently attempting to " + + "connect in the background, or is already proceeding with a prior ConnectNetwork." + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "Before connecting to the new network, the Node shall disconnect the operational network connections " + + "managed by any other Network Commissioning cluster instances (whether under the Root Node or a " + + "Secondary Network Interface), where those connections are not represented by an entry in the " + + "Networks attribute of the corresponding cluster instance. This ensures that an Administrator or " + + "Commissioner can reliably reconfigure the operational network connection of a device that has one " + + "or more Secondary Network interfaces, for example by removing the active network configuration from " + + "one cluster instance, followed by adding a new configuration and calling ConnectNetwork on a " + + "different cluster instance." + + "\n" + + "Success or failure of this command shall be communicated by the ConnectNetworkResponse command, " + + "unless some data model validations caused a FAILURE status to be sent prior to finishing execution " + + "of the command. The ConnectNetworkResponse shall indicate the value Success in the NetworkingStatus " + + "field on successful connection. On failure to connect, the ConnectNetworkResponse shall contain an " + + "appropriate NetworkingStatus, DebugText and ErrorValue indicating the reason for failure." + + "\n" + + "The amount of time needed to determine successful or failing connectivity on the cluster server’s " + + "associated interface is provided by the ConnectMaxTimeSeconds attribute. Clients shall NOT consider " + + "the connection to have timed-out until at least that duration has taken place. For non-concurrent " + + "commissioning situations, the client SHOULD allow additional margin of time to account for its " + + "delay in executing operational discovery of the Node once it is connected to the new network." + + "\n" + + "On successful connection, the entry associated with the given Network configuration in the Networks " + + "attribute shall indicate its Connected field set to true, and all other entries, if any exist, " + + "shall indicate their Connected field set to false." + + "\n" + + "On failure to connect, the entry associated with the given Network configuration in the Networks " + + "attribute shall indicate its Connected field set to false." + + "\n" + + "The precedence order of any entry subject to ConnectNetwork shall NOT change within the Networks " + + "attribute." + + "\n" + + "Even after successfully connecting to a network, the configuration shall revert to the prior state " + + "of configuration if the CommissioningComplete command (see CommissioningComplete) is not " + + "successfully invoked before expiry of the Fail-Safe timer." + + "\n" + + "When non-concurrent commissioning is being used by a Commissioner or Administrator, the Con" + + "\n" + + "nectNetworkResponse shall be sent with the NetworkingStatus field set to Success prior to closing " + + "the commissioning channel, even if not yet connected to the operational network, unless the device " + + "would be incapable of joining that network, in which case the usual failure path described in the " + + "prior paragraphs shall be followed. Once the commissioning channel is closed, the operational " + + "channel will be started. It is possible that the only method to determine success of the operation " + + "is operational discovery of the Node on the new operational network. Therefore, before invoking the " + + "ConnectNetwork command, the client SHOULD re-invoke the Arm Fail-Safe command with a duration that " + + "meets the following:" + + "\n" + + " 1. Sufficient time to meet the minimum required time (see ConnectMaxTimeSeconds) that may be " + + " taken by the server to connect to the desired network." + + "\n" + + " 2. Sufficient time to account for possible message-layer retries when a response is requested." + + "\n" + + " 3. Sufficient time to allow operational discovery on the new network by a Commissioner or " + + " Administrator." + + "\n" + + " 4. Sufficient time to establish a CASE session after operational discovery" + + "\n" + + " 5. Not so long that, in error situations, the delay to reverting back to being discoverable for " + + " commissioning with a previous configuration would cause significant user-perceived delay." + + "\n" + + "Note as well that the CommissioningTimeout duration provided in a prior OpenCommissioningWindow or " + + "OpenBasicCommissioningWindow command may impact the total time available to proceed with error " + + "recovery after a connection failure." + + "\n" + + "The LastNetworkingStatus, LastNetworkID and LastConnectErrorValue attributes may assist the client " + + "in determining the reason for a failure after reconnecting over a Commissioning channel, especially " + + "in non-concurrent commissioning situations.", + + xref: { document: "core", section: "11.9.7.8" } + }, + + Field({ + name: "NetworkId", id: 0x0, type: "octstr", conformance: "M", constraint: "1 to 32", + details: "This field shall contain the NetworkID for the entry used to configure the connection: the SSID for " + + "Wi-Fi and XPAN ID for Thread.", + xref: { document: "core", section: "11.9.7.8.1" } + }), + + Field({ + name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", + details: "See Breadcrumb for usage.", + xref: { document: "core", section: "11.9.7.8.2" } + }) + ), + + Command( + { + name: "ConnectNetworkResponse", id: 0x7, conformance: "WI | TH", direction: "response", + + details: "Before generating a ConnectNetworkResponse, the server shall:" + + "\n" + + " • Set the LastNetworkingStatus attribute value to the NetworkingStatus matching the response." + + "\n" + + " • Set the LastNetworkID attribute value to the NetworkID that was used in the ConnectNetwork " + + " command which caused the response to be generated." + + "\n" + + " • Set the LastConnectErrorValue attribute value to the ErrorValue matching the response, " + + " including setting it to null if the ErrorValue is not applicable.", + + xref: { document: "core", section: "11.9.7.9" } + }, + + Field({ + name: "NetworkingStatus", id: 0x0, type: "NetworkCommissioningStatusEnum", conformance: "M", + + details: "The NetworkingStatus field shall indicate the status of the last connection attempt, taking one of " + + "these values:" + + "\n" + + " • Success: Connection succeeded." + + "\n" + + " • NetworkNotFound: No instance of an explicitly-provided network identifier was found during the " + + " attempt to join the network." + + "\n" + + " • OutOfRange: Network identifier was invalid (e.g. empty, too long, etc)." + + "\n" + + " • NetworkIdNotFound: The network identifier was not found among the added network configurations " + + " in Networks attribute." + + "\n" + + " • RegulatoryError: Could not connect to a network due to lack of regulatory configuration." + + "\n" + + " • UnknownError: An internal error occurred during the operation." + + "\n" + + " • Association errors (see also description of errors in NetworkCommissioningStatusEnum): " + + " AuthFailure, UnsupportedSecurity, OtherConnectionFailure, IPV6Failed, IPBindFailed", + + xref: { document: "core", section: "11.9.7.9.1" } + }), + + Field({ + name: "DebugText", id: 0x1, type: "string", conformance: "O", + details: "See DebugText for usage.", + xref: { document: "core", section: "11.9.7.9.2" } + }), + + Field({ + name: "ErrorValue", id: 0x2, type: "int32", conformance: "M", quality: "X", + + details: " • ErrorValue interpretation for Wi-Fi association errors:" + + "\n" + + " ◦ On any association failure during enabling of a network, the ErrorValue field shall be set to " + + " the Status Code value that was present in the last frame related to association where Status " + + " Code was not equal to zero and which caused the failure of a final retry attempt, if this " + + " final failure was due to one of the following Management frames:" + + "\n" + + " ▪ Association Response (Type 0, Subtype 1)" + + "\n" + + " ▪ Reassociation Response (Type 0, Subtype 3)" + + "\n" + + " ▪ Authentication (Type 0, Subtype 11)" + + "\n" + + " ◦ Table 9-50 \"Status Codes\" in IEEE 802.11-2020 contains a description of all values possible, " + + " which can unambiguously be used to determine the cause, such as an invalid security type, " + + " unsupported rate, etc." + + "\n" + + " • Otherwise, the ErrorValue field shall contain an implementation-dependent value which may be " + + " used by a reader of the structure to record, report or diagnose the failure.", + + xref: { document: "core", section: "11.9.7.9.3" } + }) + ), + + Command( + { + name: "ReorderNetwork", id: 0x8, access: "A", conformance: "WI | TH", direction: "request", + response: "NetworkConfigResponse", + details: "This command shall set the specific order of the network configuration selected by its NetworkID in " + + "the Networks attribute to match the position given by NetworkIndex.", + xref: { document: "core", section: "11.9.7.10" } + }, + + Field({ + name: "NetworkId", id: 0x0, type: "octstr", conformance: "M", constraint: "1 to 32", + details: "This field shall contain the NetworkID for the entry to reorder: the SSID for Wi-Fi and XPAN ID for " + + "Thread.", + xref: { document: "core", section: "11.9.7.10.1" } + }), + + Field({ + name: "NetworkIndex", id: 0x1, type: "uint8", conformance: "M", constraint: "desc", + details: "This field shall contain the 0-based index of the new desired position of the entry in the Networks " + + "attribute.", + xref: { document: "core", section: "11.9.7.10.2" } + }), + + Field( + { + name: "Breadcrumb", id: 0x2, type: "uint64", conformance: "O", + + details: "See Breadcrumb for usage." + + "\n" + + "Effect when received" + + "\n" + + "If the Networks attribute does not contain a matching entry, the command shall immediately respond " + + "with NetworkConfigResponse having NetworkingStatus status field set to NetworkIdNotFound." + + "\n" + + "If the NetworkIndex field has a value larger or equal to the current number of entries in the " + + "Networks attribute, the command shall immediately respond with NetworkConfigResponse having " + + "NetworkingStatus status field set to OutOfRange." + + "\n" + + "On success, the NetworkConfigResponse command shall have its NetworkIndex field set to the 0- based " + + "index of the entry in the Networks attribute that was just updated, matching the incoming " + + "NetworkIndex, and a NetworkingStatus status field set to Success." + + "\n" + + "The entry selected shall be inserted at the new position in the list. All other entries, if any " + + "exist, shall be moved to allow the insertion, in a way that they all retain their existing relative " + + "order between each other, with the exception of the newly re-ordered entry." + + "\n" + + "Re-ordering to the same NetworkIndex as the current location shall be considered as a success and " + + "yield no visible changes of the Networks attribute." + + "\n" + + "Examples of re-ordering" + + "\n" + + "To better illustrate the re-ordering operation, consider this initial state, exemplary of a Wi-Fi " + + "device:" + + "\n" + + "On receiving ReorderNetwork with:" + + "\n" + + " • NetworkID = Home-Guest" + + "\n" + + " • NetworkIndex = 0" + + "\n" + + "The outcome, after applying to the initial state would be:" + + "\n" + + "In the above outcome, FancyCat and BlueDolphin moved \"down\" and Home-Guest became the highest " + + "priority network in the list." + + "\n" + + "On receiving ReorderNetwork with:" + + "\n" + + " • NetworkID = FancyCat" + + "\n" + + " • NetworkIndex = 3" + + "\n" + + "The outcome, after applying to the initial state would be:" + + "\n" + + "In the above outcome, BlueDolphin, Home-Guest and WillowTree moved \"up\" and FancyCat became the " + + "lowest priority network in the list.", + + xref: { document: "core", section: "11.9.7.10.3" } + } + ) + ), + + Datatype( + { + name: "WiFiSecurityBitmap", type: "map8", + details: "WiFiSecurityBitmap encodes the supported Wi-Fi security types present in the Security field of the " + + "WiFiInterfaceScanResultStruct.", + xref: { document: "core", section: "11.9.5.1" } + }, + + Field({ name: "Unencrypted", constraint: "0", description: "Supports unencrypted Wi-Fi" }), + Field({ name: "Wep", constraint: "1", description: "Supports Wi-Fi using WEP security" }), + Field({ name: "WpaPersonal", constraint: "2", description: "Supports Wi-Fi using WPA-Personal security" }), + Field({ name: "Wpa2Personal", constraint: "3", description: "Supports Wi-Fi using WPA2-Personal security" }), + Field({ name: "Wpa3Personal", constraint: "4", description: "Supports Wi-Fi using WPA3-Personal security" }) + ), + + Datatype( + { + name: "ThreadCapabilitiesBitmap", type: "map16", + + details: "The ThreadCapabilitiesBitmap encodes the supported Thread features and capabilities of a Thread- " + + "enabled network interface." + + "\n" + + "NOTE" + + "\n" + + "The valid combinations of capabilities are restricted and dependent on Thread version.", + + xref: { document: "core", section: "11.9.5.2" } + }, + + Field({ + name: "IsBorderRouterCapable", constraint: "0", + description: "Thread Border Router functionality is present" + }), + Field({ + name: "IsRouterCapable", constraint: "1", + description: "Router mode is supported (interface could be in router or REED mode)" + }), + Field({ name: "IsSleepyEndDeviceCapable", constraint: "2", description: "Sleepy end-device mode is supported" }), + Field({ + name: "IsFullThreadDevice", constraint: "3", + description: "Device is a full Thread device (opposite of Minimal Thread Device)" + }), + Field({ + name: "IsSynchronizedSleepyEndDeviceCapable", constraint: "4", + description: "Synchronized sleepy end-device mode is supported" + }) + ), + + Datatype( + { + name: "WiFiBandEnum", type: "enum8", + details: "WiFiBandEnum encodes a supported Wi-Fi frequency band present in the WiFiBand field of the " + + "WiFiInterfaceScanResultStruct.", + xref: { document: "core", section: "11.9.5.3" } + }, + + Field({ name: "2G4", id: 0x0, conformance: "O.b+", description: "2.4GHz - 2.401GHz to2.495GHz(802.11b/g/n/ax)" }), + Field({ name: "3G65", id: 0x1, conformance: "O.b+", description: "3.65GHz - 3.655GHz to3.695GHz (802.11y)" }), + Field({ name: "5G", id: 0x2, conformance: "O.b+", description: "5GHz - 5.150GHz to5.895GHz(802.11a/n/ac/ax)" }), + Field({ + name: "6G", id: 0x3, conformance: "O.b+", + description: "6GHz - 5.925GHz to7.125GHz (802.11ax / Wi-Fi 6E)" + }), + Field({ name: "60G", id: 0x4, conformance: "O.b+", description: "60GHz - 57.24GHz to70.20GHz (802.11ad/ay)" }), + Field({ name: "1G", id: 0x5, conformance: "O.b+", description: "Sub-1GHz - 755MHz to 931MHz (802.11ah)" }) + ), + + Datatype( + { name: "NetworkCommissioningStatusEnum", type: "enum8", xref: { document: "core", section: "11.9.5.4" } }, + Field({ name: "Success", id: 0x0, conformance: "M", description: "OK, no error" }), + Field({ name: "OutOfRange", id: 0x1, conformance: "M", description: "Value Outside Range" }), + Field({ + name: "BoundsExceeded", id: 0x2, conformance: "M", + description: "A collection would exceed its size limit" + }), + Field({ + name: "NetworkIdNotFound", id: 0x3, conformance: "M", + description: "The NetworkID is not among the collection of added networks" + }), + Field({ + name: "DuplicateNetworkId", id: 0x4, conformance: "M", + description: "The NetworkID is already among the collection of added networks" + }), + Field({ name: "NetworkNotFound", id: 0x5, conformance: "M", description: "Cannot find AP: SSID Not found" }), + Field({ + name: "RegulatoryError", id: 0x6, conformance: "M", + description: "Cannot find AP: Mismatch on band/channels/regulatory domain/ 2.4GHz vs 5GHz" + }), + Field({ + name: "AuthFailure", id: 0x7, conformance: "M", + description: "Cannot associate due to authentication failure" + }), + Field({ + name: "UnsupportedSecurity", id: 0x8, conformance: "M", + description: "Cannot associate due to unsupported security mode" + }), + Field({ name: "OtherConnectionFailure", id: 0x9, conformance: "M", description: "Other association failure" }), + Field({ name: "Ipv6Failed", id: 0xa, conformance: "M", description: "Failure to generate an IPv6 address" }), + Field({ name: "IpBindFailed", id: 0xb, conformance: "M", description: "Failure to bind Wi-Fi <-> IP interfaces" }), + Field({ name: "UnknownError", id: 0xc, conformance: "M", description: "Unknown error" }) + ), + + Datatype( + { + name: "NetworkInfoStruct", type: "struct", + details: "NetworkInfoStruct struct describes an existing network configuration, as provided in the Networks " + + "attribute.", + xref: { document: "core", section: "11.9.5.5" } + }, + + Field({ + name: "NetworkId", id: 0x0, type: "octstr", conformance: "M", constraint: "1 to 32", + + details: "Every network is uniquely identified (for purposes of commissioning) by a NetworkID mapping to the " + + "following technology-specific properties:" + + "\n" + + " • SSID for Wi-Fi" + + "\n" + + " • Extended PAN ID for Thread" + + "\n" + + " • Network interface instance name at operating system (or equivalent unique name) for Ethernet." + + "\n" + + "The semantics of the NetworkID field therefore varies between network types accordingly. It " + + "contains SSID for Wi-Fi networks, Extended PAN ID (XPAN ID) for Thread networks and netif name for " + + "Ethernet networks." + + "\n" + + "NOTE" + + "\n" + + "SSID in Wi-Fi is a collection of 1-32 bytes, the text encoding of which is not specified. " + + "Implementations must be careful to support reporting byte strings without requiring a particular " + + "encoding for transfer. Only the commissioner should try to potentially decode the bytes. The most " + + "common encoding is UTF-8, however this is just a convention. Some configurations may use Latin-1 or " + + "other character sets. A commissioner may decode using UTF-8, replacing encoding errors with \"?\" at " + + "the application level while retaining the underlying representation." + + "\n" + + "XPAN ID is a big-endian 64-bit unsigned number, represented on the first 8 octets of the octet " + + "string.", + + xref: { document: "core", section: "11.9.5.5.1" } + }), + + Field({ + name: "Connected", id: 0x1, type: "bool", conformance: "M", + details: "This field shall indicate the connected status of the associated network, where \"connected\" means " + + "currently linked to the network technology (e.g. Associated for a Wi-Fi network, media connected " + + "for an Ethernet network).", + xref: { document: "core", section: "11.9.5.5.2" } + }) + ), + + Datatype( + { + name: "WiFiInterfaceScanResultStruct", type: "struct", + details: "WiFiInterfaceScanResultStruct represents a single Wi-Fi network scan result.", + xref: { document: "core", section: "11.9.5.6" } + }, + Field({ name: "Security", id: 0x0, type: "WiFiSecurityBitmap", conformance: "WI" }), + Field({ name: "Ssid", id: 0x1, type: "octstr", conformance: "WI", constraint: "max 32" }), + Field({ name: "Bssid", id: 0x2, type: "octstr", conformance: "WI", constraint: "6" }), + Field({ name: "Channel", id: 0x3, type: "uint16", conformance: "WI" }), + + Field({ + name: "WiFiBand", id: 0x4, type: "WiFiBandEnum", conformance: "[WI]", + details: "This field, if present, may be used to differentiate overlapping channel number values across " + + "different Wi-Fi frequency bands.", + xref: { document: "core", section: "11.9.5.6.1" } + }), + + Field({ + name: "Rssi", id: 0x5, type: "int8", conformance: "[WI]", + details: "This field, if present, shall denote the signal strength in dBm of the associated scan result.", + xref: { document: "core", section: "11.9.5.6.2" } + }) + ), + + Datatype( + { + name: "ThreadInterfaceScanResultStruct", type: "struct", + details: "ThreadInterfaceScanResultStruct represents a single Thread network scan result.", + xref: { document: "core", section: "11.9.5.7" } + }, + Field({ name: "PanId", id: 0x0, type: "uint16", conformance: "TH", constraint: "max 65534" }), + Field({ name: "ExtendedPanId", id: 0x1, type: "uint64", conformance: "TH" }), + Field({ name: "NetworkName", id: 0x2, type: "string", conformance: "TH", constraint: "1 to 16" }), + Field({ name: "Channel", id: 0x3, type: "uint16", conformance: "TH" }), + Field({ name: "Version", id: 0x4, type: "uint8", conformance: "TH" }), + Field({ + name: "ExtendedAddress", id: 0x5, type: "hwadr", conformance: "TH", + details: "ExtendedAddress stands for an IEEE 802.15.4 Extended Address.", + xref: { document: "core", section: "11.9.5.7.1" } + }), + Field({ name: "Rssi", id: 0x6, type: "int8", conformance: "TH" }), + Field({ name: "Lqi", id: 0x7, type: "uint8", conformance: "TH" }) + ) + ), + + Cluster( + { + name: "GeneralCommissioning", id: 0x30, classification: "node", pics: "CGEN", + details: "This cluster is used to manage basic commissioning lifecycle." + + "\n" + + "This cluster also represents responsibilities related to commissioning that don’t well fit other " + + "commissioning clusters, like Section 11.9, “Network Commissioning Cluster”. It also hosts " + + "functionalities those other clusters may depend on.", + xref: { document: "core", section: "11.10" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.10.4" } }, + Field({ + name: "TC", conformance: "P", constraint: "0", description: "TermsAndConditions", + details: "Supports Terms & Conditions acknowledgement" + }) + ), + + Attribute({ + name: "Breadcrumb", id: 0x0, type: "uint64", access: "RW VA", conformance: "M", default: 0, + + details: "This attribute allows for the storage of a client-provided small payload which Administrators and " + + "Commissioners may write and then subsequently read, to keep track of their own progress. This may " + + "be used by the Commissioner to avoid repeating already-executed actions upon re-establishing a " + + "commissioning link after an error." + + "\n" + + "On start/restart of the server, such as when a device is power-cycled, this attribute shall be " + + "reset to zero." + + "\n" + + "Some commands related to commissioning also have a side-effect of updating or resetting this " + + "attribute and this is specified in their respective functional descriptions." + + "\n" + + "The format of the value within this attribute is unspecified and its value is not otherwise used by " + + "the functioning of any cluster, other than being set as a side-effect of commands where this " + + "behavior is described.", + + xref: { document: "core", section: "11.10.6.1" } + }), + + Attribute({ + name: "BasicCommissioningInfo", id: 0x1, type: "BasicCommissioningInfo", access: "R V", + conformance: "M", constraint: "desc", quality: "F", + details: "This attribute shall describe critical parameters needed at the beginning of commissioning flow. " + + "See BasicCommissioningInfo for more information.", + xref: { document: "core", section: "11.10.6.2" } + }), + + Attribute({ + name: "RegulatoryConfig", id: 0x2, type: "RegulatoryLocationTypeEnum", access: "R V", + conformance: "M", default: { type: "reference", name: "LocationCapability" }, + details: "Indicates the regulatory configuration for the product." + + "\n" + + "Note that the country code is part of Basic Information Cluster and therefore NOT listed on the " + + "RegulatoryConfig attribute.", + xref: { document: "core", section: "11.10.6.3" } + }), + + Attribute({ + name: "LocationCapability", id: 0x3, type: "RegulatoryLocationTypeEnum", access: "R V", + conformance: "M", default: 2, quality: "F", + + details: "LocationCapability is statically set by the manufacturer and indicates if this Node needs to be " + + "told an exact RegulatoryLocation. For example a Node which is \"Indoor Only\" would not be certified " + + "for outdoor use at all, and thus there is no need for a commissioner to set or ask the user about " + + "whether the device will be used inside or outside. However a device which states its capability is" + + "\n" + + "\"Indoor/Outdoor\" means it would like clarification if possible." + + "\n" + + "For Nodes without radio network interfaces (e.g. Ethernet-only devices), the value IndoorOutdoor " + + "shall always be used." + + "\n" + + "The default value of the RegulatoryConfig attribute is the value of LocationCapability attribute. " + + "This means devices always have a safe default value, and Commissioners which choose to implement " + + "smarter handling can.", + + xref: { document: "core", section: "11.10.6.4" } + }), + + Attribute({ + name: "SupportsConcurrentConnection", id: 0x4, type: "bool", access: "R V", conformance: "M", + default: true, quality: "F", + details: "Indicates whether this device supports \"concurrent connection flow\" commissioning mode (see Section " + + "5.5, “Commissioning Flows”). If false, the device only supports \"non-concurrent connection flow\" " + + "mode.", + xref: { document: "core", section: "11.10.6.5" } + }), + + Attribute({ + name: "TcAcceptedVersion", id: 0x5, type: "uint16", access: "R A", conformance: "P, TC", + quality: "N", + + details: "Indicates the last version of the T&Cs for which the device received user acknowledgements. On " + + "factory reset this field shall be reset to 0." + + "\n" + + "When Custom Commissioning Flow is used to obtain user consent (e. g. because the Commissioner does " + + "not support the TC feature), the manufacturer-provided means for obtaining user consent shall " + + "ensure that this attribute is set to a value which is greater than or equal to TCMinRequiredVersion " + + "before returning the user back to the originating Commissioner (see Enhanced Setup Flow).", + + xref: { document: "core", section: "11.10.6.6" } + }), + + Attribute({ + name: "TcMinRequiredVersion", id: 0x6, type: "uint16", access: "R A", conformance: "P, TC", + quality: "N", + + details: "Indicates the minimum version of the texts presented by the Enhanced Setup Flow that need to be " + + "accepted by the user for this device. This attribute may change as the result of an OTA update." + + "\n" + + "If an event such as a software update causes TCAcceptedVersion to become less than " + + "TCMinRequiredVersion, then the device shall update TCAcknowledgementsRequired to True so that an " + + "administrator can detect that a newer version of the texts needs to be presented to the user.", + + xref: { document: "core", section: "11.10.6.7" } + }), + + Attribute({ + name: "TcAcknowledgements", id: 0x7, type: "map16", access: "R A", conformance: "P, TC", + quality: "N", + + details: "Indicates the user’s response to the presented terms. Each bit position corresponds to a user " + + "response for the associated index of matching text, such that bit 0 (bit value 1) is for text index " + + "0. Bit 15 (bit value 0x8000) is for text index 15. A bit value of 1 indicates acceptance and a " + + "value of 0 indicates non-acceptance. For example, if there are two texts that were presented where " + + "the first (bit 0, value 1) was declined and the second accepted (bit 1, value 2), we would expect " + + "the resulting value of the map to be 2." + + "\n" + + "Whenever a user provides responses to newly presented terms and conditions, this attribute shall be " + + "updated with the latest responses. This may happen in response to updated terms that were presented " + + "to the user. On a factory reset this field shall be reset with all bits set to 0.", + + xref: { document: "core", section: "11.10.6.8" } + }), + + Attribute({ + name: "TcAcknowledgementsRequired", id: 0x8, type: "bool", access: "R A", conformance: "P, TC", + default: true, quality: "N", + + details: "Indicates whether SetTCAcknowledgements is currently required to be called with the inclusion of " + + "mandatory terms accepted." + + "\n" + + "This attribute may be present and False in the case where no terms and conditions are currently " + + "mandatory to accept for CommissioningComplete to succeed." + + "\n" + + "This attribute may appear, or become True after commissioning (e.g. due to a firmware update) to " + + "indicate that new Terms & Conditions are available that the user must accept." + + "\n" + + "Upon Factory Data Reset, this attribute shall be set to a value of True." + + "\n" + + "When Custom Commissioning Flow is used to obtain user consent (e.g. because the Commissioner does " + + "not support the TC feature), the manufacturer-provided means for obtaining user consent shall " + + "ensure that this attribute is set to False before returning the user back to the original " + + "Commissioner (see Enhanced Setup Flow).", + + xref: { document: "core", section: "11.10.6.9" } + }), + + Attribute({ + name: "TcUpdateDeadline", id: 0x9, type: "uint32", access: "R A", conformance: "P, TC", + quality: "X N", + details: "Indicates the System Time in seconds when any functionality limitations will begin due to a lack of " + + "acceptance of updated Terms and Conditions, as described in Section 5.7.4.5, “Presenting Updated " + + "Terms and Conditions”." + + "\n" + + "A null value indicates that there is no pending deadline for updated TC acceptance.", + xref: { document: "core", section: "11.10.6.10" } + }), + + Command( + { + name: "ArmFailSafe", id: 0x0, access: "A", conformance: "M", direction: "request", + response: "ArmFailSafeResponse", + + details: "Success or failure of this command shall be communicated by the ArmFailSafeResponse command, unless " + + "some data model validations caused a failure status code to be issued during the processing of the " + + "command." + + "\n" + + "If the fail-safe timer is not currently armed, the commissioning window is open, and the command " + + "was received over a CASE session, the command shall leave the current fail-safe state unchanged and " + + "immediately respond with an ArmFailSafeResponse containing an ErrorCode value of " + + "BusyWithOtherAdmin. This is done to allow commissioners, which use PASE connections, the " + + "opportunity to use the failsafe during the relatively short commissioning window." + + "\n" + + "Otherwise, the command shall arm or re-arm the \"fail-safe timer\" with an expiry time set for a " + + "duration of ExpiryLengthSeconds, or disarm it, depending on the situation:" + + "\n" + + " • If ExpiryLengthSeconds is 0 and the fail-safe timer was already armed and the accessing fabric " + + " matches the Fabric currently associated with the fail-safe context, then the fail-safe timer " + + " shall be immediately expired (see further below for side-effects of expiration)." + + "\n" + + " • If ExpiryLengthSeconds is 0 and the fail-safe timer was not armed, then this command invocation " + + " shall lead to a success response with no side-effects against the fail-safe context." + + "\n" + + " • If ExpiryLengthSeconds is non-zero and the fail-safe timer was not currently armed, then the " + + " fail-safe timer shall be armed for that duration." + + "\n" + + " • If ExpiryLengthSeconds is non-zero and the fail-safe timer was currently armed, and the " + + " accessing Fabric matches the fail-safe context’s associated Fabric, then the fail-safe timer " + + " shall be re- armed to expire in ExpiryLengthSeconds." + + "\n" + + " • Otherwise, the command shall leave the current fail-safe state unchanged and immediately " + + " respond with ArmFailSafeResponse containing an ErrorCode value of BusyWithOtherAdmin, " + + " indicating a likely conflict between commissioners." + + "\n" + + "The value of the Breadcrumb field shall be written to the Breadcrumb on successful execution of the " + + "command." + + "\n" + + "If the receiver restarts unexpectedly (e.g., power interruption, software crash, or other reset) " + + "the receiver shall behave as if the fail-safe timer expired and perform the sequence of clean-up " + + "steps listed below." + + "\n" + + "On successful execution of the command, the ErrorCode field of the ArmFailSafeResponse shall be set " + + "to OK." + + "\n" + + "### Fail Safe Context" + + "\n" + + "When first arming the fail-safe timer, a 'Fail Safe Context' shall be created on the receiver, to " + + "track the following state information while the fail-safe is armed:" + + "\n" + + " • The fail-safe timer duration." + + "\n" + + " • The state of all Network Commissioning Networks attribute configurations, to allow recovery of " + + " connectivity after Fail-Safe expiry." + + "\n" + + " • Whether an AddNOC command or UpdateNOC command has taken place." + + "\n" + + " • A Fabric Index for the fabric-scoping of the context, starting at the accessing fabric index " + + " for the ArmFailSafe command, and updated with the Fabric Index associated with an AddNOC " + + " command or an UpdateNOC command being invoked successfully during the ongoing Fail-Safe timer " + + " period." + + "\n" + + " • The operational credentials associated with any Fabric whose configuration is affected by the " + + " UpdateNOC command." + + "\n" + + " • Optionally: the previous state of non-fabric-scoped data that is mutated during the fail-safe " + + " period." + + "\n" + + "Note the following to assist in understanding the above state-keeping, which summarizes other " + + "normative requirements in the respective sections:" + + "\n" + + " • The AddNOC command can only be invoked once per contiguous non-expiring fail-safe timer period, " + + " and only if no UpdateNOC command was previously processed within the same fail-safe timer " + + " period." + + "\n" + + " • The UpdateNOC command can only be invoked once per contiguous non-expiring fail-safe timer " + + " period, can only be invoked over a CASE session, and only if no AddNOC command was previously " + + " processed in the same fail-safe timer period." + + "\n" + + "On creation of the Fail Safe Context a second timer shall be created to expire at " + + "MaxCumulativeFailsafeSeconds as specified in BasicCommissioningInfo. This Cumulative Fail Safe " + + "Context timer (CFSC timer) serves to limit the lifetime of any particular Fail Safe Context; it " + + "shall NOT be extended or modified on subsequent invocations of ArmFailSafe associated with this " + + "Fail Safe Context. Upon expiry of the CFSC timer, the receiver shall execute cleanup behavior " + + "equivalent to that of fail-safe timer expiration as detailed in Section 11.10.7.2.2, “Behavior on " + + "expiry of Fail-Safe timer”. Termination of the session prior to the expiration of that timer for " + + "any reason (including a successful end of commissioning or an expiry of a fail-safe timer) shall " + + "also delete the CFSC timer." + + "\n" + + "### Behavior on expiry of Fail-Safe timer" + + "\n" + + "If the fail-safe timer expires before the CommissioningComplete command is successfully invoked, " + + "the following sequence of clean-up steps shall be executed, in order, by the receiver:" + + "\n" + + " 1. Terminate any open PASE secure session by clearing any associated Secure Session Context at " + + " the Server." + + "\n" + + " 2. Revoke the temporary administrative privileges granted to any open PASE session (see Section " + + " 6.6.2.9, “Bootstrapping of the Access Control Cluster”) at the Server." + + "\n" + + " 3. If an AddNOC or UpdateNOC command has been successfully invoked, terminate all CASE sessions " + + " associated with the Fabric whose Fabric Index is recorded in the Fail-Safe context (see " + + " ArmFailSafe) by clearing any associated Secure Session Context at the Server." + + "\n" + + " 4. Reset the configuration of all Network Commissioning Networks attribute to their state prior " + + " to the Fail-Safe being armed." + + "\n" + + " 5. If an UpdateNOC command had been successfully invoked, revert the state of operational key " + + " pair, NOC and ICAC for that Fabric to the state prior to the Fail-Safe timer being armed, for " + + " the Fabric Index that was the subject of the UpdateNOC command." + + "\n" + + " 6. If an AddNOC command had been successfully invoked, achieve the equivalent effect of invoking " + + " the RemoveFabric command against the Fabric Index stored in the Fail-Safe Context for the " + + " Fabric Index that was the subject of the AddNOC command. This shall remove all associations " + + " to that Fabric including all fabric-scoped data, and may possibly factory-reset the device " + + " depending on current device state. This shall only apply to Fabrics added during the " + + " fail-safe period as the result of the AddNOC command." + + "\n" + + " 7. If the CSRRequest command had been successfully invoked, but no AddNOC or UpdateNOC command " + + " had been successfully invoked, then the new operational key pair temporarily generated for " + + " the purposes of NOC addition or update (see Node Operational CSR Procedure) shall be removed " + + " as it is no longer needed." + + "\n" + + " 8. Remove any RCACs added by the AddTrustedRootCertificate command that are not currently " + + " referenced by any entry in the Fabrics attribute." + + "\n" + + " 9. Reset the Breadcrumb attribute to zero." + + "\n" + + " 10. Optionally: if no factory-reset resulted from the previous steps, it is recommended that the " + + " Node rollback the state of all non fabric-scoped data present in the Fail-Safe context.", + + xref: { document: "core", section: "11.10.7.2" } + }, + + Field({ name: "ExpiryLengthSeconds", id: 0x0, type: "uint16", conformance: "M", default: 900 }), + Field({ name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "M" }) + ), + + Command( + { + name: "ArmFailSafeResponse", id: 0x1, conformance: "M", direction: "response", + xref: { document: "core", section: "11.10.7.3" } + }, + + Field({ + name: "ErrorCode", id: 0x0, type: "CommissioningErrorEnum", conformance: "M", default: 0, + details: "This field shall contain the result of the operation, based on the behavior specified in the " + + "functional description of the ArmFailSafe command.", + xref: { document: "core", section: "11.10.7.3.1" } + }), + + Field({ + name: "DebugText", id: 0x1, type: "string", conformance: "M", constraint: "max 128", default: "", + details: "See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”.", + xref: { document: "core", section: "11.10.7.3.2" } + }) + ), + + Command( + { + name: "SetRegulatoryConfig", id: 0x2, access: "A", conformance: "M", direction: "request", + response: "SetRegulatoryConfigResponse", + + details: "This shall add or update the regulatory configuration in the RegulatoryConfig Attribute to the " + + "value provided in the NewRegulatoryConfig field." + + "\n" + + "Success or failure of this command shall be communicated by the SetRegulatoryConfigResponse " + + "command, unless some data model validations caused a failure status code to be issued during the " + + "processing of the command." + + "\n" + + "The CountryCode field shall conforms to ISO 3166-1 alpha-2 and shall be used to set the Location " + + "attribute reflected by the Basic Information Cluster." + + "\n" + + "If the server limits some of the values (e.g. locked to a particular country, with no regulatory " + + "data for others), then setting regulatory information outside a valid country or location shall " + + "still set the Location attribute reflected by the Basic Information Cluster configuration, but the " + + "SetRegulatoryConfigResponse replied shall have the ErrorCode field set to ValueOutsideRange error." + + "\n" + + "If the LocationCapability attribute is not Indoor/Outdoor and the NewRegulatoryConfig value" + + "\n" + + "received does not match either the Indoor or Outdoor fixed value in LocationCapability, then the " + + "SetRegulatoryConfigResponse replied shall have the ErrorCode field set to ValueOutsideRange error " + + "and the RegulatoryConfig attribute and associated internal radio configuration shall remain " + + "unchanged." + + "\n" + + "If the LocationCapability attribute is set to Indoor/Outdoor, then the RegulatoryConfig attribute " + + "shall be set to match the NewRegulatoryConfig field." + + "\n" + + "On successful execution of the command, the ErrorCode field of the SetRegulatoryConfigResponse " + + "shall be set to OK." + + "\n" + + "The Breadcrumb field shall be used to atomically set the Breadcrumb attribute on success of this " + + "command, when SetRegulatoryConfigResponse has the ErrorCode field set to OK. If the command fails, " + + "the Breadcrumb attribute shall be left unchanged.", + + xref: { document: "core", section: "11.10.7.4" } + }, + + Field({ name: "NewRegulatoryConfig", id: 0x0, type: "RegulatoryLocationTypeEnum", conformance: "M" }), + Field({ name: "CountryCode", id: 0x1, type: "string", conformance: "M", constraint: "2" }), + Field({ name: "Breadcrumb", id: 0x2, type: "uint64", conformance: "M" }) + ), + + Command( + { + name: "SetRegulatoryConfigResponse", id: 0x3, conformance: "M", direction: "response", + xref: { document: "core", section: "11.10.7.5" } + }, + + Field({ + name: "ErrorCode", id: 0x0, type: "CommissioningErrorEnum", conformance: "M", default: 0, + details: "This field shall contain the result of the operation, based on the behavior specified in the " + + "functional description of the SetRegulatoryConfig command.", + xref: { document: "core", section: "11.10.7.5.1" } + }), + + Field({ + name: "DebugText", id: 0x1, type: "string", conformance: "M", default: "", + details: "See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”.", + xref: { document: "core", section: "11.10.7.5.2" } + }) + ), + + Command({ + name: "CommissioningComplete", id: 0x4, access: "F A", conformance: "M", direction: "request", + response: "CommissioningCompleteResponse", + + details: "This command has no data." + + "\n" + + "Success or failure of this command shall be communicated by the CommissioningCompleteResponse " + + "command, unless some data model validations caused a failure status code to be issued during the " + + "processing of the command." + + "\n" + + "This command signals the Server that the Commissioner or Administrator has successfully completed " + + "all steps needed during the Fail-Safe period, such as commissioning (see Section 5.5, " + + "“Commissioning Flows”) or other Administrator operations requiring usage of the Fail Safe timer. It " + + "ensures that the Server is configured in a state such that it still has all necessary elements to " + + "be fully operable within a Fabric, such as ACL entries (see Section 9.10, “Access Control Cluster”) " + + "and operational credentials (see Section 6.4, “Node Operational Credentials Specification”), and " + + "that the Node is reachable using CASE" + + "\n" + + "(CASE)”) over an operational network." + + "\n" + + "An ErrorCode of NoFailSafe shall be responded to the invoker if the CommissioningComplete command " + + "was received when no Fail-Safe context exists." + + "\n" + + "If Terms and Conditions are required, then an ErrorCode of TCAcknowledgementsNotReceived shall be " + + "responded to the invoker if the user acknowledgements to the required Terms and Conditions have not " + + "been provided. If the TCAcceptedVersion for the provided acknowledgements is less than " + + "TCMinRequiredVersion, then an ErrorCode of TCMinVersionNotMet shall be responded to the invoker." + + "\n" + + "This command is fabric-scoped, so cannot be issued over a session that does not have an associated " + + "fabric, i.e. over PASE session prior to an AddNOC command. In addition, this command is only " + + "permitted over CASE and must be issued by a node associated with the ongoing Fail-Safe context. An " + + "ErrorCode of InvalidAuthentication shall be responded to the invoker if the CommissioningComplete " + + "command was received outside a CASE session (e.g., over Group messaging, or PASE session after " + + "AddNOC), or if the accessing fabric is not the one associated with the ongoing Fail-Safe context." + + "\n" + + "This command shall only result in success with an ErrorCode value of OK in the " + + "CommissioningCompleteResponse if received over a CASE session and the accessing fabric index " + + "matches the Fabric Index associated with the current Fail-Safe context. In other words:" + + "\n" + + " • If no AddNOC command had been successfully invoked, the CommissioningComplete command must " + + " originate from the Fabric that initiated the Fail-Safe context." + + "\n" + + " • After an AddNOC command has been successfully invoked, the CommissioningComplete command must " + + " originate from the Fabric which was joined through the execution of that command, which updated " + + " the Fail-Safe context’s Fabric Index." + + "\n" + + "On successful execution of the CommissioningComplete command, where the " + + "CommissioningCompleteResponse has an ErrorCode of OK, the following actions shall be undertaken on " + + "the Server:" + + "\n" + + " 1. The Fail-Safe timer associated with the current Fail-Safe context shall be disarmed." + + "\n" + + " 2. The commissioning window at the Server shall be closed." + + "\n" + + " 3. Any temporary administrative privileges automatically granted to any open PASE session shall " + + " be revoked (see Section 6.6.2.9, “Bootstrapping of the Access Control Cluster”)." + + "\n" + + " 4. The Secure Session Context of any PASE session still established at the Server shall be " + + " cleared." + + "\n" + + " 5. The Breadcrumb attribute shall be reset to zero." + + "\n" + + "After receipt of a CommissioningCompleteResponse with an ErrorCode value of OK, a client cannot " + + "expect any previously established PASE session to still be usable, due to the server having cleared " + + "such sessions.", + + xref: { document: "core", section: "11.10.7.6" } + }), + + Command( + { + name: "CommissioningCompleteResponse", id: 0x5, conformance: "M", direction: "response", + xref: { document: "core", section: "11.10.7.7" } + }, + + Field({ + name: "ErrorCode", id: 0x0, type: "CommissioningErrorEnum", conformance: "M", default: 0, + details: "This field shall contain the result of the operation, based on the behavior specified in the " + + "functional description of the CommissioningComplete command.", + xref: { document: "core", section: "11.10.7.7.1" } + }), + + Field({ + name: "DebugText", id: 0x1, type: "string", conformance: "M", default: "", + details: "See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”.", + xref: { document: "core", section: "11.10.7.7.2" } + }) + ), + + Command( + { + name: "SetTcAcknowledgements", id: 0x6, access: "A", conformance: "P, TC", direction: "request", + response: "SetTcAcknowledgementsResponse", + details: "This command sets the user acknowledgements received in the Enhanced Setup Flow Terms & Conditions " + + "into the node.", + xref: { document: "core", section: "11.10.7.8" } + }, + + Field({ + name: "TcVersion", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall contain the version of the Enhanced Setup Flow Terms & Conditions that were " + + "presented to the user.", + xref: { document: "core", section: "11.10.7.8.1" } + }), + + Field({ + name: "TcUserResponse", id: 0x1, type: "map16", conformance: "M", + + details: "This field shall contain the user responses to the Enhanced Setup Flow Terms & Conditions as a map " + + "where each bit set in the bitmap corresponds to an accepted term in the file located at " + + "EnhancedSetupFlowTCUrl." + + "\n" + + "### Effect on Receipt" + + "\n" + + "This command shall copy the user responses and accepted version to the presented Enhanced Setup " + + "Flow Terms & Conditions from the values provided in the TCUserResponse and TCVersion fields to the " + + "TCAcknowledgements Attribute and the TCAcceptedVersion Attribute fields respectively." + + "\n" + + "This command shall result in success with an ErrorCode value of OK in the " + + "SetTCAcknowledgementsResponse if all required terms were accepted by the user. Specifically, all " + + "bits have a value of 1 in TCAcknowledgements whose ordinal is marked as required in the file " + + "located at EnhancedSe" + + "\n" + + "tupFlowTCUrl." + + "\n" + + "If the TCVersion field is less than the TCMinRequiredVersion, then the ErrorCode of " + + "TCMinVersionNotMet shall be returned and TCAcknowledgements shall remain unchanged." + + "\n" + + "If TCVersion is greater than or equal to TCMinRequiredVersion, but the TCUserResponse value " + + "indicates that not all required terms were accepted by the user, then the ErrorCode of " + + "RequiredTCNotAccepted shall be returned and TCAcknowledgements shall remain unchanged.", + + xref: { document: "core", section: "11.10.7.8.2" } + }) + ), + + Command( + { + name: "SetTcAcknowledgementsResponse", id: 0x7, conformance: "P, TC", direction: "response", + details: "This command is used to convey the result from SetTCAcknowledgements.", + xref: { document: "core", section: "11.10.7.9" } + }, + + Field({ + name: "ErrorCode", id: 0x0, type: "CommissioningErrorEnum", conformance: "M", default: 0, + details: "This field shall contain the result of the operation, based on the behavior specified in the " + + "functional description of the SetTCAcknowledgements command.", + xref: { document: "core", section: "11.10.7.9.1" } + }) + ), + + Datatype( + { + name: "CommissioningErrorEnum", type: "enum8", + details: "This enumeration is used by several response commands in this cluster to indicate particular errors.", + xref: { document: "core", section: "11.10.5.1" } + }, + Field({ name: "Ok", id: 0x0, conformance: "M", description: "No error" }), + Field({ + name: "ValueOutsideRange", id: 0x1, conformance: "M", + description: "Attempting to set regulatory configuration to a region or indoor/outdoor mode for which the server does not have proper configuration." + }), + Field({ + name: "InvalidAuthentication", id: 0x2, conformance: "M", + description: "Executed CommissioningComplete outside CASE session." + }), + Field({ + name: "NoFailSafe", id: 0x3, conformance: "M", + description: "Executed CommissioningComplete when there was no active Fail-Safe context." + }), + Field({ + name: "BusyWithOtherAdmin", id: 0x4, conformance: "M", + description: "Attempting to arm fail- safe or execute CommissioningComplete from a fabric different than the one associated with the current fail- safe context." + }), + Field({ + name: "RequiredTcNotAccepted", id: 0x5, conformance: "TC", + description: "One or more required TC features from the Enhanced Setup Flow were not accepted." + }), + Field({ + name: "TcAcknowledgementsNotReceived", id: 0x6, conformance: "TC", + description: "No acknowledgements from the user for the TC features were received." + }), + Field({ + name: "TcMinVersionNotMet", id: 0x7, conformance: "TC", + description: "The version of the TC features acknowledged by the user did not meet the minimum required version." + }) + ), + + Datatype( + { + name: "RegulatoryLocationTypeEnum", type: "enum8", + details: "This enumeration is used by the RegulatoryConfig and LocationCapability attributes to indicate " + + "possible radio usage.", + xref: { document: "core", section: "11.10.5.2" } + }, + + Field({ name: "Indoor", id: 0x0, conformance: "M", description: "Indoor only" }), + Field({ name: "Outdoor", id: 0x1, conformance: "M", description: "Outdoor only" }), + Field({ name: "IndoorOutdoor", id: 0x2, conformance: "M", description: "Indoor/Outdoor" }) + ), + + Datatype( + { + name: "BasicCommissioningInfo", type: "struct", + details: "This structure provides some constant values that may be of use to all commissioners.", + xref: { document: "core", section: "11.10.5.3" } + }, + + Field({ + name: "FailSafeExpiryLengthSeconds", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall contain a conservative initial duration (in seconds) to set in the FailSafe for " + + "the commissioning flow to complete successfully. This may vary depending on the speed or sleepiness " + + "of the Commissionee. This value, if used in the ArmFailSafe command’s ExpiryLengthSeconds field " + + "SHOULD allow a Commissioner to proceed with a nominal commissioning without having to-rearm the " + + "fail-safe, with some margin.", + xref: { document: "core", section: "11.10.5.3.1" } + }), + + Field({ + name: "MaxCumulativeFailsafeSeconds", id: 0x1, type: "uint16", conformance: "M", constraint: "desc", + + details: "This field shall contain a conservative value in seconds denoting the maximum total duration for " + + "which a fail safe timer can be re-armed. See Section 11.10.7.2.1, “Fail Safe Context”." + + "\n" + + "The value of this field shall be greater than or equal to the FailSafeExpiryLengthSeconds. Absent " + + "additional guidelines, it is recommended that the value of this field be aligned with the initial " + + "Announcement Duration and default to 900 seconds.", + + xref: { document: "core", section: "11.10.5.3.2" } + }) + ) + ), + + Cluster( + { + name: "DiagnosticLogs", id: 0x32, classification: "node", pics: "DLOG", + details: "This Cluster supports an interface to a Node. It provides commands for retrieving unstructured " + + "diagnostic logs from a Node that may be used to aid in diagnostics. It will often be the case that " + + "unstructured diagnostic logs will be Node-wide and not specific to any subset of Endpoints. When " + + "present, this Cluster shall be implemented once for the Node. The Node SHOULD also implement the " + + "BDX Initiator and BDX Sender roles as defined in the BDX Protocol.", + xref: { document: "core", section: "11.11" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Command( + { + name: "RetrieveLogsRequest", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "RetrieveLogsResponse", + details: "Reception of this command starts the process of retrieving diagnostic logs from a Node.", + xref: { document: "core", section: "11.11.5.1" } + }, + + Field({ + name: "Intent", id: 0x0, type: "IntentEnum", conformance: "M", + details: "This field shall indicate why the diagnostic logs are being retrieved from the Node. A Node may " + + "utilize this field to selectively determine the logs to transfer.", + xref: { document: "core", section: "11.11.5.1.1" } + }), + + Field({ + name: "RequestedProtocol", id: 0x1, type: "TransferProtocolEnum", conformance: "M", + + details: "This field shall be used to indicate how the log transfer is to be realized. If the field is set to " + + "BDX, then if the receiving Node supports BDX it shall attempt to use BDX to transfer any potential " + + "diagnostic logs; if the receiving Node does not support BDX then the Node shall follow the " + + "requirements defined for a TransferProtocolEnum of ResponsePayload. If this field is set to " + + "ResponsePayload the receiving Node shall only utilize the LogContent field of the " + + "RetrieveLogsResponse command to transfer diagnostic log information.", + + xref: { document: "core", section: "11.11.5.1.2" } + }), + + Field({ + name: "TransferFileDesignator", id: 0x2, type: "string", conformance: "O", constraint: "max 32", + + details: "This field shall be present if the RequestedProtocol is BDX. The TransferFileDesignator shall be " + + "set as the File Designator of the BDX transfer if initiated." + + "\n" + + "Effect on Receipt" + + "\n" + + "On receipt of this command, the Node shall respond with a RetrieveLogsResponse command." + + "\n" + + "If the RequestedProtocol is set to BDX the Node SHOULD immediately realize the RetrieveLogsResponse " + + "command by initiating a BDX Transfer, sending a BDX SendInit message with the File Designator field " + + "of the message set to the value of the TransferFileDesignator field of the RetrieveLogsRequest. On " + + "reception of a BDX SendAccept message the Node shall send a RetrieveLogsResponse command with a " + + "Status field set to Success and proceed with the log transfer over BDX. If a failure StatusReport " + + "is received in response to the SendInit message, the Node shall send a RetrieveLogsResponse command " + + "with a Status of Denied. In the case where the Node is able to fit the entirety of the requested " + + "logs within the LogContent field, the Status field of the RetrieveLogsResponse shall be set to " + + "Exhausted and a BDX session shall NOT be initiated." + + "\n" + + "If the RequestedProtocol is set to BDX and either the Node does not support BDX or it is not " + + "possible for the Node to establish a BDX session, then the Node shall utilize the LogContent field " + + "of the RetrieveLogsResponse command to transfer as much of the current logs as it can fit within " + + "the response, and the Status field of the RetrieveLogsResponse shall be set to Exhausted." + + "\n" + + "If the RequestedProtocol is set to ResponsePayload the Node shall utilize the LogContent field of " + + "the RetrieveLogsResponse command to transfer as much of the current logs as it can fit within the " + + "response, and a BDX session shall NOT be initiated." + + "\n" + + "If the RequestedProtocol is set to BDX and there is no TransferFileDesignator the command shall " + + "fail with a Status Code of INVALID_COMMAND." + + "\n" + + "If the Intent and/or the RequestedProtocol arguments contain invalid (out of range) values the " + + "command shall fail with a Status Code of INVALID_COMMAND.", + + xref: { document: "core", section: "11.11.5.1.3" } + }) + ), + + Command( + { + name: "RetrieveLogsResponse", id: 0x1, conformance: "M", direction: "response", + details: "This shall be generated as a response to the RetrieveLogsRequest. The data for this command is " + + "shown in the following.", + xref: { document: "core", section: "11.11.5.2" } + }, + + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", + details: "This field shall indicate the result of an attempt to retrieve diagnostic logs.", + xref: { document: "core", section: "11.11.5.2.1" } + }), + + Field({ + name: "LogContent", id: 0x1, type: "octstr", conformance: "M", constraint: "max 1024", + details: "This field shall be included in the command if the Status field has a value of Success or " + + "Exhausted. A Node SHOULD utilize this field to transfer the newest diagnostic log entries. This " + + "field shall be empty if BDX is requested and the Status field has a value of Success.", + xref: { document: "core", section: "11.11.5.2.2" } + }), + + Field({ + name: "UtcTimeStamp", id: 0x2, type: "epoch-us", conformance: "O", + details: "This field SHOULD be included in the command if the Status field has a value of Success and the " + + "Node maintains a wall clock. When included, the UTCTimeStamp field shall contain the value of the " + + "oldest log entry in the diagnostic logs that are being transferred.", + xref: { document: "core", section: "11.11.5.2.3" } + }), + + Field({ + name: "TimeSinceBoot", id: 0x3, type: "systime-us", conformance: "O", + details: "This field SHOULD be included in the command if the Status field has a value of Success. When " + + "included, the TimeSinceBoot field shall contain the time of the oldest log entry in the diagnostic " + + "logs that are being transferred represented by the number of microseconds since the last time the " + + "Node went through a reboot.", + xref: { document: "core", section: "11.11.5.2.4" } + }) + ), + + Datatype( + { name: "IntentEnum", type: "enum8", xref: { document: "core", section: "11.11.4.1" } }, + + Field({ + name: "EndUserSupport", id: 0x0, conformance: "M", + description: "Logs to be used for end- user support", + details: "shall indicate that the purpose of the log request is to retrieve logs for the intention of " + + "providing support to an end-user.", + xref: { document: "core", section: "11.11.4.1.1" } + }), + + Field({ + name: "NetworkDiag", id: 0x1, conformance: "M", + description: "Logs to be used for network diagnostics", + details: "shall indicate that the purpose of the log request is to diagnose the network(s) for which the Node " + + "is currently commissioned (and/or connected) or has previously been commissioned (and/or connected).", + xref: { document: "core", section: "11.11.4.1.2" } + }), + + Field({ + name: "CrashLogs", id: 0x2, conformance: "M", description: "Obtain crash logs from the Node", + details: "shall indicate that the purpose of the log request is to retrieve any crash logs that may be " + + "present on a Node.", + xref: { document: "core", section: "11.11.4.1.3" } + }) + ), + + Datatype( + { name: "StatusEnum", type: "enum8", xref: { document: "core", section: "11.11.4.2" } }, + Field({ + name: "Success", id: 0x0, conformance: "M", description: "Successful transfer of logs", + details: "shall be used if diagnostic logs will be or are being transferred.", + xref: { document: "core", section: "11.11.4.2.1" } + }), + + Field({ + name: "Exhausted", id: 0x1, conformance: "M", description: "All logs has been transferred", + details: "shall be used when a BDX session is requested, however, all available logs were provided in a " + + "LogContent field.", + xref: { document: "core", section: "11.11.4.2.2" } + }), + + Field({ + name: "NoLogs", id: 0x2, conformance: "M", description: "No logs of the requested type available", + details: "shall be used if the Node does not currently have any diagnostic logs of the requested type " + + "(Intent) to transfer.", + xref: { document: "core", section: "11.11.4.2.3" } + }), + + Field({ + name: "Busy", id: 0x3, conformance: "M", description: "Unable to handle request, retry later", + details: "shall be used if the Node is unable to handle the request (e.g. in the process of another transfer) " + + "and the Client SHOULD re-attempt the request later.", + xref: { document: "core", section: "11.11.4.2.4" } + }), + + Field({ + name: "Denied", id: 0x4, conformance: "M", + description: "The request is denied, no logs being transferred", + details: "shall be used if the Node is denying the current transfer of diagnostic logs for any reason.", + xref: { document: "core", section: "11.11.4.2.5" } + }) + ), + + Datatype( + { name: "TransferProtocolEnum", type: "enum8", xref: { document: "core", section: "11.11.4.3" } }, + + Field({ + name: "ResponsePayload", id: 0x0, conformance: "M", + description: "Logs to be returned as a response", + details: "shall be used by a Client to request that logs are transferred using the LogContent attribute of " + + "the response", + xref: { document: "core", section: "11.11.4.3.1" } + }), + + Field({ + name: "Bdx", id: 0x1, conformance: "M", description: "Logs to be returned using BDX", + details: "shall be used by a Client to request that logs are transferred using BDX as defined in BDX Protocol", + xref: { document: "core", section: "11.11.4.3.2" } + }) + ) + ), + + Cluster( + { + name: "GeneralDiagnostics", id: 0x33, classification: "node", pics: "DGGEN", + details: "The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire " + + "standardized diagnostics metrics that may be used by a Node to assist a user or Administrator in " + + "diagnosing potential problems. The General Diagnostics Cluster attempts to centralize all metrics " + + "that are broadly relevant to the majority of Nodes.", + xref: { document: "core", section: "11.12" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.12.4" } }, + + Field({ + name: "DMTEST", conformance: "desc", constraint: "0", description: "DataModelTest", + details: "This feature indicates support for extended Data Model testing commands, which are required in some " + + "situations." + + "\n" + + "This feature shall be supported if the MaxPathsPerInvoke attribute of the Basic Information Cluster " + + "has a value > 1.", + xref: { document: "core", section: "11.12.4.1" } + }) + ), + + Attribute( + { + name: "NetworkInterfaces", id: 0x0, type: "list", access: "R V", conformance: "M", + constraint: "max 8", + details: "The NetworkInterfaces attribute shall be a list of NetworkInterface structs. Each logical network " + + "interface on the Node shall be represented by a single entry within the NetworkInterfaces attribute.", + xref: { document: "core", section: "11.12.6.1" } + }, + + Field({ name: "entry", type: "NetworkInterface" }) + ), + + Attribute({ + name: "RebootCount", id: 0x1, type: "uint16", access: "R V", conformance: "M", quality: "N", + details: "The RebootCount attribute shall indicate a best-effort count of the number of times the Node has " + + "rebooted. The RebootCount attribute SHOULD be incremented each time the Node reboots. The " + + "RebootCount attribute shall NOT be incremented when a Node wakes from a low-power or sleep state. " + + "The RebootCount attribute shall only be reset to 0 upon a factory reset of the Node.", + xref: { document: "core", section: "11.12.6.2" } + }), + + Attribute({ + name: "UpTime", id: 0x2, type: "uint64", access: "R V", conformance: "M", quality: "C", + details: "The UpTime attribute shall indicate a best-effort assessment of the length of time, in seconds, " + + "since the Node’s last reboot. This attribute SHOULD be incremented to account for the periods of " + + "time that a Node is in a low-power or sleep state. This attribute shall only be reset upon a device " + + "reboot. This attribute shall be based on the same System Time source as those used to fulfill any " + + "usage of the system-us and system-ms data types within the server.", + xref: { document: "core", section: "11.12.6.3" } + }), + + Attribute({ + name: "TotalOperationalHours", id: 0x3, type: "uint32", access: "R V", conformance: "O", + quality: "N C", + details: "The TotalOperationalHours attribute shall indicate a best-effort attempt at tracking the length of " + + "time, in hours, that the Node has been operational. The TotalOperationalHours attribute SHOULD be " + + "incremented to account for the periods of time that a Node is in a low-power or sleep state. The " + + "TotalOperationalHours attribute shall only be reset upon a factory reset of the Node.", + xref: { document: "core", section: "11.12.6.4" } + }), + + Attribute({ + name: "BootReason", id: 0x4, type: "BootReasonEnum", access: "R V", conformance: "O", + details: "The BootReason attribute shall indicate the reason for the Node’s most recent boot.", + xref: { document: "core", section: "11.12.6.5" } + }), + + Attribute( + { + name: "ActiveHardwareFaults", id: 0x5, type: "list", access: "R V", conformance: "O", + constraint: "max 11", + + details: "The ActiveHardwareFaults attribute shall indicate the set of faults currently detected by the Node. " + + "When the Node detects a fault has been raised, the appropriate HardwareFaultEnum value shall be " + + "added to this list. This list shall NOT contain more than one instance of a specific " + + "HardwareFaultEnum value. When the Node detects that all conditions contributing to a fault has been" + + "\n" + + "cleared, the corresponding HardwareFaultEnum value shall be removed from this list. An empty list " + + "shall indicate there are currently no active faults. The order of this list SHOULD have no " + + "significance. Clients interested in monitoring changes in active faults may subscribe to this " + + "attribute, or they may subscribe to HardwareFaultChange.", + + xref: { document: "core", section: "11.12.6.6" } + }, + + Field({ name: "entry", type: "HardwareFaultEnum" }) + ), + + Attribute( + { + name: "ActiveRadioFaults", id: 0x6, type: "list", access: "R V", conformance: "O", + constraint: "max 7", + + details: "The ActiveRadioFaults attribute shall indicate the set of faults currently detected by the Node. " + + "When the Node detects a fault has been raised, the appropriate RadioFaultEnum value shall be added " + + "to this list. This list shall NOT contain more than one instance of a specific RadioFaultEnum " + + "value. When the Node detects that all conditions contributing to a fault has been cleared, the " + + "corresponding RadioFaultEnum value shall be removed from this list. An empty list shall indicate " + + "there are currently no active faults. The order of this list SHOULD have no significance. Clients " + + "interested in monitoring changes in active faults may subscribe to this attribute, or they may " + + "subscribe to RadioFaultChange.", + + xref: { document: "core", section: "11.12.6.7" } + }, + + Field({ name: "entry", type: "RadioFaultEnum" }) + ), + + Attribute( + { + name: "ActiveNetworkFaults", id: 0x7, type: "list", access: "R V", conformance: "O", + constraint: "max 4", + + details: "The ActiveNetworkFaults attribute shall indicate the set of faults currently detected by the Node. " + + "When the Node detects a fault has been raised, the appropriate NetworkFaultEnum value shall be " + + "added to this list. This list shall NOT contain more than one instance of a specific " + + "NetworkFaultEnum value. When the Node detects that all conditions contributing to a fault has been " + + "cleared, the corresponding NetworkFaultEnum value shall be removed from this list. An empty list " + + "shall indicate there are currently no active faults. The order of this list SHOULD have no " + + "significance. Clients interested in monitoring changes in active faults may subscribe to this " + + "attribute, or they may subscribe to NetworkFaultChange.", + + xref: { document: "core", section: "11.12.6.8" } + }, + + Field({ name: "entry", type: "NetworkFaultEnum" }) + ), + + Attribute({ + name: "TestEventTriggersEnabled", id: 0x8, type: "bool", access: "R V", conformance: "M", + + details: "The TestEventTriggersEnabled attribute shall indicate whether the Node has any TestEventTrigger " + + "configured. When this attribute is true, the Node has been configured with one or more test event " + + "triggers by virtue of the internally programmed EnableKey value (see TestEventTrigger) being set to " + + "a non-zero value. This attribute can be used by Administrators to detect if a device was " + + "inadvertently commissioned with test event trigger mode enabled, and take appropriate action (e.g. " + + "warn the user and/or offer to remove all fabrics on the Node).", + + xref: { document: "core", section: "11.12.6.9" } + }), + + Attribute({ name: "DoNotUse", id: 0x9, conformance: "X", xref: { document: "core", section: "11.12.6" } }), + + Event( + { + name: "HardwareFaultChange", id: 0x0, access: "V", conformance: "O", priority: "critical", + details: "The HardwareFaultChange Event shall indicate a change in the set of hardware faults currently " + + "detected by the Node.", + xref: { document: "core", section: "11.12.8.1" } + }, + + Field( + { + name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 11", + details: "This field shall represent the set of faults currently detected, as per HardwareFaultEnum.", + xref: { document: "core", section: "11.12.8.1.1" } + }, + Field({ name: "entry", type: "HardwareFaultEnum" }) + ), + + Field( + { + name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 11", + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "HardwareFaultEnum.", + xref: { document: "core", section: "11.12.8.1.2" } + }, + + Field({ name: "entry", type: "HardwareFaultEnum" }) + ) + ), + + Event( + { + name: "RadioFaultChange", id: 0x1, access: "V", conformance: "O", priority: "critical", + details: "The RadioFaultChange Event shall indicate a change in the set of radio faults currently detected by " + + "the Node.", + xref: { document: "core", section: "11.12.8.2" } + }, + + Field( + { + name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 7", + details: "This field shall represent the set of faults currently detected, as per RadioFaultEnum.", + xref: { document: "core", section: "11.12.8.2.1" } + }, + Field({ name: "entry", type: "RadioFaultEnum" }) + ), + + Field( + { + name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 7", + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "RadioFaultEnum.", + xref: { document: "core", section: "11.12.8.2.2" } + }, + + Field({ name: "entry", type: "RadioFaultEnum" }) + ) + ), + + Event( + { + name: "NetworkFaultChange", id: 0x2, access: "V", conformance: "O", priority: "critical", + details: "The NetworkFaultChange Event shall indicate a change in the set of network faults currently " + + "detected by the Node.", + xref: { document: "core", section: "11.12.8.3" } + }, + + Field( + { + name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 4", + details: "This field shall represent the set of faults currently detected, as per NetworkFaultEnum.", + xref: { document: "core", section: "11.12.8.3.1" } + }, + Field({ name: "entry", type: "NetworkFaultEnum" }) + ), + + Field( + { + name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 4", + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "NetworkFaultEnum.", + xref: { document: "core", section: "11.12.8.3.2" } + }, + + Field({ name: "entry", type: "NetworkFaultEnum" }) + ) + ), + + Event( + { + name: "BootReason", id: 0x3, access: "V", conformance: "M", priority: "critical", + details: "The BootReason Event shall indicate the reason that caused the device to start-up.", + xref: { document: "core", section: "11.12.8.4" } + }, + Field({ + name: "BootReason", id: 0x0, type: "BootReasonEnum", conformance: "M", + details: "This field shall contain the reason for this BootReason event.", + xref: { document: "core", section: "11.12.8.4.1" } + }) + ), + + Command( + { + name: "TestEventTrigger", id: 0x0, access: "M", conformance: "M", direction: "request", + response: "status", + + details: "This command shall be supported to provide a means for certification tests to trigger some test- " + + "plan-specific events, necessary to assist in automation of device interactions for some " + + "certification test cases. This command shall NOT cause any changes to the state of the device that " + + "persist after the last fabric is removed." + + "\n" + + "The fields for the TestEventTrigger command are as follows:", + + xref: { document: "core", section: "11.12.7.1" } + }, + + Field({ + name: "EnableKey", id: 0x0, type: "octstr", conformance: "M", constraint: "16", + + details: "The EnableKey is a 128 bit value provided by the client in this command, which needs to match a " + + "value chosen by the manufacturer and configured on the server using manufacturer-specific means, " + + "such as pre-provisioning. The value of all zeroes is reserved to indicate that no EnableKey is set. " + + "Therefore, if the EnableKey field is received with all zeroes, this command shall FAIL with a " + + "response status of CONSTRAINT_ERROR." + + "\n" + + "The EnableKey SHOULD be unique per exact set of devices going to a certification test." + + "\n" + + "Devices not targeted towards going to a certification test event shall NOT have a non-zero " + + "EnableKey value configured, so that only devices in test environments are responsive to this " + + "command." + + "\n" + + "In order to prevent unwittingly actuating a particular trigger, this command shall respond with a " + + "response status of CONSTRAINT_ERROR if the EnableKey field does not match the a-priori value " + + "configured on the device.", + + xref: { document: "core", section: "11.12.7.1.1" } + }), + + Field({ + name: "EventTrigger", id: 0x1, type: "uint64", conformance: "M", + + details: "This field shall indicate the test or test mode which the client wants to trigger." + + "\n" + + "The expected side-effects of EventTrigger values are out of scope of this specification and will be " + + "described within appropriate certification test literature provided to manufacturers by the " + + "Connectivity Standards Alliance, in conjunction with certification test cases documentation." + + "\n" + + "Values of EventTrigger in the range 0xFFFF_FFFF_0000_0000 through 0xFFFF_FFFF_FFFF_FFFF are " + + "reserved for testing use by manufacturers and will not appear in CSA certification test literature." + + "\n" + + "If the value of EventTrigger received is not supported by the receiving Node, this command shall" + + "\n" + + "fail with a status code of INVALID_COMMAND." + + "\n" + + "Otherwise, if the EnableKey value matches the configured internal value for a particular Node, and " + + "the EventTrigger value matches a supported test event trigger value, the command shall succeed and " + + "execute the expected trigger action." + + "\n" + + "If no specific test event triggers are required to be supported by certification test requirements " + + "for the features that a given product will be certified against, this command may always fail with " + + "the INVALID_COMMAND status, equivalent to the situation of receiving an unknown EventTrigger, for " + + "all possible EventTrigger values.", + + xref: { document: "core", section: "11.12.7.1.2" } + }) + ), + + Command({ + name: "TimeSnapshot", id: 0x1, access: "O", conformance: "M", direction: "request", + response: "TimeSnapshotResponse", + + details: "This command may be used by a client to obtain a correlated view of both System Time, and, if " + + "currently synchronized and supported, \"wall clock time\" of the server. This can help clients " + + "establish time correlation between their concept of time and the server’s concept of time. This is " + + "especially useful when processing event histories where some events only contain System Time." + + "\n" + + "Upon command invocation, the server shall respond with a TimeSnapshotResponse.", + + xref: { document: "core", section: "11.12.7.2" } + }), + + Command( + { + name: "TimeSnapshotResponse", id: 0x2, conformance: "M", direction: "response", + + details: "This command shall be generated in response to a TimeSnapshot command." + + "\n" + + "When generating this response, all fields shall be gathered as close together in time as possible, " + + "so that the time jitter between the values is minimized." + + "\n" + + "If the Time Synchronization cluster is supported by the node, the PosixTimeMs field shall NOT be " + + "null unless the UTCTime attribute in the Time Synchronization cluster is also null.", + + xref: { document: "core", section: "11.12.7.3" } + }, + + Field({ + name: "SystemTimeMs", id: 0x0, type: "systime-ms", conformance: "M", + details: "This shall indicate the current System Time in milliseconds (type system-ms), with the value taken " + + "at the time of processing of the TimeSnapshot command that generated this response." + + "\n" + + "The value shall be taken from the same clock which populates the Timestamp field in events when " + + "using System Time for the field.", + xref: { document: "core", section: "11.12.7.3.1" } + }), + + Field({ + name: "PosixTimeMs", id: 0x1, type: "posix-ms", conformance: "M", default: null, quality: "X", + + details: "This shall indicate the current time in POSIX Time in milliseconds, with the value taken from the " + + "same source that could populate the Timestamp field of events. This value shall only be null when " + + "any the following are true:" + + "\n" + + " • The node doesn’t support the Time Synchronization cluster." + + "\n" + + " • The node’s Time Synchronization cluster instance’s UTCTime attribute is null.", + + xref: { document: "core", section: "11.12.7.3.2" } + }) + ), + + Command( + { + name: "PayloadTestRequest", id: 0x3, access: "M", conformance: "DMTEST", direction: "request", + response: "PayloadTestResponse", + + details: "This command provides a means for certification tests or manufacturer’s internal tests to validate " + + "particular command handling and encoding constraints by generating a response of a given size." + + "\n" + + "This command shall use the same EnableKey behavior as the TestEventTrigger command, whereby " + + "processing of the command is only enabled when the TestEventTriggersEnabled field is true, which " + + "shall NOT be true outside of certification testing or manufacturer’s internal tests." + + "\n" + + "The fields for the PayloadTestRequest command are as follows:", + + xref: { document: "core", section: "11.12.7.4" } + }, + + Field({ + name: "EnableKey", id: 0x0, type: "octstr", conformance: "M", constraint: "16", + details: "This field shall have the same meaning and usage as the TestEventTrigger EnableKey field.", + xref: { document: "core", section: "11.12.7.4.1" } + }), + Field({ + name: "Value", id: 0x1, type: "uint8", conformance: "M", + details: "This field shall indicate the value to use in every byte of the PayloadTestResponse’s Payload field.", + xref: { document: "core", section: "11.12.7.4.2" } + }), + + Field({ + name: "Count", id: 0x2, type: "uint16", conformance: "M", constraint: "max 2048", + + details: "This field shall indicate the number of times to repeat the Value in the PayloadTestResponse’s " + + "Payload field." + + "\n" + + "Effect upon receipt" + + "\n" + + "This command shall respond with a response status of CONSTRAINT_ERROR if either:" + + "\n" + + " • The EnableKey field does not match the a-priori value configured on the device." + + "\n" + + " • The TestEventTriggersEnabled field is currently false." + + "\n" + + "Otherwise, the server shall respond with a PayloadTestResponse command with a Payload field value " + + "containing Count instances of the Value byte. If the response is too large to send, the server " + + "shall fail the command and respond with a response status of RESOURCE_EXHAUSTED." + + "\n" + + "For example:" + + "\n" + + " • If Value is 0x55 and the Count is zero, then the PayloadTestResponse would have the Payload " + + " field set to an empty octet string." + + "\n" + + " • If Value is 0xA5 and the Count is 10, the PayloadTestResponse would have the Payload field set" + + "\n" + + "to a content whose hexadecimal representation would be A5A5A5A5A5A5A5A5A5A5, and base64 " + + "representation would be paWlpaWlpaWlpQ==.", + + xref: { document: "core", section: "11.12.7.4.3" } + }) + ), + + Command( + { + name: "PayloadTestResponse", id: 0x4, conformance: "DMTEST", direction: "response", + details: "This command is sent by the server on receipt of the PayloadTestRequest command.", + xref: { document: "core", section: "11.12.7.5" } + }, + Field({ + name: "Payload", id: 0x0, type: "octstr", conformance: "M", constraint: "max 2048", + details: "This field shall contain the computed response of the PayloadTestRequest command.", + xref: { document: "core", section: "11.12.7.5.1" } + }) + ), + + Datatype( + { name: "HardwareFaultEnum", type: "enum8", xref: { document: "core", section: "11.12.5.1" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "The Node has encountered an unspecified fault." + }), + Field({ + name: "Radio", id: 0x1, conformance: "O", + description: "The Node has encountered a fault with at least one of its radios." + }), + Field({ + name: "Sensor", id: 0x2, conformance: "O", + description: "The Node has encountered a fault with at least one of its sensors." + }), + Field({ + name: "ResettableOverTemp", id: 0x3, conformance: "O", + description: "The Node has encountered an over-temperature fault that is resettable." + }), + Field({ + name: "NonResettableOverTemp", id: 0x4, conformance: "O", + description: "The Node has encountered an over-temperature fault that is not resettable." + }), + Field({ + name: "PowerSource", id: 0x5, conformance: "O", + description: "The Node has encountered a fault with at least one of its power sources." + }), + Field({ + name: "VisualDisplayFault", id: 0x6, conformance: "O", + description: "The Node has encountered a fault with at least one of its visual displays." + }), + Field({ + name: "AudioOutputFault", id: 0x7, conformance: "O", + description: "The Node has encountered a fault with at least one of its audio outputs." + }), + Field({ + name: "UserInterfaceFault", id: 0x8, conformance: "O", + description: "The Node has encountered a fault with at least one of its user interfaces." + }), + Field({ + name: "NonVolatileMemoryError", id: 0x9, conformance: "O", + description: "The Node has encountered a fault with its non-volatile memory." + }), + Field({ + name: "TamperDetected", id: 0xa, conformance: "O", + description: "The Node has encountered disallowed physical tampering." + }) + ), + + Datatype( + { name: "RadioFaultEnum", type: "enum8", xref: { document: "core", section: "11.12.5.2" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "The Node has encountered an unspecified radio fault." + }), + Field({ + name: "WiFiFault", id: 0x1, conformance: "O", + description: "The Node has encountered a fault with its Wi-Fi radio." + }), + Field({ + name: "CellularFault", id: 0x2, conformance: "O", + description: "The Node has encountered a fault with its cellular radio." + }), + Field({ + name: "ThreadFault", id: 0x3, conformance: "O", + description: "The Node has encountered a fault with its802.15.4 radio." + }), + Field({ + name: "NfcFault", id: 0x4, conformance: "O", + description: "The Node has encountered a fault with its NFC radio." + }), + Field({ + name: "BleFault", id: 0x5, conformance: "O", + description: "The Node has encountered a fault with its BLE radio." + }), + Field({ + name: "EthernetFault", id: 0x6, conformance: "O", + description: "The Node has encountered a fault with its Ethernet controller." + }) + ), + + Datatype( + { name: "NetworkFaultEnum", type: "enum8", xref: { document: "core", section: "11.12.5.3" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "The Node has encountered an unspecified fault." + }), + Field({ + name: "HardwareFailure", id: 0x1, conformance: "O", + description: "The Node has encountered a network fault as a result of a hardware failure." + }), + Field({ + name: "NetworkJammed", id: 0x2, conformance: "O", + description: "The Node has encountered a network fault as a result of a jammed network." + }), + Field({ + name: "ConnectionFailed", id: 0x3, conformance: "O", + description: "The Node has encountered a network fault as a result of a failure to establish a connection." + }) + ), + + Datatype( + { name: "InterfaceTypeEnum", type: "enum8", xref: { document: "core", section: "11.12.5.4" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "Indicates an interface of an unspecified type." + }), + Field({ name: "WiFi", id: 0x1, conformance: "O", description: "Indicates a Wi-Fi interface." }), + Field({ name: "Ethernet", id: 0x2, conformance: "O", description: "Indicates a Ethernet interface." }), + Field({ name: "Cellular", id: 0x3, conformance: "O", description: "Indicates a Cellular interface." }), + Field({ name: "Thread", id: 0x4, conformance: "O", description: "Indicates a Thread interface." }) + ), + + Datatype( + { name: "BootReasonEnum", type: "enum8", xref: { document: "core", section: "11.12.5.5" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "The Node is unable to identify the Power-On reason as one of the other provided enumeration values." + }), + Field({ + name: "PowerOnReboot", id: 0x1, conformance: "M", + description: "The Node has booted as the result of physical interaction with the device resulting in a reboot." + }), + Field({ + name: "BrownOutReset", id: 0x2, conformance: "M", + description: "The Node has rebooted as the result of a brown-out of the Node’s power supply." + }), + Field({ + name: "SoftwareWatchdogReset", id: 0x3, conformance: "M", + description: "The Node has rebooted as the result of a software watchdog timer." + }), + Field({ + name: "HardwareWatchdogReset", id: 0x4, conformance: "M", + description: "The Node has rebooted as the result of a hardware watchdog timer." + }), + Field({ + name: "SoftwareUpdateCompleted", id: 0x5, conformance: "M", + description: "The Node has rebooted as the result of a completed software update." + }), + Field({ + name: "SoftwareReset", id: 0x6, conformance: "M", + description: "The Node has rebooted as the result of a software initiated reboot." + }) + ), + + Datatype( + { + name: "NetworkInterface", type: "struct", + details: "This structure describes a network interface supported by the Node, as provided in the " + + "NetworkInterfaces attribute.", + xref: { document: "core", section: "11.12.5.6" } + }, + + Field({ + name: "Name", id: 0x0, type: "string", conformance: "M", constraint: "max 32", + details: "This field shall indicate a human-readable (displayable) name for the network interface, that is " + + "different from all other interfaces.", + xref: { document: "core", section: "11.12.5.6.1" } + }), + + Field({ + name: "IsOperational", id: 0x1, type: "bool", conformance: "M", + details: "This field shall indicate if the Node is currently advertising itself operationally on this network " + + "interface and is capable of successfully receiving incoming traffic from other Nodes.", + xref: { document: "core", section: "11.12.5.6.2" } + }), + + Field({ + name: "OffPremiseServicesReachableIPv4", id: 0x2, type: "bool", conformance: "M", default: null, + quality: "X", + details: "This field shall indicate whether the Node is currently able to reach off-premise services it uses " + + "by utilizing IPv4. The value shall be null if the Node does not use such services or does not know " + + "whether it can reach them.", + xref: { document: "core", section: "11.12.5.6.3" } + }), + + Field({ + name: "OffPremiseServicesReachableIPv6", id: 0x3, type: "bool", conformance: "M", default: null, + quality: "X", + details: "This field shall indicate whether the Node is currently able to reach off-premise services it uses " + + "by utilizing IPv6. The value shall be null if the Node does not use such services or does not know " + + "whether it can reach them.", + xref: { document: "core", section: "11.12.5.6.4" } + }), + + Field({ + name: "HardwareAddress", id: 0x4, type: "hwadr", conformance: "M", + details: "This field shall contain the current link-layer address for a 802.3 or IEEE 802.11-2020 network" + + "\n" + + "interface and contain the current extended MAC address for a 802.15.4 interface. The byte order of " + + "the octstr shall be in wire byte order. For addresses values less than 64 bits, the first two bytes " + + "shall be zero.", + xref: { document: "core", section: "11.12.5.6.5" } + }), + + Field( + { + name: "IPv4Addresses", id: 0x5, type: "list", conformance: "M", constraint: "max 4", + details: "This field shall provide a list of the IPv4 addresses that are currently assigned to the network " + + "interface.", + xref: { document: "core", section: "11.12.5.6.6" } + }, + + Field({ name: "entry", type: "ipv4adr" }) + ), + + Field( + { + name: "IPv6Addresses", id: 0x6, type: "list", conformance: "M", constraint: "max 8", + details: "This field shall provide a list of the unicast IPv6 addresses that are currently assigned to the " + + "network interface. This list shall include the Node’s link-local address and SHOULD include any " + + "assigned GUA and ULA addresses. This list shall NOT include any multicast group addresses to which " + + "the Node is subscribed.", + xref: { document: "core", section: "11.12.5.6.7" } + }, + + Field({ name: "entry", type: "ipv6adr" }) + ), + + Field({ + name: "Type", id: 0x7, type: "InterfaceTypeEnum", conformance: "M", + details: "This field shall indicate the type of the interface using the InterfaceTypeEnum.", + xref: { document: "core", section: "11.12.5.6.8" } + }) + ) + ), + + Cluster( + { + name: "SoftwareDiagnostics", id: 0x34, classification: "node", pics: "DGSW", quality: "K", + details: "The Software Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that " + + "may be used by a Node to assist a user or Administrator in diagnosing potential problems. The " + + "Software Diagnostics Cluster attempts to centralize all metrics that are relevant to the software " + + "that may be running on a Node.", + xref: { document: "core", section: "11.13" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.13.4" } }, + Field({ + name: "WTRMRK", constraint: "0", description: "Watermarks", + details: "Node makes available the metrics for high watermark related to memory consumption." + }) + ), + + Attribute( + { + name: "ThreadMetrics", id: 0x0, type: "list", access: "R V", conformance: "O", constraint: "max 64", + details: "The ThreadMetrics attribute shall be a list of ThreadMetricsStruct structs. Each active thread on " + + "the Node shall be represented by a single entry within the ThreadMetrics attribute.", + xref: { document: "core", section: "11.13.6.1" } + }, + + Field({ name: "entry", type: "ThreadMetricsStruct" }) + ), + + Attribute({ + name: "CurrentHeapFree", id: 0x1, type: "uint64", access: "R V", conformance: "O", + details: "The CurrentHeapFree attribute shall indicate the current amount of heap memory, in bytes, that are " + + "free for allocation. The effective amount may be smaller due to heap fragmentation or other reasons.", + xref: { document: "core", section: "11.13.6.2" } + }), + + Attribute({ + name: "CurrentHeapUsed", id: 0x2, type: "uint64", access: "R V", conformance: "O", + details: "The CurrentHeapUsed attribute shall indicate the current amount of heap memory, in bytes, that is " + + "being used.", + xref: { document: "core", section: "11.13.6.3" } + }), + + Attribute({ + name: "CurrentHeapHighWatermark", id: 0x3, type: "uint64", access: "R V", conformance: "WTRMRK", + details: "The CurrentHeapHighWatermark attribute shall indicate the maximum amount of heap memory, in bytes, " + + "that has been used by the Node. This value shall only be reset upon a Node reboot or upon receiving " + + "of the ResetWatermarks command.", + xref: { document: "core", section: "11.13.6.4" } + }), + + Event( + { + name: "SoftwareFault", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "The SoftwareFault Event shall be generated when a software fault takes place on the Node.", + xref: { document: "core", section: "11.13.8.1" } + }, + + Field({ + name: "Id", id: 0x0, type: "uint64", conformance: "M", default: 0, + details: "The ID field shall be set to the ID of the software thread in which the last software fault " + + "occurred.", + xref: { document: "core", section: "11.13.8.1.1" } + }), + + Field({ + name: "Name", id: 0x1, type: "string", conformance: "O", constraint: "max 8", + details: "The Name field shall be set to a manufacturer-specified name or prefix of the software thread in " + + "which the last software fault occurred.", + xref: { document: "core", section: "11.13.8.1.2" } + }), + + Field({ + name: "FaultRecording", id: 0x2, type: "octstr", conformance: "O", constraint: "max 1024", + details: "The FaultRecording field shall be a manufacturer-specified payload intended to convey information " + + "to assist in further diagnosing or debugging a software fault. The FaultRecording field may be used " + + "to convey information such as, but not limited to, thread backtraces or register contents.", + xref: { document: "core", section: "11.13.8.1.3" } + }) + ), + + Command({ + name: "ResetWatermarks", id: 0x0, access: "M", conformance: "WTRMRK", direction: "request", + response: "status", + + details: "Receipt of this command shall reset the following values which track high and lower watermarks:" + + "\n" + + " • The StackFreeMinimum field of the ThreadMetrics attribute" + + "\n" + + " • The CurrentHeapHighWatermark attribute This command has no payload." + + "\n" + + "Effect on Receipt" + + "\n" + + "On receipt of this command, the Node shall make the following modifications to attributes it " + + "supports:" + + "\n" + + "If implemented, the server shall set the value of the CurrentHeapHighWatermark attribute to the " + + "value of the CurrentHeapUsed attribute." + + "\n" + + "If implemented, the server shall set the value of the StackFreeMinimum field for every thread to " + + "the value of the corresponding thread’s StackFreeCurrent field.", + + xref: { document: "core", section: "11.13.7.1" } + }), + + Datatype( + { name: "ThreadMetricsStruct", type: "struct", xref: { document: "core", section: "11.13.5.1" } }, + + Field({ + name: "Id", id: 0x0, type: "uint64", conformance: "M", + details: "The Id field shall be a server-assigned per-thread unique ID that is constant for the duration of " + + "the thread. Efforts SHOULD be made to avoid reusing ID values when possible.", + xref: { document: "core", section: "11.13.5.1.1" } + }), + + Field({ + name: "Name", id: 0x1, type: "string", conformance: "O", constraint: "max 8", + details: "The Name field shall be set to a vendor defined name or prefix of the software thread that is " + + "static for the duration of the thread.", + xref: { document: "core", section: "11.13.5.1.2" } + }), + + Field({ + name: "StackFreeCurrent", id: 0x2, type: "uint32", conformance: "O", + details: "The StackFreeCurrent field shall indicate the current amount of stack memory, in bytes, that are " + + "not being utilized on the respective thread.", + xref: { document: "core", section: "11.13.5.1.3" } + }), + + Field({ + name: "StackFreeMinimum", id: 0x3, type: "uint32", conformance: "O", + details: "The StackFreeMinimum field shall indicate the minimum amount of stack memory, in bytes, that has " + + "been available at any point between the current time and this attribute being reset or initialized " + + "on the respective thread. This value shall only be reset upon a Node reboot or upon receiving of " + + "the ResetWatermarks command.", + xref: { document: "core", section: "11.13.5.1.4" } + }), + + Field({ + name: "StackSize", id: 0x4, type: "uint32", conformance: "O", + details: "The StackSize field shall indicate the amount of stack memory, in bytes, that has been allocated " + + "for use by the respective thread.", + xref: { document: "core", section: "11.13.5.1.5" } + }) + ) + ), + + Cluster( + { + name: "ThreadNetworkDiagnostics", id: 0x35, classification: "node", pics: "DGTHREAD", quality: "K", + details: "The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics " + + "that may be used by a Node to assist a user or Administrator in diagnosing potential problems. The " + + "Thread Network Diagnostics Cluster attempts to centralize all metrics that are relevant to a " + + "potential Thread radio running on a Node.", + xref: { document: "core", section: "11.14" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.14.4" } }, + Field({ + name: "PKTCNT", constraint: "0", description: "PacketCounts", + details: "Server supports the counts for the number of received and transmitted packets on the Thread " + + "interface." + }), + Field({ + name: "ERRCNT", constraint: "1", description: "ErrorCounts", + details: "Server supports the counts for the number of errors that have occurred during the reception and " + + "transmission of packets on the Thread interface." + }), + Field({ + name: "MLECNT", constraint: "2", description: "MleCounts", + details: "Server supports the counts for various MLE layer happenings." + }), + Field({ + name: "MACCNT", constraint: "3", description: "MacCounts", + details: "Server supports the counts for various MAC layer happenings." + }) + ), + + Attribute({ + name: "Channel", id: 0x0, type: "uint16", access: "R V", conformance: "M", quality: "X", + details: "The Channel attribute shall indicate the 802.15.4 channel number configured on the Node’s Thread " + + "interface (that is, the Active Operational Dataset’s current Channel value). A value of null shall " + + "indicate that the Thread interface is not currently configured or operational.", + xref: { document: "core", section: "11.14.6.1" } + }), + + Attribute({ + name: "RoutingRole", id: 0x1, type: "RoutingRoleEnum", access: "R V", conformance: "M", + quality: "X", + details: "The RoutingRole attribute shall indicate the role that this Node has within the routing of messages " + + "through the Thread network, as defined by RoutingRoleEnum. The potential roles are defined" + + "\n" + + "in the following table. A value of null shall indicate that the Thread interface is not currently " + + "configured or operational.", + xref: { document: "core", section: "11.14.6.2" } + }), + + Attribute({ + name: "NetworkName", id: 0x2, type: "string", access: "R V", conformance: "M", constraint: "max 16", + quality: "X", + details: "The NetworkName attribute shall indicate a human-readable (displayable) name for the Thread network " + + "that the Node has been configured to join to. A value of null shall indicate that the Thread " + + "interface is not currently configured or operational.", + xref: { document: "core", section: "11.14.6.3" } + }), + + Attribute({ + name: "PanId", id: 0x3, type: "uint16", access: "R V", conformance: "M", quality: "X", + details: "The PanId attribute shall indicate the 16-bit identifier of the Node on the Thread network. A value " + + "of null shall indicate that the Thread interface is not currently configured or operational.", + xref: { document: "core", section: "11.14.6.4" } + }), + + Attribute({ + name: "ExtendedPanId", id: 0x4, type: "uint64", access: "R V", conformance: "M", quality: "X", + details: "The ExtendedPanId attribute shall indicate the unique 64-bit identifier of the Node on the Thread " + + "network. A value of null shall indicate that the Thread interface is not currently configured or " + + "operational.", + xref: { document: "core", section: "11.14.6.5" } + }), + + Attribute({ + name: "MeshLocalPrefix", id: 0x5, type: "ipv6pre", access: "R V", conformance: "M", quality: "X", + details: "The MeshLocalPrefix attribute shall indicate the mesh-local IPv6 prefix for the Thread network that " + + "the Node has been configured to join to. A value of null shall indicate that the Thread interface " + + "is not currently configured or operational.", + xref: { document: "core", section: "11.14.6.6" } + }), + + Attribute({ + name: "OverrunCount", id: 0x6, type: "uint64", access: "R V", conformance: "ERRCNT", default: 0, + quality: "C", + details: "The OverrunCount attribute shall indicate the number of packets dropped either at ingress or " + + "egress, due to lack of buffer memory to retain all packets on the ethernet network interface. The " + + "OverrunCount attribute shall be reset to 0 upon a reboot of the Node.", + xref: { document: "core", section: "11.14.6.7" } + }), + + Attribute( + { + name: "NeighborTable", id: 0x7, type: "list", access: "R V", conformance: "M", default: [], + details: "The NeighborTable attribute shall indicate the current list of Nodes that comprise the neighbor " + + "table on the Node.", + xref: { document: "core", section: "11.14.6.8" } + }, + + Field({ name: "entry", type: "NeighborTableStruct" }) + ), + + Attribute( + { + name: "RouteTable", id: 0x8, type: "list", access: "R V", conformance: "M", default: [], + details: "The RouteTable attribute shall indicate the current list of router capable Nodes for which routes " + + "have been established.", + xref: { document: "core", section: "11.14.6.9" } + }, + + Field({ name: "entry", type: "RouteTableStruct" }) + ), + + Attribute({ + name: "PartitionId", id: 0x9, type: "uint32", access: "R V", conformance: "M", quality: "X", + details: "The PartitionId attribute shall indicate the Thread Leader Partition Id for the Thread network to " + + "which the Node is joined. Null if not attached to a Thread network.", + xref: { document: "core", section: "11.14.6.10" } + }), + + Attribute({ + name: "Weighting", id: 0xa, type: "uint16", access: "R V", conformance: "M", constraint: "max 255", + quality: "X", + details: "The Weighting attribute shall indicate the Thread Leader Weight used when operating in the Leader " + + "role. Null if not attached to a Thread network.", + xref: { document: "core", section: "11.14.6.11" } + }), + + Attribute({ + name: "DataVersion", id: 0xb, type: "uint16", access: "R V", conformance: "M", + constraint: "max 255", quality: "X", + details: "The DataVersion attribute shall indicate the full Network Data Version the Node currently uses. " + + "Null if not attached to a Thread network.", + xref: { document: "core", section: "11.14.6.12" } + }), + + Attribute({ + name: "StableDataVersion", id: 0xc, type: "uint16", access: "R V", conformance: "M", + constraint: "max 255", quality: "X", + details: "The StableDataVersion attribute shall indicate the Network Data Version for the stable subset of " + + "data the Node currently uses. Null if not attached to a Thread network.", + xref: { document: "core", section: "11.14.6.13" } + }), + + Attribute({ + name: "LeaderRouterId", id: 0xd, type: "uint8", access: "R V", conformance: "M", + constraint: "max 62", quality: "X", + details: "The LeaderRouterId attribute shall indicate the 8-bit LeaderRouterId the Node shall attempt to " + + "utilize upon becoming a router or leader on the Thread network. Null if not attached to a Thread " + + "network.", + xref: { document: "core", section: "11.14.6.14" } + }), + + Attribute({ + name: "DetachedRoleCount", id: 0xe, type: "uint16", access: "R V", conformance: "[MLECNT]", + default: 0, quality: "C", + details: "The DetachedRoleCount attribute shall indicate the number of times the Node entered the " + + "OT_DEVICE_ROLE_DETACHED role as specified within the Thread specification. This value shall only be " + + "reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.15" } + }), + + Attribute({ + name: "ChildRoleCount", id: 0xf, type: "uint16", access: "R V", conformance: "[MLECNT]", default: 0, + quality: "C", + details: "The ChildRoleCount attribute shall indicate the number of times the Node entered the " + + "OT_DEVICE_ROLE_CHILD role as specified within the Thread specification. This value shall only be " + + "reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.16" } + }), + + Attribute({ + name: "RouterRoleCount", id: 0x10, type: "uint16", access: "R V", conformance: "[MLECNT]", + default: 0, quality: "C", + details: "The RouterRoleCount attribute shall indicate the number of times the Node entered the " + + "OT_DEVICE_ROLE_ROUTER role as specified within the Thread specification. This value shall only be " + + "reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.17" } + }), + + Attribute({ + name: "LeaderRoleCount", id: 0x11, type: "uint16", access: "R V", conformance: "[MLECNT]", + default: 0, quality: "C", + details: "The LeaderRoleCount attribute shall indicate the number of times the Node entered the " + + "OT_DEVICE_ROLE_LEADER role as specified within the Thread specification. This value shall only be " + + "reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.18" } + }), + + Attribute({ + name: "AttachAttemptCount", id: 0x12, type: "uint16", access: "R V", conformance: "[MLECNT]", + default: 0, quality: "C", + details: "The AttachAttemptCount attribute shall indicate the number of attempts that have been made to " + + "attach to a Thread network while the Node was detached from all Thread networks. This value shall " + + "only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.19" } + }), + + Attribute({ + name: "PartitionIdChangeCount", id: 0x13, type: "uint16", access: "R V", conformance: "[MLECNT]", + default: 0, quality: "C", + details: "The PartitionIdChangeCount attribute shall indicate the number of times that the Thread network " + + "that the Node is connected to has changed its Partition ID. This value shall only be reset upon a " + + "Node reboot.", + xref: { document: "core", section: "11.14.6.20" } + }), + + Attribute({ + name: "BetterPartitionAttachAttemptCount", id: 0x14, type: "uint16", access: "R V", + conformance: "[MLECNT]", default: 0, quality: "C", + details: "The BetterPartitionAttachAttemptCount attribute shall indicate the number of times a Node has " + + "attempted to attach to a different Thread partition that it has determined is better than the " + + "partition it is currently attached to. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.21" } + }), + + Attribute({ + name: "ParentChangeCount", id: 0x15, type: "uint16", access: "R V", conformance: "[MLECNT]", + default: 0, quality: "C", + details: "The ParentChangeCount attribute shall indicate the number of times a Node has changed its parent. " + + "This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.22" } + }), + + Attribute({ + name: "TxTotalCount", id: 0x16, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The TxTotalCount attribute shall indicate the total number of unique MAC frame transmission " + + "requests. The TxTotalCount attribute shall only be incremented by 1 for each MAC transmission " + + "request regardless of the amount of CCA failures, CSMA-CA attempts, or retransmissions. This value " + + "shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.23" } + }), + + Attribute({ + name: "TxUnicastCount", id: 0x17, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The TxUnicastCount attribute shall indicate the total number of unique unicast MAC frame " + + "transmission requests. The TxUnicastCount attribute shall only be incremented by 1 for each unicast " + + "MAC transmission request regardless of the amount of CCA failures, CSMA-CA attempts, or " + + "retransmissions. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.24" } + }), + + Attribute({ + name: "TxBroadcastCount", id: 0x18, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The TxBroadcastCount attribute shall indicate the total number of unique broadcast MAC frame " + + "transmission requests. The TxBroadcastCount attribute shall only be incremented by 1 for each " + + "broadcast MAC transmission request regardless of the amount of CCA failures, CSMA-CA attempts, or " + + "retransmissions. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.25" } + }), + + Attribute({ + name: "TxAckRequestedCount", id: 0x19, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The TxAckRequestedCount attribute shall indicate the total number of unique MAC frame transmission " + + "requests with requested acknowledgment. The TxAckRequestedCount attribute shall only be incremented " + + "by 1 for each MAC transmission request with requested acknowledgment regardless of the amount of " + + "CCA failures, CSMA-CA attempts, or retransmissions. This value shall only be reset upon a Node " + + "reboot.", + xref: { document: "core", section: "11.14.6.26" } + }), + + Attribute({ + name: "TxAckedCount", id: 0x1a, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The TxAckedCount attribute shall indicate the total number of unique MAC frame transmission " + + "requests that were acked. The TxAckedCount attribute shall only be incremented by 1 for each MAC " + + "transmission request that is acked regardless of the amount of CCA failures, CSMA-CA attempts, or " + + "retransmissions. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.27" } + }), + + Attribute({ + name: "TxNoAckRequestedCount", id: 0x1b, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The TxNoAckRequestedCount attribute shall indicate the total number of unique MAC frame" + + "\n" + + "transmission requests without requested acknowledgment. The TxNoAckRequestedCount attribute shall " + + "only be incremented by 1 for each MAC transmission request that is does not request acknowledgement " + + "regardless of the amount of CCA failures, CSMA-CA attempts, or retransmissions.", + xref: { document: "core", section: "11.14.6.28" } + }), + + Attribute({ + name: "TxDataCount", id: 0x1c, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The TxDataCount attribute shall indicate the total number of unique MAC Data frame transmission " + + "requests. The TxDataCount attribute shall only be incremented by 1 for each MAC Data frame " + + "transmission request regardless of the amount of CCA failures, CSMA-CA attempts, or " + + "retransmissions. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.29" } + }), + + Attribute({ + name: "TxDataPollCount", id: 0x1d, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The TxDataPollCount attribute shall indicate the total number of unique MAC Data Poll frame " + + "transmission requests. The TxDataPollCount attribute shall only be incremented by 1 for each MAC " + + "Data Poll frame transmission request regardless of the amount of CCA failures, CSMA-CA attempts, or " + + "retransmissions. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.30" } + }), + + Attribute({ + name: "TxBeaconCount", id: 0x1e, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The TxBeaconCount attribute shall indicate the total number of unique MAC Beacon frame transmission " + + "requests. The TxBeaconCount attribute shall only be incremented by 1 for each MAC Beacon frame " + + "transmission request regardless of the amount of CCA failures, CSMA-CA attempts, or retransmissions.", + xref: { document: "core", section: "11.14.6.31" } + }), + + Attribute({ + name: "TxBeaconRequestCount", id: 0x1f, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The TxBeaconRequestCount attribute shall indicate the total number of unique MAC Beacon Request " + + "frame transmission requests. The TxBeaconRequestCount attribute shall only be incremented by 1 for " + + "each MAC Beacon Request frame transmission request regardless of the amount of CCA failures, " + + "CSMA-CA attempts, or retransmissions. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.32" } + }), + + Attribute({ + name: "TxOtherCount", id: 0x20, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The TxOtherCount attribute shall indicate the total number of unique MAC frame transmission " + + "requests that are not counted by any other attribute. The TxOtherCount attribute shall only be " + + "incremented by 1 for each MAC frame transmission request regardless of the amount of CCA failures, " + + "CSMA-CA attempts, or retransmissions. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.33" } + }), + + Attribute({ + name: "TxRetryCount", id: 0x21, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The TxRetryCount attribute shall indicate the total number of MAC retransmission attempts. The " + + "TxRetryCount attribute shall only be incremented by 1 for each retransmission attempt that may be " + + "triggered by lack of acknowledgement, CSMA/CA failure, or other type of transmission error. This " + + "value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.34" } + }), + + Attribute({ + name: "TxDirectMaxRetryExpiryCount", id: 0x22, type: "uint32", access: "R V", + conformance: "[MACCNT]", default: 0, quality: "C", + + details: "The TxDirectMaxRetryExpiryCount attribute shall indicate the total number of unique MAC" + + "\n" + + "transmission packets that meet maximal retry limit for direct packets. The " + + "TxDirectMaxRetryExpiryCount attribute shall only be incremented by 1 for each unique MAC " + + "transmission packets that meets the maximal retry limit for direct packets. This value shall only " + + "be reset upon a Node reboot.", + + xref: { document: "core", section: "11.14.6.35" } + }), + + Attribute({ + name: "TxIndirectMaxRetryExpiryCount", id: 0x23, type: "uint32", access: "R V", + conformance: "[MACCNT]", default: 0, quality: "C", + details: "The TxIndirectMaxRetryExpiryCount attribute shall indicate the total number of unique MAC " + + "transmission packets that meet maximal retry limit for indirect packets. The " + + "TxIndirectMaxRetryExpiryCount attribute shall only be incremented by 1 for each unique MAC " + + "transmission packets that meets the maximal retry limit for indirect packets. This value shall only " + + "be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.36" } + }), + + Attribute({ + name: "TxErrCcaCount", id: 0x24, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The TxErrCcaCount attribute shall indicate the total number of CCA failures. The TxErrCcaCount " + + "attribute shall only be incremented by 1 for each instance of a CCA failure. This value shall only " + + "be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.37" } + }), + + Attribute({ + name: "TxErrAbortCount", id: 0x25, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The TxErrAbortCount attribute shall indicate the total number of unique MAC transmission request " + + "failures caused by an abort error. The TxErrAbortCount attribute shall only be incremented by 1 for " + + "each unique MAC transmission request failure caused by an abort error.", + xref: { document: "core", section: "11.14.6.38" } + }), + + Attribute({ + name: "TxErrBusyChannelCount", id: 0x26, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The TxErrBusyChannelCount attribute shall indicate the total number of unique MAC transmission " + + "request failures caused by an error as the result of a busy channel (a CSMA/CA fail). The " + + "TxErrBusyChannelCount attribute shall only be incremented by 1 for each unique MAC transmission " + + "request failure caused by a busy channel such as a CSMA/CA failure.", + xref: { document: "core", section: "11.14.6.39" } + }), + + Attribute({ + name: "RxTotalCount", id: 0x27, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The RxTotalCount attribute shall indicate the total number of received unique MAC frames. This " + + "value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.40" } + }), + + Attribute({ + name: "RxUnicastCount", id: 0x28, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxUnicastCount attribute shall indicate the total number of received unique unicast MAC frames. " + + "This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.41" } + }), + + Attribute({ + name: "RxBroadcastCount", id: 0x29, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxBroadcastCount attribute shall indicate the total number of received unique broadcast MAC " + + "frames. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.42" } + }), + + Attribute({ + name: "RxDataCount", id: 0x2a, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The RxDataCount attribute shall indicate the total number of received unique MAC Data frames." + + "\n" + + "This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.43" } + }), + + Attribute({ + name: "RxDataPollCount", id: 0x2b, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxDataPollCount attribute shall indicate the total number of received unique MAC Data Poll " + + "frames. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.44" } + }), + + Attribute({ + name: "RxBeaconCount", id: 0x2c, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The RxBeaconCount attribute shall indicate the total number of received unique MAC Beacon frames. " + + "This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.45" } + }), + + Attribute({ + name: "RxBeaconRequestCount", id: 0x2d, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxBeaconRequestCount attribute shall indicate the total number of received unique MAC Beacon " + + "Request frames. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.46" } + }), + + Attribute({ + name: "RxOtherCount", id: 0x2e, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The RxOtherCount attribute shall indicate the total number of received unique MAC frame requests " + + "that are not counted by any other attribute. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.47" } + }), + + Attribute({ + name: "RxAddressFilteredCount", id: 0x2f, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxAddressFilteredCount attribute shall indicate the total number of received unique MAC frame " + + "requests that have been dropped as a result of MAC filtering. This value shall only be reset upon a " + + "Node reboot.", + xref: { document: "core", section: "11.14.6.48" } + }), + + Attribute({ + name: "RxDestAddrFilteredCount", id: 0x30, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxDestAddrFilteredCount attribute shall indicate the total number of received unique MAC frame " + + "requests that have been dropped as a result of a destination address check. This value shall only " + + "be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.49" } + }), + + Attribute({ + name: "RxDuplicatedCount", id: 0x31, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxDuplicatedCount attribute shall indicate the total number of received MAC frame requests that " + + "have been dropped as a result of being a duplicate of a previously received MAC frame request. This " + + "value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.50" } + }), + + Attribute({ + name: "RxErrNoFrameCount", id: 0x32, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxErrNoFrameCount attribute shall indicate the total number of received unique MAC frame " + + "requests that have been dropped as a result of missing or malformed frame contents. This value " + + "shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.51" } + }), + + Attribute({ + name: "RxErrUnknownNeighborCount", id: 0x33, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxErrUnknownNeighborCount attribute shall indicate the total number of received unique MAC " + + "frame requests that have been dropped as a result of originating from an unknown neighbor" + + "\n" + + "device. This value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.52" } + }), + + Attribute({ + name: "RxErrInvalidSrcAddrCount", id: 0x34, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxErrInvalidSrcAddrCount attribute shall indicate the total number of received unique MAC frame " + + "requests that have been dropped as a result of containing an invalid source address. This value " + + "shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.53" } + }), + + Attribute({ + name: "RxErrSecCount", id: 0x35, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The RxErrSecCount attribute shall indicate the total number of received unique MAC frame requests " + + "that have been dropped as a result of an error with the security of the received frame. This value " + + "shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.54" } + }), + + Attribute({ + name: "RxErrFcsCount", id: 0x36, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, + quality: "C", + details: "The RxErrFcsCount attribute shall indicate the total number of received unique MAC frame requests " + + "that have been dropped as a result of an error with the FCS of the received frame. This value shall " + + "only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.55" } + }), + + Attribute({ + name: "RxErrOtherCount", id: 0x37, type: "uint32", access: "R V", conformance: "[MACCNT]", + default: 0, quality: "C", + details: "The RxErrOtherCount attribute shall indicate the total number of received unique MAC frame requests " + + "that have been dropped as a result of an error that is not counted by any other attribute. This " + + "value shall only be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.56" } + }), + + Attribute({ + name: "ActiveTimestamp", id: 0x38, type: "uint64", access: "R V", conformance: "O", default: 0, + quality: "X", + details: "Null when there is no dataset configured.", + xref: { document: "core", section: "11.14.6.57" } + }), + + Attribute({ + name: "PendingTimestamp", id: 0x39, type: "uint64", access: "R V", conformance: "O", default: 0, + quality: "X", + details: "Null when there is no dataset configured.", + xref: { document: "core", section: "11.14.6.58" } + }), + + Attribute({ + name: "Delay", id: 0x3a, type: "uint32", access: "R V", conformance: "O", default: 0, quality: "X", + details: "Null when there is no dataset configured.", + xref: { document: "core", section: "11.14.6.59" } + }), + + Attribute({ + name: "SecurityPolicy", id: 0x3b, type: "SecurityPolicy", access: "R V", conformance: "M", + quality: "X", + details: "The SecurityPolicy attribute indicates the current security policies for the Thread partition to " + + "which a Node is connected. Null when there is no dataset configured.", + xref: { document: "core", section: "11.14.6.60" } + }), + + Attribute({ + name: "ChannelPage0Mask", id: 0x3c, type: "octstr", access: "R V", conformance: "M", + constraint: "4", quality: "X", + details: "The ChannelPage0Mask attribute indicates the channels within channel page 0, in the 2.4GHz ISM " + + "band. The channels are represented in most significant bit order, with bit value 1 meaning " + + "selected, bit value 0 meaning unselected. For example, the most significant bit of the left-most " + + "byte indicates channel 0. If channel 0 and channel 10 are selected, the mask would be: 80 20 00 00. " + + "Null when there is no dataset configured.", + xref: { document: "core", section: "11.14.6.61" } + }), + + Attribute({ + name: "OperationalDatasetComponents", id: 0x3d, type: "OperationalDatasetComponents", access: "R V", + conformance: "M", quality: "X", + details: "The OperationalDatasetComponents attribute is a collection of flags to indicate the presence of " + + "various operationally acquired values.", + xref: { document: "core", section: "11.14.6.62" } + }), + + Attribute( + { + name: "ActiveNetworkFaultsList", id: 0x3e, type: "list", access: "R V", conformance: "M", + constraint: "max 4", + xref: { document: "core", section: "11.14.6" } + }, + Field({ name: "entry", type: "NetworkFaultEnum" }) + ), + + Attribute({ + name: "ExtAddress", id: 0x3f, type: "uint64", access: "R V", conformance: "P, M", quality: "X", + xref: { document: "core", section: "11.14.6" } + }), + Attribute({ + name: "Rloc16", id: 0x40, type: "uint16", access: "R V", conformance: "P, M", quality: "X", + xref: { document: "core", section: "11.14.6" } + }), + + Event( + { + name: "ConnectionStatus", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "The ConnectionStatus Event shall indicate that a Node’s connection status to a Thread network has " + + "changed.", + xref: { document: "core", section: "11.14.8.2" } + }, + + Field({ name: "ConnectionStatus", id: 0x0, type: "ConnectionStatusEnum", conformance: "M" }) + ), + + Event( + { + name: "NetworkFaultChange", id: 0x1, access: "V", conformance: "O", priority: "info", + details: "The NetworkFaultChange Event shall indicate a change in the set of network faults currently " + + "detected by the Node.", + xref: { document: "core", section: "11.14.8.1" } + }, + + Field( + { + name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 4", + details: "This field shall represent the set of faults currently detected, as per Section 11.14.5.1, " + + "“NetworkFaultEnum Type”.", + xref: { document: "core", section: "11.14.8.1.1" } + }, + + Field({ name: "entry", type: "NetworkFaultEnum" }) + ), + + Field( + { + name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 4", + details: "This field shall represent the set of faults detected prior to this change event, as per Section " + + "11.14.5.1, “NetworkFaultEnum Type”.", + xref: { document: "core", section: "11.14.8.1.2" } + }, + + Field({ name: "entry", type: "NetworkFaultEnum" }) + ) + ), + + Command({ + name: "ResetCounts", id: 0x0, access: "M", conformance: "ERRCNT", direction: "request", + response: "status", + + details: "Reception of this command shall reset the following attributes to 0:" + + "\n" + + " • OverrunCount" + + "\n" + + "This command has no associated data. Upon completion, this command shall send a status code set to " + + "a value of SUCCESS back to the initiator.", + + xref: { document: "core", section: "11.14.7.1" } + }), + + Datatype( + { name: "NetworkFaultEnum", type: "enum8", xref: { document: "core", section: "11.14.5.1" } }, + Field({ name: "Unspecified", id: 0x0, conformance: "M", description: "Indicates an unspecified fault." }), + Field({ name: "LinkDown", id: 0x1, conformance: "M", description: "Indicates the Thread link is down." }), + Field({ + name: "HardwareFailure", id: 0x2, conformance: "M", + description: "Indicates there has been Thread hardware failure." + }), + Field({ + name: "NetworkJammed", id: 0x3, conformance: "M", + description: "Indicates the Thread network is jammed." + }) + ), + + Datatype( + { name: "ConnectionStatusEnum", type: "enum8", xref: { document: "core", section: "11.14.5.2" } }, + Field({ name: "Connected", id: 0x0, conformance: "M", description: "Node is connected" }), + Field({ name: "NotConnected", id: 0x1, conformance: "M", description: "Node is not connected" }) + ), + + Datatype( + { name: "RoutingRoleEnum", type: "enum8", xref: { document: "core", section: "11.14.5.3" } }, + Field({ name: "Unspecified", id: 0x0, conformance: "M", description: "Unspecified routing role." }), + Field({ + name: "Unassigned", id: 0x1, conformance: "M", + description: "The Node does not currently have a role as a result of the Thread interface not currently being configured or operational." + }), + Field({ + name: "SleepyEndDevice", id: 0x2, conformance: "M", + description: "The Node acts as a Sleepy End Device with RX-off-when-idle sleepy radio behavior." + }), + Field({ + name: "EndDevice", id: 0x3, conformance: "M", + description: "The Node acts as an End Device without RX- off-when-idle sleepy radio behavior." + }), + Field({ name: "Reed", id: 0x4, conformance: "M", description: "The Node acts as an Router Eligible End Device." }), + Field({ name: "Router", id: 0x5, conformance: "M", description: "The Node acts as a Router Device." }), + Field({ name: "Leader", id: 0x6, conformance: "M", description: "The Node acts as a Leader Device." }) + ), + + Datatype( + { name: "NeighborTableStruct", type: "struct", xref: { document: "core", section: "11.14.5.4" } }, + Field({ + name: "ExtAddress", id: 0x0, type: "uint64", conformance: "M", + details: "This field shall specify the IEEE 802.15.4 extended address for the neighboring Node.", + xref: { document: "core", section: "11.14.5.4.1" } + }), + + Field({ + name: "Age", id: 0x1, type: "uint32", conformance: "M", + details: "This field shall specify the duration of time, in seconds, since a frame has been received from the " + + "neighboring Node.", + xref: { document: "core", section: "11.14.5.4.2" } + }), + + Field({ + name: "Rloc16", id: 0x2, type: "uint16", conformance: "M", + details: "This field shall specify the RLOC16 of the neighboring Node.", + xref: { document: "core", section: "11.14.5.4.3" } + }), + + Field({ + name: "LinkFrameCounter", id: 0x3, type: "uint32", conformance: "M", + details: "This field shall specify the number of link layer frames that have been received from the " + + "neighboring node. This field shall be reset to 0 upon a reboot of the Node.", + xref: { document: "core", section: "11.14.5.4.4" } + }), + + Field({ + name: "MleFrameCounter", id: 0x4, type: "uint32", conformance: "M", + details: "This field shall specify the number of Mesh Link Establishment frames that have been received from " + + "the neighboring node. This field shall be reset to 0 upon a reboot of the Node.", + xref: { document: "core", section: "11.14.5.4.5" } + }), + + Field({ + name: "Lqi", id: 0x5, type: "uint8", conformance: "M", constraint: "0 to 255", + details: "This field shall specify the implementation specific mix of IEEE 802.15.4 PDU receive quality " + + "indicators, scaled from 0 to 255.", + xref: { document: "core", section: "11.14.5.4.6" } + }), + + Field({ + name: "AverageRssi", id: 0x6, type: "int8", conformance: "M", constraint: "-128 to 0", + default: null, quality: "X", + details: "This field SHOULD specify the average RSSI across all received frames from the neighboring Node " + + "since the receiving Node’s last reboot. If there is no known received frames this field SHOULD have " + + "the value of null. This field shall have the units of dBm, having the range -128 dBm to 0 dBm.", + xref: { document: "core", section: "11.14.5.4.7" } + }), + + Field({ + name: "LastRssi", id: 0x7, type: "int8", conformance: "M", constraint: "-128 to 0", default: null, + quality: "X", + details: "This field shall specify the RSSI of the most recently received frame from the neighboring Node. If " + + "there is no known last received frame the LastRssi field SHOULD have the value of null. This field " + + "shall have the units of dBm, having the range -128 dBm to 0 dBm.", + xref: { document: "core", section: "11.14.5.4.8" } + }), + + Field({ + name: "FrameErrorRate", id: 0x8, type: "uint8", conformance: "M", constraint: "0 to 100", + default: 0, + details: "This field shall specify the percentage of received frames from the neighboring Node that have " + + "resulted in errors.", + xref: { document: "core", section: "11.14.5.4.9" } + }), + + Field({ + name: "MessageErrorRate", id: 0x9, type: "uint8", conformance: "M", constraint: "0 to 100", + default: 0, + details: "This field shall specify the percentage of received messages from the neighboring Node that have " + + "resulted in errors.", + xref: { document: "core", section: "11.14.5.4.10" } + }), + + Field({ + name: "RxOnWhenIdle", id: 0xa, type: "bool", conformance: "M", + details: "This field shall specify if the neighboring Node is capable of receiving frames while the Node is " + + "in an idle state.", + xref: { document: "core", section: "11.14.5.4.11" } + }), + + Field({ + name: "FullThreadDevice", id: 0xb, type: "bool", conformance: "M", + details: "This field shall specify if the neighboring Node is a full Thread device.", + xref: { document: "core", section: "11.14.5.4.12" } + }), + + Field({ + name: "FullNetworkData", id: 0xc, type: "bool", conformance: "M", + details: "This field shall specify if the neighboring Node requires the full Network Data. If set to False, " + + "the neighboring Node only requires the stable Network Data.", + xref: { document: "core", section: "11.14.5.4.13" } + }), + + Field({ + name: "IsChild", id: 0xd, type: "bool", conformance: "M", + details: "This field shall specify if the neighboring Node is a direct child of the Node reporting the " + + "NeighborTable attribute.", + xref: { document: "core", section: "11.14.5.4.14" } + }) + ), + + Datatype( + { name: "RouteTableStruct", type: "struct", xref: { document: "core", section: "11.14.5.5" } }, + + Field({ + name: "ExtAddress", id: 0x0, type: "uint64", conformance: "M", + details: "This field shall specify the IEEE 802.15.4 extended address for the Node for which this route table " + + "entry corresponds.", + xref: { document: "core", section: "11.14.5.5.1" } + }), + + Field({ + name: "Rloc16", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall specify the RLOC16 for the Node for which this route table entry corresponds.", + xref: { document: "core", section: "11.14.5.5.2" } + }), + Field({ + name: "RouterId", id: 0x2, type: "uint8", conformance: "M", + details: "This field shall specify the Router ID for the Node for which this route table entry corresponds.", + xref: { document: "core", section: "11.14.5.5.3" } + }), + + Field({ + name: "NextHop", id: 0x3, type: "uint8", conformance: "M", + details: "This field shall specify the Router ID for the next hop in the route to the Node for which this " + + "route table entry corresponds.", + xref: { document: "core", section: "11.14.5.5.4" } + }), + + Field({ + name: "PathCost", id: 0x4, type: "uint8", conformance: "M", + details: "This Field shall specify the cost of the route to the Node for which this route table entry " + + "corresponds.", + xref: { document: "core", section: "11.14.5.5.5" } + }), + + Field({ + name: "LqiIn", id: 0x5, type: "uint8", conformance: "M", + details: "This field shall specify the implementation specific mix of IEEE 802.15.4 PDU receive quality " + + "indicators, scaled from 0 to 255, from the perspective of the Node reporting the neighbor table.", + xref: { document: "core", section: "11.14.5.5.6" } + }), + + Field({ + name: "LqiOut", id: 0x6, type: "uint8", conformance: "M", + details: "This field shall specify the implementation specific mix of IEEE 802.15.4 PDU receive quality " + + "indicators, scaled from 0 to 255, from the perspective of the Node specified within the NextHop " + + "field.", + xref: { document: "core", section: "11.14.5.5.7" } + }), + + Field({ + name: "Age", id: 0x7, type: "uint8", conformance: "M", + details: "This field shall specify the duration of time, in seconds, since a frame has been received from the " + + "Node for which this route table entry corresponds.", + xref: { document: "core", section: "11.14.5.5.8" } + }), + + Field({ + name: "Allocated", id: 0x8, type: "bool", conformance: "M", + details: "This field shall specify if the router ID as defined within the RouterId field has been allocated.", + xref: { document: "core", section: "11.14.5.5.9" } + }), + + Field({ + name: "LinkEstablished", id: 0x9, type: "bool", conformance: "M", + details: "This field shall specify if a link has been established to the Node for which this route table " + + "entry corresponds.", + xref: { document: "core", section: "11.14.5.5.10" } + }) + ), + + Datatype( + { name: "SecurityPolicy", type: "struct", xref: { document: "core", section: "11.14.5.6" } }, + + Field({ + name: "RotationTime", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall specify the interval of time, in hours, that Thread security keys are rotated. " + + "Null when there is no dataset configured.", + xref: { document: "core", section: "11.14.5.6.1" } + }), + + Field({ + name: "Flags", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall specify the flags as specified in Thread 1.3.0 section 8.10.1.15. Null when there " + + "is no dataset configured.", + xref: { document: "core", section: "11.14.5.6.2" } + }) + ), + + Datatype( + { name: "OperationalDatasetComponents", type: "struct", xref: { document: "core", section: "11.14.5.7" } }, + Field({ + name: "ActiveTimestampPresent", id: 0x0, type: "bool", conformance: "M", + details: "This field shall be True if the Node has an active timestamp present, else False.", + xref: { document: "core", section: "11.14.5.7.1" } + }), + Field({ + name: "PendingTimestampPresent", id: 0x1, type: "bool", conformance: "M", + details: "This field shall be True if the Node has a pending timestamp is present, else False.", + xref: { document: "core", section: "11.14.5.7.2" } + }), + Field({ + name: "MasterKeyPresent", id: 0x2, type: "bool", conformance: "M", + details: "This field shall be True if the Node has the Thread master key, else False.", + xref: { document: "core", section: "11.14.5.7.3" } + }), + Field({ + name: "NetworkNamePresent", id: 0x3, type: "bool", conformance: "M", + details: "This field shall be True if the Node has the Thread network’s name, else False.", + xref: { document: "core", section: "11.14.5.7.4" } + }), + Field({ + name: "ExtendedPanIdPresent", id: 0x4, type: "bool", conformance: "M", + details: "This field shall be True if the Node has an extended Pan ID, else False.", + xref: { document: "core", section: "11.14.5.7.5" } + }), + Field({ + name: "MeshLocalPrefixPresent", id: 0x5, type: "bool", conformance: "M", + details: "This field shall be True if the Node has the mesh local prefix, else False.", + xref: { document: "core", section: "11.14.5.7.6" } + }), + Field({ + name: "DelayPresent", id: 0x6, type: "bool", conformance: "M", + details: "This field shall be True if the Node has the Thread network delay set, else False.", + xref: { document: "core", section: "11.14.5.7.7" } + }), + Field({ + name: "PanIdPresent", id: 0x7, type: "bool", conformance: "M", + details: "This field shall be True if the Node has a Pan ID, else False.", + xref: { document: "core", section: "11.14.5.7.8" } + }), + + Field({ + name: "ChannelPresent", id: 0x8, type: "bool", conformance: "M", + details: "This field shall be True if the Node has configured an operational channel for the Thread network, " + + "else False.", + xref: { document: "core", section: "11.14.5.7.9" } + }), + + Field({ + name: "PskcPresent", id: 0x9, type: "bool", conformance: "M", + details: "This field shall be True if the Node has been configured with the Thread network Pskc, else False.", + xref: { document: "core", section: "11.14.5.7.10" } + }), + + Field({ + name: "SecurityPolicyPresent", id: 0xa, type: "bool", conformance: "M", + details: "This field shall be True if the Node has been configured with the Thread network security policies, " + + "else False.", + xref: { document: "core", section: "11.14.5.7.11" } + }), + + Field({ + name: "ChannelMaskPresent", id: 0xb, type: "bool", conformance: "M", + details: "This field shall be True if the Node has available a mask of available channels, else False.", + xref: { document: "core", section: "11.14.5.7.12" } + }) + ) + ), + + Cluster( + { + name: "WiFiNetworkDiagnostics", id: 0x36, classification: "node", pics: "DGWIFI", quality: "K", + details: "The Wi-Fi Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics " + + "that may be used by a Node to assist a user or Administrator in diagnosing potential problems. The " + + "Wi-Fi Network Diagnostics Cluster attempts to centralize all metrics that are relevant to a " + + "potential Wi-Fi radio running on a Node.", + xref: { document: "core", section: "11.15" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.15.4" } }, + Field({ + name: "PKTCNT", constraint: "0", description: "PacketCounts", + details: "Node makes available the counts for the number of received and transmitted packets on the Wi-Fi " + + "interface." + }), + Field({ + name: "ERRCNT", constraint: "1", description: "ErrorCounts", + details: "Node makes available the counts for the number of errors that have occurred during the reception " + + "and transmission of packets on the Wi-Fi interface." + }) + ), + + Attribute({ + name: "Bssid", id: 0x0, type: "octstr", access: "R V", conformance: "M", constraint: "6", + default: null, quality: "X", + details: "The BSSID attribute shall indicate the BSSID for which the Wi-Fi network the Node is currently " + + "connected.", + xref: { document: "core", section: "11.15.6.1" } + }), + + Attribute({ + name: "SecurityType", id: 0x1, type: "SecurityTypeEnum", access: "R V", conformance: "M", + default: null, quality: "X", + details: "The SecurityType attribute shall indicate the current type of Wi-Fi security used.", + xref: { document: "core", section: "11.15.6.2" } + }), + + Attribute({ + name: "WiFiVersion", id: 0x2, type: "WiFiVersionEnum", access: "R V", conformance: "M", + default: null, quality: "X", + details: "The WiFiVersion attribute shall indicate the current 802.11 standard version in use by the Node, " + + "per the table below.", + xref: { document: "core", section: "11.15.6.3" } + }), + + Attribute({ + name: "ChannelNumber", id: 0x3, type: "uint16", access: "R V", conformance: "M", default: null, + quality: "X", + details: "The ChannelNumber attribute shall indicate the channel that Wi-Fi communication is currently " + + "operating on.", + xref: { document: "core", section: "11.15.6.4" } + }), + + Attribute({ + name: "Rssi", id: 0x4, type: "int8", access: "R V", conformance: "M", constraint: "-120 to 0", + default: null, quality: "X C", + details: "The RSSI attribute shall indicate the current RSSI of the Node’s Wi-Fi radio in dBm.", + xref: { document: "core", section: "11.15.6.5" } + }), + + Attribute({ + name: "BeaconLostCount", id: 0x5, type: "uint32", access: "R V", conformance: "ERRCNT", default: 0, + quality: "X C", + details: "The BeaconLostCount attribute shall indicate the count of the number of missed beacons the Node has " + + "detected. If the Node does not have an ability to count beacons expected and not received, this " + + "value may remain set to zero.", + xref: { document: "core", section: "11.15.6.6" } + }), + + Attribute({ + name: "BeaconRxCount", id: 0x6, type: "uint32", access: "R V", conformance: "PKTCNT", default: 0, + quality: "X C", + details: "The BeaconRxCount attribute shall indicate the count of the number of received beacons. The total " + + "number of expected beacons that could have been received during the interval since association " + + "SHOULD match the sum of BeaconRxCount and BeaconLostCount. If the Node does not have an ability to " + + "report count of beacons received, this value may remain set to zero.", + xref: { document: "core", section: "11.15.6.7" } + }), + + Attribute({ + name: "PacketMulticastRxCount", id: 0x7, type: "uint32", access: "R V", conformance: "PKTCNT", + default: 0, quality: "X C", + details: "The PacketMulticastRxCount attribute shall indicate the number of multicast packets received by the " + + "Node.", + xref: { document: "core", section: "11.15.6.8" } + }), + + Attribute({ + name: "PacketMulticastTxCount", id: 0x8, type: "uint32", access: "R V", conformance: "PKTCNT", + default: 0, quality: "X C", + details: "The PacketMulticastTxCount attribute shall indicate the number of multicast packets transmitted by " + + "the Node.", + xref: { document: "core", section: "11.15.6.9" } + }), + + Attribute({ + name: "PacketUnicastRxCount", id: 0x9, type: "uint32", access: "R V", conformance: "PKTCNT", + default: 0, quality: "X C", + details: "The PacketUnicastRxCount attribute shall indicate the number of unicast packets received by the " + + "Node.", + xref: { document: "core", section: "11.15.6.10" } + }), + + Attribute({ + name: "PacketUnicastTxCount", id: 0xa, type: "uint32", access: "R V", conformance: "PKTCNT", + default: 0, quality: "X C", + details: "The PacketUnicastTxCount attribute shall indicate the number of unicast packets transmitted by the " + + "Node.", + xref: { document: "core", section: "11.15.6.11" } + }), + + Attribute({ + name: "CurrentMaxRate", id: 0xb, type: "uint64", access: "R V", conformance: "O", default: 0, + quality: "X C", + details: "The CurrentMaxRate attribute shall indicate the current maximum PHY rate of transfer of data in " + + "bits-per-second.", + xref: { document: "core", section: "11.15.6.12" } + }), + + Attribute({ + name: "OverrunCount", id: 0xc, type: "uint64", access: "R V", conformance: "ERRCNT", default: 0, + quality: "X C", + details: "The OverrunCount attribute shall indicate the number of packets dropped either at ingress or " + + "egress, due to lack of buffer memory to retain all packets on the network interface. The " + + "OverrunCount attribute shall be reset to 0 upon a reboot of the Node.", + xref: { document: "core", section: "11.15.6.13" } + }), + + Event( + { + name: "Disconnection", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "The Disconnection Event shall indicate that a Node’s Wi-Fi connection has been disconnected as a " + + "result of de-authenticated or dis-association and indicates the reason.", + xref: { document: "core", section: "11.15.8.1" } + }, + + Field({ + name: "ReasonCode", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall contain the Reason Code field value for the Disassociation or Deauthentication " + + "event that caused the disconnection and the value shall align with Table 9-49 \"Reason codes\" of " + + "IEEE 802.11-2020.", + xref: { document: "core", section: "11.15.8.1.1" } + }) + ), + + Event( + { + name: "AssociationFailure", id: 0x1, access: "V", conformance: "O", priority: "info", + details: "The AssociationFailure event shall indicate that a Node has attempted to connect, or reconnect, to " + + "a Wi-Fi access point, but is unable to successfully associate or authenticate, after exhausting all " + + "internal retries of its supplicant.", + xref: { document: "core", section: "11.15.8.2" } + }, + + Field({ + name: "AssociationFailureCause", id: 0x0, type: "AssociationFailureCauseEnum", conformance: "M", + details: "The Status field shall be set to a value from the AssociationFailureCauseEnum.", + xref: { document: "core", section: "11.15.8.2.1" } + }), + + Field({ + name: "Status", id: 0x1, type: "uint16", conformance: "M", + + details: "The Status field shall be set to the Status Code value that was present in the last frame related " + + "to association where Status Code was not equal to zero and which caused the failure of a last trial " + + "attempt, if this last failure was due to one of the following Management frames:" + + "\n" + + " • Association Response (Type 0, Subtype 1)" + + "\n" + + " • Reassociation Response (Type 0, Subtype 3)" + + "\n" + + " • Authentication (Type 0, Subtype 11)" + + "\n" + + "Table 9-50 \"Status codes\" of IEEE 802.11-2020 contains a description of all values possible.", + + xref: { document: "core", section: "11.15.8.2.2" } + }) + ), + + Event( + { + name: "ConnectionStatus", id: 0x2, access: "V", conformance: "O", priority: "info", + details: "The ConnectionStatus Event shall indicate that a Node’s connection status to a Wi-Fi network has " + + "changed. Connected, in this context, shall mean that a Node acting as a Wi-Fi station is " + + "successfully associated to a Wi-Fi Access Point.", + xref: { document: "core", section: "11.15.8.3" } + }, + + Field({ name: "ConnectionStatus", id: 0x0, type: "ConnectionStatusEnum", conformance: "M" }) + ), + + Command({ + name: "ResetCounts", id: 0x0, access: "O", conformance: "ERRCNT", direction: "request", + response: "status", + + details: "Reception of this command shall reset the following attributes to 0:" + + "\n" + + " • BeaconLostCount" + + "\n" + + " • BeaconRxCount" + + "\n" + + " • PacketMulticastRxCount" + + "\n" + + " • PacketMulticastTxCount" + + "\n" + + " • PacketUnicastRxCount" + + "\n" + + " • PacketUnicastTxCount" + + "\n" + + "This command has no associated data.", + + xref: { document: "core", section: "11.15.7.1" } + }), + + Datatype( + { name: "SecurityTypeEnum", type: "enum8", xref: { document: "core", section: "11.15.5.1" } }, + Field({ + name: "Unspecified", id: 0x0, conformance: "M", + description: "Indicate the usage of an unspecified Wi-Fi security type" + }), + Field({ name: "None", id: 0x1, conformance: "M", description: "Indicate the usage of no Wi-Fi security" }), + Field({ name: "Wep", id: 0x2, conformance: "M", description: "Indicate the usage of WEP Wi-Fi security" }), + Field({ name: "Wpa", id: 0x3, conformance: "M", description: "Indicate the usage of WPA Wi-Fi security" }), + Field({ name: "Wpa2", id: 0x4, conformance: "M", description: "Indicate the usage of WPA2 Wi-Fi security" }), + Field({ name: "Wpa3", id: 0x5, conformance: "M", description: "Indicate the usage of WPA3 Wi-Fi security" }) + ), + + Datatype( + { name: "WiFiVersionEnum", type: "enum8", xref: { document: "core", section: "11.15.5.2" } }, + Field({ + name: "A", id: 0x0, conformance: "M", + description: "Indicate the network interface is currently using 802.11a against the wireless access point." + }), + Field({ + name: "B", id: 0x1, conformance: "M", + description: "Indicate the network interface is currently using 802.11b against the wireless access point." + }), + Field({ + name: "G", id: 0x2, conformance: "M", + description: "Indicate the network interface is currently using 802.11g against the wireless access point." + }), + Field({ + name: "N", id: 0x3, conformance: "M", + description: "Indicate the network interface is currently using 802.11n against the wireless access point." + }), + Field({ + name: "Ac", id: 0x4, conformance: "M", + description: "Indicate the network interface is currently using 802.11ac against the wireless access point." + }), + Field({ + name: "Ax", id: 0x5, conformance: "M", + description: "Indicate the network interface is currently using 802.11ax against the wireless access point." + }), + Field({ + name: "Ah", id: 0x6, conformance: "M", + description: "Indicate the network interface is currently using 802.11ah against the wireless access point." + }) + ), + + Datatype( + { name: "AssociationFailureCauseEnum", type: "enum8", xref: { document: "core", section: "11.15.5.3" } }, + Field({ name: "Unknown", id: 0x0, conformance: "M", description: "The reason for the failure is unknown." }), + Field({ + name: "AssociationFailed", id: 0x1, conformance: "M", + description: "An error occurred during association." + }), + Field({ + name: "AuthenticationFailed", id: 0x2, conformance: "M", + description: "An error occurred during authentication." + }), + Field({ name: "SsidNotFound", id: 0x3, conformance: "M", description: "The specified SSID could not be found." }) + ), + + Datatype( + { name: "ConnectionStatusEnum", type: "enum8", xref: { document: "core", section: "11.15.5.4" } }, + Field({ name: "Connected", id: 0x0, conformance: "M", description: "Indicate the node is connected" }), + Field({ name: "NotConnected", id: 0x1, conformance: "M", description: "Indicate the node is not connected" }) + ) + ), + + Cluster( + { + name: "EthernetNetworkDiagnostics", id: 0x37, classification: "node", pics: "DGETH", quality: "K", + details: "The Ethernet Network Diagnostics Cluster provides a means to acquire standardized diagnostics " + + "metrics that may be used by a Node to assist a user or Administrator in diagnosing potential " + + "problems. The Ethernet Network Diagnostics Cluster attempts to centralize all metrics that are " + + "relevant to a potential Ethernet connection to a Node.", + xref: { document: "core", section: "11.16" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.16.4" } }, + Field({ + name: "PKTCNT", constraint: "0", description: "PacketCounts", + details: "Node makes available the counts for the number of received and transmitted packets on the ethernet " + + "interface." + }), + Field({ + name: "ERRCNT", constraint: "1", description: "ErrorCounts", + details: "Node makes available the counts for the number of errors that have occurred during the reception " + + "and transmission of packets on the ethernet interface." + }) + ), + + Attribute({ + name: "PhyRate", id: 0x0, type: "PHYRateEnum", access: "R V", conformance: "O", default: null, + quality: "X", + details: "The PHYRate attribute shall indicate the current nominal, usable speed at the top of the physical " + + "layer of the Node. A value of null shall indicate that the interface is not currently configured or " + + "operational.", + xref: { document: "core", section: "11.16.6.1" } + }), + + Attribute({ + name: "FullDuplex", id: 0x1, type: "bool", access: "R V", conformance: "O", default: null, + quality: "X", + details: "The FullDuplex attribute shall indicate if the Node is currently utilizing the full-duplex " + + "operating mode. A value of null shall indicate that the interface is not currently configured or " + + "operational.", + xref: { document: "core", section: "11.16.6.2" } + }), + + Attribute({ + name: "PacketRxCount", id: 0x2, type: "uint64", access: "R V", conformance: "PKTCNT", default: 0, + quality: "C", + details: "The PacketRxCount attribute shall indicate the number of packets that have been received on the " + + "ethernet network interface. The PacketRxCount attribute shall be reset to 0 upon a reboot of the " + + "Node.", + xref: { document: "core", section: "11.16.6.3" } + }), + + Attribute({ + name: "PacketTxCount", id: 0x3, type: "uint64", access: "R V", conformance: "PKTCNT", default: 0, + quality: "C", + details: "The PacketTxCount attribute shall indicate the number of packets that have been successfully " + + "transferred on the ethernet network interface. The PacketTxCount attribute shall be reset to 0 upon " + + "a reboot of the Node.", + xref: { document: "core", section: "11.16.6.4" } + }), + + Attribute({ + name: "TxErrCount", id: 0x4, type: "uint64", access: "R V", conformance: "ERRCNT", default: 0, + quality: "C", + details: "The TxErrCount attribute shall indicate the number of failed packet transmissions that have " + + "occurred on the ethernet network interface. The TxErrCount attribute shall be reset to 0 upon a " + + "reboot of the Node.", + xref: { document: "core", section: "11.16.6.5" } + }), + + Attribute({ + name: "CollisionCount", id: 0x5, type: "uint64", access: "R V", conformance: "ERRCNT", default: 0, + quality: "C", + details: "The CollisionCount attribute shall indicate the number of collisions that have occurred while " + + "attempting to transmit a packet on the ethernet network interface. The CollisionCount attribute " + + "shall be reset to 0 upon a reboot of the Node.", + xref: { document: "core", section: "11.16.6.6" } + }), + + Attribute({ + name: "OverrunCount", id: 0x6, type: "uint64", access: "R V", conformance: "ERRCNT", default: 0, + quality: "C", + details: "The OverrunCount attribute shall indicate the number of packets dropped either at ingress or " + + "egress, due to lack of buffer memory to retain all packets on the ethernet network interface. The " + + "OverrunCount attribute shall be reset to 0 upon a reboot of the Node.", + xref: { document: "core", section: "11.16.6.7" } + }), + + Attribute({ + name: "CarrierDetect", id: 0x7, type: "bool", access: "R V", conformance: "O", default: null, + quality: "X C", + details: "The CarrierDetect attribute shall indicate the value of the Carrier Detect control signal present " + + "on the ethernet network interface. A value of null shall indicate that the interface is not " + + "currently configured or operational.", + xref: { document: "core", section: "11.16.6.8" } + }), + + Attribute({ + name: "TimeSinceReset", id: 0x8, type: "uint64", access: "R V", conformance: "O", default: 0, + quality: "C", + details: "The TimeSinceReset attribute shall indicate the duration of time, in minutes, that it has been " + + "since the ethernet network interface has reset for any reason.", + xref: { document: "core", section: "11.16.6.9" } + }), + + Command({ + name: "ResetCounts", id: 0x0, access: "M", conformance: "PKTCNT | ERRCNT", direction: "request", + response: "status", + + details: "Reception of this command shall reset the following attributes to 0:" + + "\n" + + " • PacketRxCount" + + "\n" + + " • PacketTxCount" + + "\n" + + " • TxErrCount" + + "\n" + + " • CollisionCount" + + "\n" + + " • OverrunCount" + + "\n" + + "This command has no associated data.", + + xref: { document: "core", section: "11.16.7.1" } + }), + + Datatype( + { name: "PHYRateEnum", type: "enum8", xref: { document: "core", section: "11.16.5.1" } }, + Field({ name: "Rate10M", id: 0x0, conformance: "M", description: "PHY rate is 10Mbps" }), + Field({ name: "Rate100M", id: 0x1, conformance: "M", description: "PHY rate is 100Mbps" }), + Field({ name: "Rate1G", id: 0x2, conformance: "M", description: "PHY rate is 1Gbps" }), + Field({ name: "Rate25G", id: 0x3, conformance: "M", description: "PHY rate is 2.5Gbps" }), + Field({ name: "Rate5G", id: 0x4, conformance: "M", description: "PHY rate is 5Gbps" }), + Field({ name: "Rate10G", id: 0x5, conformance: "M", description: "PHY rate is 10Gbps" }), + Field({ name: "Rate40G", id: 0x6, conformance: "M", description: "PHY rate is 40Gbps" }), + Field({ name: "Rate100G", id: 0x7, conformance: "M", description: "PHY rate is 100Gbps" }), + Field({ name: "Rate200G", id: 0x8, conformance: "M", description: "PHY rate is 200Gbps" }), + Field({ name: "Rate400G", id: 0x9, conformance: "M", description: "PHY rate is 400Gbps" }) + ) + ), + + Cluster( + { + name: "TimeSynchronization", id: 0x38, classification: "node", pics: "TIMESYNC", + + details: "Accurate time is required for a number of reasons, including scheduling, display and validating " + + "security materials." + + "\n" + + "This section describes a mechanism for Nodes to achieve and maintain time synchronization. The Time " + + "Synchronization cluster provides attributes for reading a Node’s current time. It also allows " + + "Administrators to set current time, time zone and daylight savings time (DST) settings." + + "\n" + + "The Time Synchronization cluster may be present on the root node endpoint, and shall NOT be present " + + "on any other Endpoint of any Node.", + + xref: { document: "core", section: "11.17" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.17.5" } }, + + Field({ + name: "TZ", constraint: "0", description: "TimeZone", + details: "Allows a server to translate a UTC time to a local time using the time zone and daylight savings " + + "time (DST) offsets. If a server supports the TimeZone feature, it shall support the SetTimeZone and " + + "SetDSTOffset commands, and TimeZone and DSTOffset attributes, and shall expose the local time " + + "through the LocalTime attribute.", + xref: { document: "core", section: "11.17.5.1" } + }), + + Field({ + name: "NTPC", constraint: "1", description: "NtpClient", + details: "Allows a node to use NTP/SNTP for time synchronization.", + xref: { document: "core", section: "11.17.5.2" } + }), + + Field({ + name: "NTPS", constraint: "2", description: "NtpServer", + details: "Allows a Node to host an NTP server for the network so that other Nodes can achieve a high accuracy " + + "time synchronization within the network. See Section 11.17.15, “Acting as an NTP Server”.", + xref: { document: "core", section: "11.17.5.3" } + }), + + Field({ + name: "TSC", constraint: "3", description: "TimeSyncClient", + details: "This node also supports a time synchronization client and can connect to and read time from other " + + "nodes.", + xref: { document: "core", section: "11.17.5.4" } + }) + ), + + Attribute({ + name: "UtcTime", id: 0x0, type: "epoch-us", access: "R V", conformance: "M", default: null, + quality: "X C", + details: "If the node has achieved time synchronization, this shall indicate the current time as a UTC " + + "epoch-us (Epoch Time in Microseconds)." + + "\n" + + "If the node has not achieved time synchronization, this shall be null. This attribute may be set " + + "when a SetUTCTime is received.", + xref: { document: "core", section: "11.17.8.1" } + }), + + Attribute({ + name: "Granularity", id: 0x1, type: "GranularityEnum", access: "R V", conformance: "M", + constraint: "desc", default: 0, + details: "The granularity of the error that the node is willing to guarantee on the time synchronization. It " + + "is of type GranularityEnum." + + "\n" + + "This value shall be set to NoTimeGranularity if UTCTime is null and shall NOT be set to " + + "NoTimeGranularity if UTCTime is non-null.", + xref: { document: "core", section: "11.17.8.2" } + }), + + Attribute({ + name: "TimeSource", id: 0x2, type: "TimeSourceEnum", access: "R V", conformance: "O", + constraint: "desc", default: 0, + + details: "The node’s time source. This attribute indicates what method the node is using to sync, whether the " + + "source uses NTS or not and whether the source is internal or external to the Matter network. This " + + "attribute may be used by a client to determine its level of trust in the UTCTime. It is of type " + + "TimeSourceEnum." + + "\n" + + "If a node is unsure if the selected NTP server is within the Matter network, it SHOULD select one " + + "of the NonMatter* values." + + "\n" + + "This value shall be set to None if UTCTime is null and shall NOT be set to None if UTCTime is " + + "non-null.", + + xref: { document: "core", section: "11.17.8.3" } + }), + + Attribute({ + name: "TrustedTimeSource", id: 0x3, type: "TrustedTimeSourceStruct", access: "R V", + conformance: "TSC", default: null, quality: "X N", + details: "A Node ID, endpoint, and associated fabric index of a Node that may be used as trusted time source. " + + "See Section 11.17.13, “Time source prioritization”. This attribute reflects the last value set by " + + "an administrator using the SetTrustedTimeSource command. If the value is null, no trusted time " + + "source has yet been set.", + xref: { document: "core", section: "11.17.8.4" } + }), + + Attribute({ + name: "DefaultNtp", id: 0x4, type: "string", access: "R V", conformance: "NTPC", + constraint: "max 128", default: null, quality: "X N", + + details: "The default NTP server that this Node may use if other time sources are unavailable. This attribute " + + "is settable by an Administrator using the SetDefaultNTP command. It SHOULD be set by the " + + "Commissioner during commissioning. If no default NTP server is available, the Commissioner may set " + + "this value to null. The default IANA assigned NTP port of 123 shall be used to access the NTP " + + "server." + + "\n" + + "If set, the format of this attribute shall be a domain name or a static IPv6 address with no port, " + + "in text format, as specified in RFC 5952. The address format shall follow the recommendations in " + + "Section 4 and shall NOT contain a port number.", + + xref: { document: "core", section: "11.17.8.5" } + }), + + Attribute( + { + name: "TimeZone", id: 0x5, type: "list", access: "R V", conformance: "TZ", constraint: "1 to 2", + default: "[{0,0}]", quality: "N", + + details: "A list of time zone offsets from UTC and when they shall take effect. This attribute uses a list of " + + "time offset configurations to allow Nodes to handle scheduled regulatory time zone changes. This " + + "attribute shall NOT be used to indicate daylight savings time changes (see DSTOffset attribute for " + + "daylight savings time)." + + "\n" + + "The first entry shall have a ValidAt entry of 0. If there is a second entry, it shall have a " + + "non-zero ValidAt time." + + "\n" + + "If a node supports a TimeZoneDatabase, and it has data for the given time zone Name and the given " + + "Offset matches, the node may update its own DSTOffset attribute to add new DST change times as " + + "required, based on the Name fields of the TimeZoneStruct. Administrators may add additional entries " + + "to the DSTOffset of other Nodes with the same time zone, if required." + + "\n" + + "If a node does not support a TimeZoneDatabase, the Name field of the TimeZoneStruct is only " + + "applicable for client-side localization. In particular:" + + "\n" + + " • If the node does not support a TimeZoneDatabase, the Name field shall NOT be used to calculate " + + " the local time." + + "\n" + + " • If the node does not support a TimeZoneDatabase, the Name field shall NOT be used to calculate " + + " DST start or end dates." + + "\n" + + "When time passes, the node SHOULD remove any entries which are no longer active and change the " + + "ValidAt time for the currently used TimeZoneStruct list item to zero." + + "\n" + + "This attribute shall have at least one entry. If the node does not have a default time zone and no " + + "time zone has been set, it may set this value to a list containing a single TimeZoneStruct with an " + + "offset of 0 (UTC) and a ValidAt time of 0.", + + xref: { document: "core", section: "11.17.8.6" } + }, + + Field({ name: "entry", type: "TimeZoneStruct" }) + ), + + Attribute( + { + name: "DstOffset", id: 0x6, type: "list", access: "R V", conformance: "TZ", default: [], + quality: "N", + + details: "A list of offsets to apply for daylight savings time, and their validity period. List entries shall " + + "be sorted by ValidStarting time." + + "\n" + + "A list entry shall NOT have a ValidStarting time that is smaller than the ValidUntil time of the " + + "previous entry. There shall be at most one list entry with a null ValidUntil time and, if such an " + + "entry is present, it shall appear last in the list." + + "\n" + + "Over time, the node SHOULD remove any entries which are no longer active from the list." + + "\n" + + "Over time, if the node supports a TimeZoneDatabase and it has information available for the given " + + "time zone name, it may update its own list to add additional entries." + + "\n" + + "If a time zone does not use DST, this shall be indicated by a single entry with a 0 offset and a " + + "null ValidUntil field.", + + xref: { document: "core", section: "11.17.8.7" } + }, + + Field({ name: "entry", type: "DSTOffsetStruct" }) + ), + + Attribute({ + name: "LocalTime", id: 0x7, type: "epoch-us", access: "R V", conformance: "TZ", default: null, + quality: "X C", + + details: "The computed current local time of the node as a epoch-us (Epoch Time in Microseconds). The value " + + "of LocalTime shall be the sum of the UTCTime, the offset of the currently valid TimeZoneStruct from " + + "the TimeZone attribute (converted to microseconds), and the offset of the currently valid " + + "DSTOffsetStruct from the DSTOffset attribute (converted to microseconds), if such an entry exists." + + "\n" + + "If the node has not achieved time synchronization, this shall be null. If the node has an empty " + + "DSTOffset, this shall be null.", + + xref: { document: "core", section: "11.17.8.8" } + }), + + Attribute({ + name: "TimeZoneDatabase", id: 0x8, type: "TimeZoneDatabaseEnum", access: "R V", conformance: "TZ", + default: 2, quality: "F", + details: "Indicates whether the node has access to a time zone database. Nodes with a time zone database may " + + "update their own DSTOffset attribute to add new entries and may push DSTOffset updates to other " + + "Nodes in the same time zone as required.", + xref: { document: "core", section: "11.17.8.9" } + }), + + Attribute({ + name: "NtpServerAvailable", id: 0x9, type: "bool", access: "R V", conformance: "NTPS", + default: false, + details: "If the node is running an RFC 5905 NTPv4 compliant server on port 123, this value shall be True. If " + + "the node is not currently running an NTP server, this value shall be False.", + xref: { document: "core", section: "11.17.8.10" } + }), + + Attribute({ + name: "TimeZoneListMaxSize", id: 0xa, type: "uint8", access: "R V", conformance: "TZ", + constraint: "1 to 2", quality: "F", + details: "Number of supported list entries in the TimeZone attribute. This attribute may take the value of 1 " + + "or 2, where the optional second list entry may be used to handle scheduled regulatory time zone " + + "changes.", + xref: { document: "core", section: "11.17.8.11" } + }), + + Attribute({ + name: "DstOffsetListMaxSize", id: 0xb, type: "uint8", access: "R V", conformance: "TZ", + constraint: "min 1", quality: "F", + details: "Number of supported list entries in DSTOffset attribute. This value must be at least 1.", + xref: { document: "core", section: "11.17.8.12" } + }), + + Attribute({ + name: "SupportsDnsResolve", id: 0xc, type: "bool", access: "R V", conformance: "NTPC", + default: false, quality: "F", + details: "This attribute is true if the node supports resolving a domain name. DefaultNTP Address values for " + + "these nodes may include domain names. If this is False, the Address for a DefaultNTP shall be an " + + "IPv6 address.", + xref: { document: "core", section: "11.17.8.13" } + }), + + Event({ + name: "DstTableEmpty", id: 0x0, access: "V", conformance: "TZ", priority: "info", + + details: "This event shall be generated when the node stops applying the current DSTOffset and there are no " + + "entries in the list with a larger ValidStarting time, indicating the need to possibly get new DST " + + "data. This event shall also be generated if the DSTOffset list is cleared either by a SetTimeZone " + + "command, or by a SetDSTOffset command with an empty list." + + "\n" + + "The node shall generate this event if the node has not generated a DSTTableEmpty event in the last " + + "hour, and the DSTOffset list is empty when the node attempts to update its time. DSTTableEmpty " + + "events corresponding to a time update SHOULD NOT be generated more often than once per hour." + + "\n" + + "There is no data for this event.", + + xref: { document: "core", section: "11.17.10.1" } + }), + + Event( + { + name: "DstStatus", id: 0x1, access: "V", conformance: "TZ", priority: "info", + details: "This event shall be generated when the node starts or stops applying a DST offset.", + xref: { document: "core", section: "11.17.10.2" } + }, + + Field({ + name: "DstOffsetActive", id: 0x0, type: "bool", conformance: "M", + details: "Indicates whether the current DST offset is being applied (i.e, daylight savings time is applied, " + + "as opposed to standard time).", + xref: { document: "core", section: "11.17.10.2.1" } + }) + ), + + Event( + { + name: "TimeZoneStatus", id: 0x2, access: "V", conformance: "TZ", priority: "info", + details: "This event shall be generated when the node changes its time zone offset or name. It shall NOT be " + + "sent for DST changes that are not accompanied by a time zone change.", + xref: { document: "core", section: "11.17.10.3" } + }, + + Field({ + name: "Offset", id: 0x0, type: "int32", conformance: "M", constraint: "-43200 to 50400", + details: "Current time zone offset from UTC in seconds.", + xref: { document: "core", section: "11.17.10.3.1" } + }), + + Field({ + name: "Name", id: 0x1, type: "string", conformance: "O", constraint: "0 to 64", + details: "Current time zone name. This name SHOULD use the country/city format specified by the IANA Time " + + "Zone Database.", + xref: { document: "core", section: "11.17.10.3.2" } + }) + ), + + Event({ + name: "TimeFailure", id: 0x3, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated if the node has not generated a TimeFailure event in the last hour, " + + "and the node is unable to get a time from any source. This event SHOULD NOT be generated more often " + + "than once per hour.", + xref: { document: "core", section: "11.17.10.4" } + }), + + Event({ + name: "MissingTrustedTimeSource", id: 0x4, access: "V", conformance: "TSC", priority: "info", + + details: "This event shall be generated if the TrustedTimeSource is set to null upon fabric removal or by a " + + "SetTrustedTimeSource command." + + "\n" + + "This event shall also be generated if the node has not generated a MissingTrustedTimeSource event " + + "in the last hour, and the node fails to update its time from the TrustedTimeSource because the " + + "TrustedTimeSource is null or the specified peer cannot be reached. MissingTrustedTimeSource events " + + "corresponding to a time update SHOULD NOT be generated more often than once per hour.", + + xref: { document: "core", section: "11.17.10.5" } + }), + + Command( + { + name: "SetUtcTime", id: 0x0, access: "A", conformance: "M", direction: "request", + response: "status", + + details: "This command may be issued by Administrator to set the time. If the Commissioner does not have a " + + "valid time source, it may send a Granularity of NoTimeGranularity." + + "\n" + + "Upon receipt of this command, the node may update its UTCTime attribute to match the time specified " + + "in the command, if the stated Granularity and TimeSource are acceptable. The node shall" + + "\n" + + "update its UTCTime attribute if its current Granularity is NoTimeGranularity." + + "\n" + + "If the time is updated, the node shall also update its Granularity attribute based on the " + + "granularity specified in the command and the expected clock drift of the node. This SHOULD normally " + + "be one level lower than the stated command Granularity. It shall also update its TimeSource " + + "attribute to Admin. It shall also update its Last Known Good UTC Time as defined in Section " + + "3.5.6.1, “Last Known Good UTC Time”." + + "\n" + + "If the node updates its UTCTime attribute, it shall accept the command with a status code of " + + "SUCCESS. If it opts to not update its time, it shall fail the command with a cluster specific " + + "Status Code of TimeNotAccepted.", + + xref: { document: "core", section: "11.17.9.1" } + }, + + Field({ + name: "UtcTime", id: 0x0, type: "epoch-us", conformance: "M", default: 0, + details: "This shall give the Client’s UTC Time.", + xref: { document: "core", section: "11.17.9.1.1" } + }), + Field({ + name: "Granularity", id: 0x1, type: "GranularityEnum", conformance: "M", default: 0, + details: "This shall give the Client’s Granularity, as described in Granularity.", + xref: { document: "core", section: "11.17.9.1.2" } + }), + Field({ + name: "TimeSource", id: 0x2, type: "TimeSourceEnum", conformance: "O", default: 0, + details: "This shall give the Client’s TimeSource, as described in TimeSource.", + xref: { document: "core", section: "11.17.9.1.3" } + }) + ), + + Command( + { + name: "SetTrustedTimeSource", id: 0x1, access: "F A", conformance: "TSC", direction: "request", + response: "status", + + details: "This command shall set the TrustedTimeSource attribute. Upon receipt of this command:" + + "\n" + + " • If the TrustedTimeSource field in the command is null, the node shall set the TrustedTimeSource " + + " attribute to null and shall generate a MissingTrustedTimeSource event." + + "\n" + + " • Otherwise, the node shall set the TrustedTimeSource attribute to a struct which has NodeID and " + + " Endpoint fields matching those in the TrustedTimeSource field and has its FabricIndex field set " + + " to the command’s accessing fabric index.", + + xref: { document: "core", section: "11.17.9.2" } + }, + + Field({ + name: "TrustedTimeSource", id: 0x0, type: "FabricScopedTrustedTimeSourceStruct", access: "F", + conformance: "M", quality: "X", + details: "This field contains the Node ID and endpoint of a trusted time source on the accessing fabric.", + xref: { document: "core", section: "11.17.9.2.1" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Command( + { + name: "SetTimeZone", id: 0x2, access: "M", conformance: "TZ", direction: "request", + response: "SetTimeZoneResponse", + + details: "This command is used to set the time zone of the node." + + "\n" + + "If the given list is larger than the TimeZoneListMaxSize, the node shall respond with " + + "RESOURCE_EXHAUSTED and the TimeZone attribute shall NOT be updated." + + "\n" + + "If the given list does not conform to the list requirements in TimeZone attribute the node shall " + + "respond with a CONSTRAINT_ERROR and the TimeZone attribute shall NOT be updated." + + "\n" + + "If there are no errors in the list, the TimeZone field shall be copied to the TimeZone attribute. A " + + "TimeZoneStatus event shall be generated with the new time zone information." + + "\n" + + "If the node supports a time zone database and it has information available for the time zone that " + + "will be applied, it may set its DSTOffset attribute, otherwise the DSTOffset attribute shall be set " + + "to an empty list. A DSTTableEmpty event shall be generated if the DSTOffset attribute is empty. A " + + "DSTStatus event shall be generated if the node was previously applying a DST offset.", + + xref: { document: "core", section: "11.17.9.3" } + }, + + Field( + { name: "TimeZone", id: 0x0, type: "list", conformance: "M", constraint: "1 to 2" }, + Field({ name: "entry", type: "TimeZoneStruct" }) + ) + ), + + Command( + { + name: "SetTimeZoneResponse", id: 0x3, conformance: "TZ", direction: "response", + details: "This command shall be generated in response to a SetTimeZone command.", + xref: { document: "core", section: "11.17.9.4" } + }, + + Field({ + name: "DstOffsetsRequired", id: 0x0, type: "bool", conformance: "M", default: true, + details: "If the node supports a time zone database with information for the time zone that will be applied, " + + "it may use this information to set the DSTOffset attribute. If the node is setting its own " + + "DSTOffset attribute, the DSTOffsetsRequired field shall be set to false, otherwise it shall be set " + + "to true.", + xref: { document: "core", section: "11.17.9.4.1" } + }) + ), + + Command( + { + name: "SetDstOffset", id: 0x4, access: "M", conformance: "TZ", direction: "request", + response: "status", + + details: "This command is used to set the DST offsets for a node." + + "\n" + + " • If the length of DSTOffset is larger than DSTOffsetListMaxSize, the node shall respond with" + + "\n" + + "RESOURCE_EXHAUSTED." + + "\n" + + " • Else if the list entries do not conform to the list requirements for DSTOffset attribute, the " + + " node shall respond with CONSTRAINT_ERROR." + + "\n" + + "If there are no errors in the list, the DSTOffset field shall be copied to the DSTOffset attribute." + + "\n" + + "If the DSTOffset attribute change causes a corresponding change to the DST state, a DSTStatus event " + + "shall be generated. If the list is empty, the node shall generate a DSTTableEmpty event.", + + xref: { document: "core", section: "11.17.9.5" } + }, + + Field( + { name: "DstOffset", id: 0x0, type: "list", conformance: "M" }, + Field({ name: "entry", type: "DSTOffsetStruct" }) + ) + ), + + Command( + { + name: "SetDefaultNtp", id: 0x5, access: "A", conformance: "NTPC", direction: "request", + response: "status", + + details: "This command is used to set the DefaultNTP attribute. If the DefaultNTP Address field does not " + + "conform to the requirements in the DefaultNTP attribute description, the command shall fail with a " + + "status code of INVALID_COMMAND. If the node does not support DNS resolution (as specified in " + + "SupportsDNSResolve) and the provided Address is a domain name, the command shall fail with a status " + + "code of INVALID_COMMAND. Otherwise, the node shall set the DefaultNTP attribute to match the " + + "DefaultNTP provided in this command.", + + xref: { document: "core", section: "11.17.9.6" } + }, + + Field({ + name: "DefaultNtp", id: 0x0, type: "string", conformance: "M", constraint: "max 128", quality: "X", + details: "This field contains the address of an NTP server than can be used as a fallback for time " + + "synchronization. The format of this field shall follow the requirements in the DefaultNTP attribute " + + "description.", + xref: { document: "core", section: "11.17.9.6.1" } + }) + ), + + Datatype( + { name: "GranularityEnum", type: "enum8", xref: { document: "core", section: "11.17.6.1" } }, + Field({ + name: "NoTimeGranularity", id: 0x0, conformance: "M", + description: "This indicates that the node is not currently synchronized with a UTC Time source and its clock is based on the Last Known Good UTC Time only." + }), + Field({ + name: "MinutesGranularity", id: 0x1, conformance: "M", + description: "This indicates the node was synchronized to an upstream source in the past, but sufficient clock drift has occurred such that the clock error is now > 5 seconds." + }), + Field({ + name: "SecondsGranularity", id: 0x2, conformance: "M", + description: "This indicates the node is synchronized to an upstream source using a low resolution protocol. UTC Time is accurate to ± 5 seconds." + }), + Field({ + name: "MillisecondsGranularity", id: 0x3, conformance: "M", + description: "This indicates the node is synchronized to an upstream source using high resolution time- synchronization protocol such as NTP, or has built-in GNSS with some amount of jitter applying its GNSS timestamp. UTC Time is accurate to ± 50 ms." + }), + Field({ + name: "MicrosecondsGranularity", id: 0x4, conformance: "M", + description: "This indicates the node is synchronized to an upstream source using a highly precise time- synchronization protocol such as PTP, or has built-in GNSS. UTC time is accurate to ± 10 μs." + }) + ), + + Datatype( + { name: "TimeSourceEnum", type: "enum8", xref: { document: "core", section: "11.17.6.2" } }, + Field({ + name: "None", id: 0x0, conformance: "M", + description: "Node is not currently synchronized with a UTC Time source." + }), + Field({ name: "Unknown", id: 0x1, conformance: "M", description: "Node uses an unlisted time source." }), + Field({ + name: "Admin", id: 0x2, conformance: "M", + description: "Node received time from a client using the SetUTCTime Command." + }), + Field({ + name: "NodeTimeCluster", id: 0x3, conformance: "M", + description: "Synchronized time by querying the Time Synchronization cluster of another Node." + }), + Field({ + name: "NonMatterSntp", id: 0x4, conformance: "M", + description: "SNTP from a server not in the Matter network. NTS is not used." + }), + Field({ + name: "NonMatterNtp", id: 0x5, conformance: "M", + description: "NTP from servers not in the Matter network. None of the servers used NTS." + }), + Field({ + name: "MatterSntp", id: 0x6, conformance: "M", + description: "SNTP from a server within the Matter network. NTS is not used." + }), + Field({ + name: "MatterNtp", id: 0x7, conformance: "M", + description: "NTP from servers within the Matter network. None of the servers used NTS." + }), + Field({ + name: "MixedNtp", id: 0x8, conformance: "M", + description: "NTP from multiple servers in the Matter network and external. None of the servers used NTS." + }), + Field({ + name: "NonMatterSntpnts", id: 0x9, conformance: "M", + description: "SNTP from a server not in the Matter network. NTS is used." + }), + Field({ + name: "NonMatterNtpnts", id: 0xa, conformance: "M", + description: "NTP from servers not in the Matter network. NTS is used on at least one server." + }), + Field({ + name: "MatterSntpnts", id: 0xb, conformance: "M", + description: "SNTP from a server within the Matter network. NTS is used." + }), + Field({ + name: "MatterNtpnts", id: 0xc, conformance: "M", + description: "NTP from a server within the Matter network. NTS is used on at least one server." + }), + Field({ + name: "MixedNtpnts", id: 0xd, conformance: "M", + description: "NTP from multiple servers in the Matter network and external. NTS is used on at least one server." + }), + Field({ + name: "CloudSource", id: 0xe, conformance: "M", + description: "Time synchronization comes from a vendor cloud-based source (e.g. \"Date\" header in authenticated HTTPS connection)." + }), + Field({ name: "Ptp", id: 0xf, conformance: "M", description: "Time synchronization comes from PTP." }), + Field({ name: "Gnss", id: 0x10, conformance: "M", description: "Time synchronization comes from a GNSS source." }) + ), + + Datatype( + { + name: "TimeZoneDatabaseEnum", type: "enum8", + details: "It indicates what the device knows about the contents of the IANA Time Zone Database. Partial " + + "support on a device may be used to omit historical data, less commonly used time zones, and/or time " + + "zones not related to the region a product is sold in.", + xref: { document: "core", section: "11.17.6.3" } + }, + + Field({ + name: "Full", id: 0x0, conformance: "M", + description: "Node has a full list of the available time zones" + }), + Field({ + name: "Partial", id: 0x1, conformance: "M", + description: "Node has a partial list of the available time zones" + }), + Field({ name: "None", id: 0x2, conformance: "M", description: "Node does not have a time zone database" }) + ), + + Datatype( + { name: "TrustedTimeSourceStruct", type: "struct", xref: { document: "core", section: "11.17.6.4" } }, + + Field({ + name: "FabricIndex", id: 0x0, type: "fabric-idx", conformance: "M", + details: "The Fabric Index associated with the Fabric of the client which last set the value of the trusted " + + "time source node.", + xref: { document: "core", section: "11.17.6.4.1" } + }), + + Field({ + name: "NodeId", id: 0x1, type: "node-id", conformance: "M", + details: "Node ID of the trusted time source node on the Fabric associated with the entry.", + xref: { document: "core", section: "11.17.6.4.2" } + }), + Field({ + name: "Endpoint", id: 0x2, type: "endpoint-no", conformance: "M", + details: "Endpoint on the trusted time source node that contains the Time Synchronization cluster server.", + xref: { document: "core", section: "11.17.6.4.3" } + }) + ), + + Datatype( + { + name: "FabricScopedTrustedTimeSourceStruct", type: "struct", + xref: { document: "core", section: "11.17.6.5" } + }, + Field({ + name: "NodeId", id: 0x0, type: "node-id", conformance: "M", + details: "Node ID of the trusted time source node on the Fabric of the issuer.", + xref: { document: "core", section: "11.17.6.5.1" } + }), + + Field({ + name: "Endpoint", id: 0x1, type: "endpoint-no", conformance: "M", + details: "Endpoint on the trusted time source node that contains the Time Synchronization cluster server. " + + "This is provided to avoid having to do discovery of the location of that endpoint by walking over " + + "all endpoints and checking their Descriptor Cluster.", + xref: { document: "core", section: "11.17.6.5.2" } + }) + ), + + Datatype( + { name: "TimeZoneStruct", type: "struct", xref: { document: "core", section: "11.17.6.6" } }, + Field({ + name: "Offset", id: 0x0, type: "int32", conformance: "M", constraint: "-43200 to 50400", + details: "The time zone offset from UTC in seconds.", + xref: { document: "core", section: "11.17.6.6.1" } + }), + Field({ + name: "ValidAt", id: 0x1, type: "epoch-us", conformance: "M", + details: "The UTC time when the offset shall be applied.", + xref: { document: "core", section: "11.17.6.6.2" } + }), + + Field({ + name: "Name", id: 0x2, type: "string", conformance: "O", constraint: "0 to 64", + details: "The time zone name SHOULD provide a human-readable time zone name and it SHOULD use the " + + "country/city format specified by the IANA Time Zone Database. The Name field may be used for " + + "display. If the node supports a TimeZoneDatabase it may use the Name field to set its own DST " + + "offsets if it has database information for the supplied time zone Name and the given Offset matches.", + xref: { document: "core", section: "11.17.6.6.3" } + }) + ), + + Datatype( + { name: "DSTOffsetStruct", type: "struct", xref: { document: "core", section: "11.17.6.7" } }, + + Field({ + name: "Offset", id: 0x0, type: "int32", conformance: "M", constraint: "desc", + details: "The DST offset in seconds. Normally this is in the range of 0 to 3600 seconds (1 hour), but this " + + "field will accept any values in the int32 range to accommodate potential future legislation that " + + "does not fit with these assumptions.", + xref: { document: "core", section: "11.17.6.7.1" } + }), + + Field({ + name: "ValidStarting", id: 0x1, type: "epoch-us", conformance: "M", + details: "The UTC time when the offset shall be applied.", + xref: { document: "core", section: "11.17.6.7.2" } + }), + + Field({ + name: "ValidUntil", id: 0x2, type: "epoch-us", conformance: "M", quality: "X", + details: "The UTC time when the offset shall stop being applied. Providing a null value here indicates a " + + "permanent DST change. If this value is non-null the value shall be larger than the ValidStarting " + + "time.", + xref: { document: "core", section: "11.17.6.7.3" } + }) + ), + + Datatype( + { name: "StatusCodeEnum", type: "enum8", xref: { document: "core", section: "11.17.7.1" } }, + Field({ + name: "TimeNotAccepted", id: 0x2, conformance: "M", + description: "Node rejected the attempt to set the UTC time" + }) + ) + ), + + Cluster( + { + name: "OperationalCredentials", id: 0x3e, classification: "node", pics: "OPCREDS", + details: "This cluster is used to add or remove Node Operational credentials on a Commissionee or Node, as " + + "well as manage the associated Fabrics.", + xref: { document: "core", section: "11.18" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "NoCs", id: 0x0, type: "list", access: "R F A", conformance: "M", + constraint: "max supportedFabrics", quality: "N C", + + details: "This attribute contains all NOCs applicable to this Node, encoded as a read-only list of NOCStruct." + + "\n" + + "Operational Certificates shall be added through the AddNOC command, and shall be removed through " + + "the RemoveFabric command." + + "\n" + + "Upon Factory Data Reset, this attribute shall be set to a default value of an empty list." + + "\n" + + "The number of entries in this list shall match the number of entries in the Fabrics attribute.", + + xref: { document: "core", section: "11.18.5.1" } + }, + + Field({ name: "entry", type: "NOCStruct" }) + ), + + Attribute( + { + name: "Fabrics", id: 0x1, type: "list", access: "R F V", conformance: "M", + constraint: "max supportedFabrics", quality: "N", + + details: "This attribute describes all fabrics to which this Node is commissioned, encoded as a read-only " + + "list of FabricDescriptorStruct. This information may be computed directly from the NOCs attribute." + + "\n" + + "Upon Factory Data Reset, this attribute shall be set to a default value of an empty list." + + "\n" + + "The number of entries in this list shall match the number of entries in the NOCs attribute.", + + xref: { document: "core", section: "11.18.5.2" } + }, + + Field({ name: "entry", type: "FabricDescriptorStruct" }) + ), + + Attribute({ + name: "SupportedFabrics", id: 0x2, type: "uint8", access: "R V", conformance: "M", + constraint: "5 to 254", quality: "F", + details: "This attribute contains the number of Fabrics that are supported by the device. This value is fixed " + + "for a particular device.", + xref: { document: "core", section: "11.18.5.3" } + }), + + Attribute({ + name: "CommissionedFabrics", id: 0x3, type: "uint8", access: "R V", conformance: "M", + constraint: "max supportedFabrics", quality: "N", + + details: "This attribute contains the number of Fabrics to which the device is currently commissioned. This " + + "attribute shall be equal to the following:" + + "\n" + + " • The number of entries in the NOCs attribute." + + "\n" + + " • The number of entries in the Fabrics attribute." + + "\n" + + "Upon Factory Data Reset, this attribute shall be set to a default value of 0.", + + xref: { document: "core", section: "11.18.5.4" } + }), + + Attribute( + { + name: "TrustedRootCertificates", id: 0x4, type: "list", access: "R V", conformance: "M", + constraint: "max supportedFabrics[max 400]", quality: "N C", + + details: "This attribute shall contain a read-only list of Trusted Root CA Certificates (RCAC) installed on " + + "the Node, as octet strings containing their Matter Certificate Encoding representation." + + "\n" + + "These certificates are installed through the AddTrustedRootCertificate command." + + "\n" + + "Depending on the method of storage employed by the server, either shared storage for identical root " + + "certificates shared by many fabrics, or individually stored root certificate per fabric, multiple " + + "identical root certificates may legally appear within the list." + + "\n" + + "To match a root with a given fabric, the root certificate’s subject and subject public key need to " + + "be cross-referenced with the NOC or ICAC certificates that appear in the NOCs attribute for a given " + + "fabric." + + "\n" + + "Upon Factory Data Reset, this attribute shall be set to a default value whereby the list is empty.", + + xref: { document: "core", section: "11.18.5.5" } + }, + + Field({ name: "entry", type: "octstr" }) + ), + + Attribute({ + name: "CurrentFabricIndex", id: 0x5, type: "uint8", access: "R V", conformance: "M", default: 0, + details: "This attribute shall contain accessing fabric index." + + "\n" + + "This attribute is useful to contextualize Fabric-Scoped entries obtained from response commands or " + + "attribute reads, since a given Fabric may be referenced by a different Fabric Index locally on a " + + "remote Node.", + xref: { document: "core", section: "11.18.5.6" } + }), + + Command( + { + name: "AttestationRequest", id: 0x0, access: "A", conformance: "M", direction: "request", + response: "AttestationResponse", + details: "This command shall be generated to request the Attestation Information, in the form of an " + + "AttestationResponse Command. If the AttestationNonce that is provided in the command is malformed, " + + "a recipient shall fail the command with a Status Code of INVALID_COMMAND. The AttestationNonce " + + "field shall be used in the computation of the Attestation Information.", + xref: { document: "core", section: "11.18.6.1" } + }, + + Field({ name: "AttestationNonce", id: 0x0, type: "octstr", conformance: "M", constraint: "32" }) + ), + + Command( + { + name: "AttestationResponse", id: 0x1, conformance: "M", direction: "response", + + details: "This command shall be generated in response to an Attestation Request command." + + "\n" + + "See Section 11.18.4.7, “Attestation Information” for details about the generation of the fields " + + "within this response command." + + "\n" + + "See Section F.2, “Device Attestation Response test vector” for an example computation of an " + + "AttestationResponse.", + + xref: { document: "core", section: "11.18.6.2" } + }, + + Field({ + name: "AttestationElements", id: 0x0, type: "octstr", conformance: "M", constraint: "max respMax", + details: "This field shall contain the octet string of the serialized attestation_elements_message.", + xref: { document: "core", section: "11.18.6.2.1" } + }), + + Field({ + name: "AttestationSignature", id: 0x1, type: "octstr", conformance: "M", constraint: "64", + details: "This field shall contain the octet string of the necessary attestation_signature as described in " + + "Section 11.18.4.7, “Attestation Information”.", + xref: { document: "core", section: "11.18.6.2.2" } + }) + ), + + Command( + { + name: "CertificateChainRequest", id: 0x2, access: "A", conformance: "M", direction: "request", + response: "CertificateChainResponse", + details: "If the CertificateType is not a valid value per CertificateChainTypeEnum then the command shall " + + "fail with a Status Code of INVALID_COMMAND.", + xref: { document: "core", section: "11.18.6.3" } + }, + + Field({ + name: "CertificateType", id: 0x0, type: "CertificateChainTypeEnum", conformance: "M", + constraint: "desc" + }) + ), + + Command( + { + name: "CertificateChainResponse", id: 0x3, conformance: "M", direction: "response", + details: "This command shall be generated in response to a CertificateChainRequest command.", + xref: { document: "core", section: "11.18.6.4" } + }, + + Field({ + name: "Certificate", id: 0x0, type: "octstr", conformance: "M", constraint: "max 600", + details: "This field shall be the DER encoded certificate corresponding to the CertificateType field in the " + + "CertificateChainRequest command.", + xref: { document: "core", section: "11.18.6.4.1" } + }) + ), + + Command( + { + name: "CsrRequest", id: 0x4, access: "A", conformance: "M", direction: "request", + response: "CsrResponse", + + details: "This command shall be generated to execute the Node Operational CSR Procedure and subsequently " + + "return the NOCSR Information, in the form of a CSRResponse Command." + + "\n" + + "The CSRNonce field shall be used in the computation of the NOCSR Information. If the CSRNonce is " + + "malformed, then this command shall fail with an INVALID_COMMAND status code." + + "\n" + + "If the IsForUpdateNOC field is present and set to true, but the command was received over a PASE " + + "session, the command shall fail with an INVALID_COMMAND status code, as it would never be possible " + + "to use a resulting subsequent certificate issued from the CSR with the UpdateNOC command, which is " + + "forbidden over PASE sessions." + + "\n" + + "If the IsForUpdateNOC field is present and set to true, the internal state of the CSR associated " + + "keypair shall be tagged as being for a subsequent UpdateNOC, otherwise the internal state of the " + + "CSR shall be tagged as being for a subsequent AddNOC. See AddNOC and UpdateNOC for details about " + + "the processing." + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, " + + "then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + + "\n" + + "If the Node Operational Key Pair generated during processing of the Node Operational CSR Procedure " + + "is found to collide with an existing key pair already previously generated and installed, and that " + + "check had been executed, then this command shall fail with a FAILURE status code sent back to the " + + "initiator.", + + xref: { document: "core", section: "11.18.6.5" } + }, + + Field({ name: "CsrNonce", id: 0x0, type: "octstr", conformance: "M", constraint: "32" }), + Field({ name: "IsForUpdateNoc", id: 0x1, type: "bool", conformance: "O", default: false }) + ), + + Command( + { + name: "CsrResponse", id: 0x5, conformance: "M", direction: "response", + + details: "This command shall be generated in response to a CSRRequest Command." + + "\n" + + "See Section 11.18.4.9, “NOCSR Information” for details about the generation of the fields within " + + "this response command." + + "\n" + + "See Section F.3, “Node Operational CSR Response test vector” for an example computation of a " + + "CSRResponse.", + + xref: { document: "core", section: "11.18.6.6" } + }, + + Field({ + name: "NocsrElements", id: 0x0, type: "octstr", conformance: "M", constraint: "max respMax", + details: "This field shall contain the octet string of the serialized nocsr_elements_message.", + xref: { document: "core", section: "11.18.6.6.1" } + }), + + Field({ + name: "AttestationSignature", id: 0x1, type: "octstr", conformance: "M", constraint: "64", + details: "This field shall contain the octet string of the necessary attestation_signature as described in " + + "Section 11.18.4.9, “NOCSR Information”.", + xref: { document: "core", section: "11.18.6.6.2" } + }) + ), + + Command( + { + name: "AddNoc", id: 0x6, access: "A", conformance: "M", direction: "request", + response: "NocResponse", + + details: "This command shall add a new NOC chain to the device and commission a new Fabric association upon " + + "successful validation of all arguments and preconditions." + + "\n" + + "The new value shall immediately be reflected in the NOCs list attribute." + + "\n" + + "A Commissioner or Administrator shall issue this command after issuing the CSRRequest command and " + + "receiving its response." + + "\n" + + "A Commissioner or Administrator SHOULD issue this command after performing the Attestation " + + "Procedure.", + + xref: { document: "core", section: "11.18.6.8" } + }, + + Field({ name: "NocValue", id: 0x0, type: "octstr", conformance: "M", constraint: "max 400" }), + Field({ name: "IcacValue", id: 0x1, type: "octstr", conformance: "O", constraint: "max 400" }), + + Field({ + name: "IpkValue", id: 0x2, type: "octstr", conformance: "M", constraint: "16", + + details: "This field shall contain the value of the Epoch Key for the Identity Protection Key (IPK) to set " + + "for the Fabric which is to be added. This is needed to bootstrap a necessary configuration value " + + "for subsequent CASE to succeed. See Section 4.14.2.6.1, “Identity Protection Key (IPK)” for details." + + "\n" + + "The IPK shall be provided as an octet string of length CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES." + + "\n" + + "On successful execution of the AddNOC command, the side-effect of having provided this field shall " + + "be equivalent to having done a GroupKeyManagement cluster KeySetWrite command invocation using the " + + "newly joined fabric as the accessing fabric and with the following argument fields (assuming " + + "KeySetWrite allowed a GroupKeySetID set to 0):", + + xref: { document: "core", section: "11.18.6.8.1" } + }), + + Field({ + name: "CaseAdminSubject", id: 0x3, type: "subject-id", conformance: "M", + + details: "If the AddNOC command succeeds according to the semantics of the following subsections, then the " + + "Access Control SubjectID shall be used to atomically add an Access Control Entry enabling that " + + "Subject to subsequently administer the Node whose operational identity is being added by this " + + "command." + + "\n" + + "The format of the new Access Control Entry, created from this, shall be:" + + "\n" + + "NOTE" + + "\n" + + "Unless such an Access Control Entry is added atomically as described here, there would be no way " + + "for the caller on its given Fabric to eventually add another Access Control Entry for CASE " + + "authentication mode, to enable the new Administrator to administer the device, since the Fabric " + + "Scoping of the Access Control List prevents the current Node from being able to write new entries " + + "scoped to that Fabric, if the session is established from CASE. While a session established from " + + "PASE does gain Fabric Scope of a newly-joined Fabric, this argument is made mandatory to provide " + + "symmetry between both types of session establishment, both of which need to eventually add an " + + "\"Administer Node over CASE\" Access Control Entry to finalize new Fabric configuration and " + + "subsequently be able to call the CommissioningComplete command.", + + xref: { document: "core", section: "11.18.6.8.2" } + }), + + Field({ + name: "AdminVendorId", id: 0x4, type: "vendor-id", conformance: "M", + + details: "This field shall be set to the Vendor ID of the entity issuing the AddNOC command. This value shall " + + "NOT be one of the reserved Vendor ID values defined in Table 1, “Vendor ID Allocations”." + + "\n" + + "### Effect When Received" + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, " + + "then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + + "\n" + + "If the prior CSRRequest state that preceded AddNOC had the IsForUpdateNOC field indicated as true, " + + "then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + + "\n" + + "If no prior AddTrustedRootCertificate command was successfully executed within the fail-safe timer " + + "period, then this command shall process an error by responding with a NOCResponse with a StatusCode " + + "of InvalidNOC as described in Section 11.18.6.7.2, “Handling Errors”. In other words, AddNOC always " + + "requires that the client provides the root of trust certificate within the same Fail- Safe context " + + "as the rest of the new fabric’s operational credentials, even if some other fabric already uses the " + + "exact same root of trust certificate." + + "\n" + + "If the NOC provided in the NOCValue encodes an Operational Identifier for a pair already present on the device, then the device shall process the error by responding " + + "with a StatusCode of FabricConflict as described in Section 11.18.6.7.2, “Handling Errors”." + + "\n" + + "If the device already has the CommissionedFabrics attribute equal to the SupportedFabrics " + + "attribute, then the device’s operational credentials table is considered full and the device shall " + + "process the error by responding with a StatusCode of TableFull as described in Section 11.18.6.7.2, " + + "“Handling Errors”." + + "\n" + + "If the CaseAdminSubject field is not a valid ACL subject in the context of AuthMode set to CASE, " + + "such as not being in either the Operational or CASE Authenticated Tag range, then the device shall " + + "process the error by responding with a StatusCode of InvalidAdminSubject as described in Section " + + "11.18.6.7.2, “Handling Errors”." + + "\n" + + "Otherwise, the command is considered an addition of credentials, also known as \"joining a fabric\", " + + "and the following shall apply:" + + "\n" + + " 1. A new FabricIndex shall be allocated, taking the next valid fabric-index value in " + + " monotonically incrementing order, wrapping around from 254 (0xFE) to 1, since value 0 is " + + " reserved and using 255 (0xFF) would prevent cluster specifications from using nullable " + + " fabric-idx fields." + + "\n" + + " 2. An entry within the Fabrics attribute table shall be added, reflecting the matter-fabric-id " + + " RDN within the NOC’s subject, along with the public key of the trusted root of the chain and " + + " the AdminVendorID field." + + "\n" + + " 3. The operational key pair associated with the incoming NOC from the NOCValue, and generated by " + + " the prior CSRRequest command, shall be recorded for subsequent use during CASE within the " + + " fail-safe timer period (see Section 5.5, “Commissioning Flows”)." + + "\n" + + " 4. The incoming NOCValue and ICACValue (if present) shall be stored under the FabricIndex " + + " associated with the new Fabric Scope, along with the RootCACertificate provided with the " + + " prior successful AddTrustedRootCertificate command invoked in the same fail-safe period." + + "\n" + + " a. Implementation of certificate chain storage may separate or otherwise encode the components " + + " of the array in implementation-specific ways, as long as they follow the correct format when " + + " being read from the NOCs list or used within other protocols such as CASE." + + "\n" + + " 5. The NOCs list shall reflect the incoming NOC from the NOCValue field and ICAC from the " + + " ICACValue field (if present)." + + "\n" + + " 6. The operational discovery service record shall immediately reflect the new Operational " + + " Identifier, such that the Node immediately begins to exist within the Fabric and becomes " + + " reachable over CASE under the new operational identity." + + "\n" + + " 7. The receiver shall create and add a new Access Control Entry using the CaseAdminSubject field " + + " to grant subsequent Administer access to an Administrator member of the new Fabric. It is " + + " recommended that the Administrator presented in CaseAdminSubject exist within the same entity " + + " that is currently invoking the AddNOC command, within another of the Fabrics of which it is a " + + " member." + + "\n" + + " a. If the Managed Device Feature is implemented by the ACL cluster, then one or more ARL " + + " entries with the new FabricIndex may be added to the ARL attribute." + + "\n" + + " 8. The incoming IPKValue shall be stored in the Fabric-scoped slot within the Group Key " + + " Management cluster (see KeySetWrite), for subsequent use during CASE." + + "\n" + + " 9. The Fabric Index associated with the armed fail-safe context (see ArmFailSafe) shall be " + + " updated to match the Fabric Index just allocated." + + "\n" + + " 10. If the current secure session was established with PASE, the receiver shall:" + + "\n" + + " a. Augment the secure session context with the FabricIndex generated above, such that " + + " subsequent interactions have the proper accessing fabric." + + "\n" + + " 11. If the current secure session was established with CASE, subsequent configuration of the " + + " newly installed Fabric requires the opening of a new CASE session from the Administrator from " + + " the Fabric just installed. This Administrator is the one listed in the CaseAdminSubject " + + " argument." + + "\n" + + "Thereafter, the Node shall respond with an NOCResponse with a StatusCode of OK and a FabricIndex " + + "field matching the FabricIndex under which the new Node Operational Certificate (NOC) is scoped.", + + xref: { document: "core", section: "11.18.6.8.3" } + }) + ), + + Command( + { + name: "UpdateNoc", id: 0x7, access: "F A", conformance: "M", direction: "request", + response: "NocResponse", + + details: "This command shall replace the NOC and optional associated ICAC (if present) scoped under the " + + "accessing fabric upon successful validation of all arguments and preconditions. The new value shall " + + "immediately be reflected in the NOCs list attribute." + + "\n" + + "A Commissioner or Administrator shall issue this command after issuing the CSRRequest Command and " + + "receiving its response." + + "\n" + + "A Commissioner or Administrator SHOULD issue this command after performing the Attestation " + + "Procedure." + + "\n" + + "Effect When Received" + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, " + + "then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + + "\n" + + "If a prior AddTrustedRootCertificate command was successfully invoked within the fail-safe timer " + + "period, then this command shall fail with a CONSTRAINT_ERROR status code sent back to the " + + "initiator, since the only valid following logical operation is invoking the AddNOC command." + + "\n" + + "If the prior CSRRequest state that preceded UpdateNOC had the IsForUpdateNOC field indicated as " + + "false, then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + + "\n" + + "If any of the following conditions arise, the Node shall process an error by responding with an " + + "NOCResponse with a StatusCode of InvalidNOC as described in Section 11.18.6.7.2, “Handling Errors”:" + + "\n" + + " • The NOC provided in the NOCValue does not refer in its subject to the FabricID associated with " + + " the accessing fabric." + + "\n" + + " • The ICAC provided in the ICACValue (if present) has a FabricID in its subject that does not " + + " match the FabricID associated with the accessing fabric." + + "\n" + + "Otherwise, the command is considered an update of existing credentials for a given Fabric, and the " + + "following shall apply:" + + "\n" + + " 1. The Operational Certificate under the accessing fabric index in the NOCs list shall be updated " + + " to match the incoming NOCValue and ICACValue (if present), such that the Node’s Operational " + + " Identifier within the Fabric immediately changes." + + "\n" + + " a. The operational key pair associated with the incoming NOC from the NOCValue, and generated " + + " by the prior CSRRequest command, shall be committed to permanent storage, for subsequent use " + + " during CASE." + + "\n" + + " b. The operational discovery service record shall immediately reflect the new Operational " + + " Identifier." + + "\n" + + " c. All internal data reflecting the prior operational identifier of the Node within the Fabric " + + " shall be revoked and removed, to an outcome equivalent to the disappearance of the prior " + + " Node, except for the ongoing CASE session context, which shall temporarily remain valid " + + " until the NOCResponse has been successfully delivered or until the next transport-layer " + + " error, so that the response can be received by the Administrator invoking the command." + + "\n" + + "Thereafter, the Node shall respond with an NOCResponse with a StatusCode of OK and a FabricIndex " + + "field matching the FabricIndex under which the updated NOC is scoped.", + + xref: { document: "core", section: "11.18.6.9" } + }, + + Field({ name: "NocValue", id: 0x0, type: "octstr", access: "F", conformance: "M", constraint: "max 400" }), + Field({ name: "IcacValue", id: 0x1, type: "octstr", access: "F", conformance: "O", constraint: "max 400" }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Command( + { + name: "NocResponse", id: 0x8, conformance: "M", direction: "response", + + details: "This command shall be generated in response to the following commands:" + + "\n" + + " • AddNOC" + + "\n" + + " • UpdateNOC" + + "\n" + + " • UpdateFabricLabel" + + "\n" + + " • RemoveFabric" + + "\n" + + "It provides status information about the success or failure of those commands.", + + xref: { document: "core", section: "11.18.6.10" } + }, + + Field({ + name: "StatusCode", id: 0x0, type: "NodeOperationalCertStatusEnum", conformance: "M", + details: "This field shall contain an NOCStatus value representing the status of an operation involving a NOC.", + xref: { document: "core", section: "11.18.6.10.1" } + }), + + Field({ + name: "FabricIndex", id: 0x1, type: "fabric-idx", conformance: "O", constraint: "1 to 254", + details: "This field shall be present whenever StatusCode has a value of OK. If present, it shall contain the " + + "Fabric Index of the Fabric last added, removed or updated.", + xref: { document: "core", section: "11.18.6.10.2" } + }), + + Field({ + name: "DebugText", id: 0x2, type: "string", conformance: "O", constraint: "max 128", + details: "This field may contain debugging textual information from the cluster implementation, which SHOULD " + + "NOT be presented to user interfaces in any way. Its purpose is to help developers in " + + "troubleshooting errors and the contents may go into logs or crash reports.", + xref: { document: "core", section: "11.18.6.10.3" } + }) + ), + + Command( + { + name: "UpdateFabricLabel", id: 0x9, access: "F A", conformance: "M", direction: "request", + response: "NocResponse", + + details: "This command shall be used by an Administrator to set the user-visible Label field for a given " + + "Fabric, as reflected by entries in the Fabrics attribute. An Administrator shall use this command " + + "to set the Label to a string (possibly selected by the user themselves) that the user can recognize " + + "and relate to this Administrator" + + "\n" + + " • during the commissioning process, and" + + "\n" + + " • whenever the user chooses to update this string." + + "\n" + + "The Label field, along with the VendorID field in the same entry of the Fabrics attribute, SHOULD " + + "be used by Administrators to provide additional per-fabric context when operations such as " + + "RemoveFabric are considered or used.", + + xref: { document: "core", section: "11.18.6.11" } + }, + + Field({ + name: "Label", id: 0x0, type: "string", access: "F", conformance: "M", constraint: "max 32", + + details: "This field shall contain the label to set for the fabric associated with the current secure session." + + "\n" + + "Effect on Receipt" + + "\n" + + "If the Label field is identical to a Label already in use by a Fabric within the Fabrics list that " + + "is not the accessing fabric, then an NOCResponse with a StatusCode of LabelConflict shall be " + + "returned for the command and there shall NOT be any permanent changes to any Fabric data." + + "\n" + + "Otherwise, the Label field for the accessing fabric shall immediately be updated to reflect the " + + "Label argument provided. Following the update, an NOCResponse with a StatusCode of OK shall be " + + "returned." + + "\n" + + "If the command was invoked within a fail-safe context after a successful UpdateNOC command, then " + + "the label update shall apply to the pending update state that will be reverted if fail-safe expires " + + "prior to a CommissioningComplete command. In other words, label updates apply to the state of the " + + "Fabrics Attribute as currently visible, even for an existing fabric currently in process of being " + + "updated.", + + xref: { document: "core", section: "11.18.6.11.1" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Command( + { + name: "RemoveFabric", id: 0xa, access: "A", conformance: "M", direction: "request", + response: "NocResponse", + + details: "This command is used by Administrators to remove a given Fabric and delete all associated " + + "fabric-scoped data." + + "\n" + + "If the given Fabric being removed is the last one to reference a given Trusted Root CA Certificate " + + "stored in the Trusted Root Certificates list, then that Trusted Root Certificate shall be removed." + + "\n" + + "WARNING" + + "\n" + + "This command, if referring to an already existing Fabric not under the control of the invoking " + + "Administrator, shall ONLY be invoked after obtaining some form of explicit user consent through " + + "some method executed by the Administrator or Commissioner. This method of obtaining consent SHOULD " + + "employ as much data as possible about the existing Fabric associations within the Fabrics list, so " + + "that likelihood is as small as possible of a user removing a Fabric unwittingly. If a method exists " + + "for an Administrator or Commissioner to convey Fabric Removal to an entity related to that Fabric, " + + "whether in-band or out-of-band, then this method SHOULD be used to notify the other Administrative " + + "Domain’s party of the removal. Otherwise, users may only observe the removal of a Fabric " + + "association as persistently failing attempts to reach a Node operationally.", + + xref: { document: "core", section: "11.18.6.12" } + }, + + Field({ + name: "FabricIndex", id: 0x0, type: "fabric-idx", conformance: "M", constraint: "1 to 254", + + details: "This field shall contain the Fabric Index reference (see fabric-index) associated with the Fabric " + + "which is to be removed from the device." + + "\n" + + "Effect on Receipt" + + "\n" + + "If the FabricIndex field does not match the FabricIndex of any entry within the Fabrics list, then " + + "an NOCResponse with a StatusCode of InvalidFabricIndex shall be returned for the command and" + + "\n" + + "there shall NOT be any permanent changes to any device data. Otherwise, one of the following " + + "outcomes shall occur:" + + "\n" + + " 1. If the FabricIndex matches the last remaining entry in the Fabrics list, then the device shall " + + " delete all Matter related data on the node which was created since it was commissioned. This " + + " includes all Fabric-Scoped data, including Access Control List, Access Restriction List, " + + " bindings, scenes, group keys, operational certificates, etc. All Trusted Roots shall also be " + + " removed. If a time synchronization cluster is present on the Node, the TrustedTimeSource and " + + " DefaultNtp shall be set to null. Any Matter related data including logs, secure sessions, " + + " exchanges and interaction model constructs shall also be removed. Since this operation " + + " involves the removal of the secure session data that may underpin the current set of " + + " exchanges, the Node invoking the command SHOULD NOT expect a response before terminating its " + + " secure session with the target." + + "\n" + + " 2. If the FabricIndex does not equal the accessing fabric index, then the device shall begin the " + + " process of irrevocably deleting all associated Fabric-Scoped data, including Access Control " + + " Entries, Access Restriction Entries, bindings, group keys, operational certificates, etc. Any " + + " remaining Trusted Roots no longer referenced by any operational certificate shall also be " + + " removed. If a time synchronization cluster is present on the Node, and the TrustedTimeSource " + + " FabricIndex matches the given FabricIndex, the TrustedTimeSource shall be set to null. All " + + " secure sessions, exchanges and interaction model constructs related to the Operational " + + " Identity under the given Fabric shall also be removed. Following the removal, an NOCResponse " + + " with a StatusCode of OK shall be returned." + + "\n" + + " 3. If the FabricIndex equals the accessing fabric index, then the device shall begin the process " + + " of irrevocably deleting all associated Fabric-Scoped data, including Access Control Entries, " + + " Access Restriction Entries, bindings, group keys, operational certificates, etc. Any remaining " + + " Trusted Roots no longer referenced by any operational certificate shall also be removed. If a " + + " time synchronization cluster is present on the Node, and the TrustedTimeSource FabricIndex " + + " matches the given FabricIndex, the TrustedTimeSource shall be set to null. All secure " + + " sessions, exchanges and interaction model constructs related to the Operational Identity under " + + " the given Fabric shall also be removed. Since this operation involves the removal of the " + + " secure session data that may underpin the current set of exchanges, the Node invoking the " + + " command SHOULD NOT expect a response before terminating its secure session with the target.", + + xref: { document: "core", section: "11.18.6.12.1" } + }) + ), + + Command( + { + name: "AddTrustedRootCertificate", id: 0xb, access: "A", conformance: "M", direction: "request", + response: "status", + + details: "This command shall add a Trusted Root CA Certificate, provided as its Matter Certificate Encoding " + + "representation, to the TrustedRootCertificates Attribute list and shall ensure the next AddNOC " + + "command executed uses the provided certificate as its root of trust." + + "\n" + + "If the certificate from the RootCACertificate field is already installed, based on exact " + + "byte-for-byte equality, then this command shall succeed with no change to the list." + + "\n" + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "If a prior AddTrustedRootCertificate command was successfully invoked within the fail-safe timer " + + "period, which would cause the new invocation to add a second root certificate within a given fail-" + + "\n" + + "safe timer period, then this command shall fail with a CONSTRAINT_ERROR status code sent back to " + + "the initiator." + + "\n" + + "If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, " + + "then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + + "\n" + + "If the certificate from the RootCACertificate field fails any validity checks, not fulfilling all " + + "the requirements for a valid Matter Certificate Encoding representation, including a truncated or " + + "oversize value, then this command shall fail with an INVALID_COMMAND status code sent back to the " + + "initiator." + + "\n" + + "Note that the only method of removing a trusted root is by removing the Fabric that uses it as its " + + "root of trust using the RemoveFabric command.", + + xref: { document: "core", section: "11.18.6.13" } + }, + + Field({ name: "RootCaCertificate", id: 0x0, type: "octstr", conformance: "M", constraint: "max 400" }) + ), + + Datatype( + { + name: "CertificateChainTypeEnum", type: "enum8", + details: "This enumeration is used by the CertificateChainRequest command to convey which certificate from " + + "the device attestation certificate chain to transmit back to the client.", + xref: { document: "core", section: "11.18.4.2" } + }, + + Field({ + name: "DacCertificate", id: 0x1, conformance: "M", + description: "Request the DER- encoded DAC certificate" + }), + Field({ + name: "PaiCertificate", id: 0x2, conformance: "M", + description: "Request the DER- encoded PAI certificate" + }) + ), + + Datatype( + { + name: "NodeOperationalCertStatusEnum", type: "enum8", + details: "This enumeration is used by the NOCResponse common response command to convey detailed outcome of " + + "several of this cluster’s operations.", + xref: { document: "core", section: "11.18.4.3" } + }, + + Field({ name: "Ok", id: 0x0, conformance: "M", description: "OK, no error" }), + Field({ + name: "InvalidPublicKey", id: 0x1, conformance: "M", + description: "Public Key in the NOC does not match the public key in the NOCSR" + }), + Field({ + name: "InvalidNodeOpId", id: 0x2, conformance: "M", + description: "The Node Operational ID in the NOC is not formatted correctly." + }), + Field({ name: "InvalidNoc", id: 0x3, conformance: "M", description: "Any other validation error in NOC chain" }), + Field({ + name: "MissingCsr", id: 0x4, conformance: "M", + description: "No record of prior CSR for which this NOC could match" + }), + Field({ name: "TableFull", id: 0x5, conformance: "M", description: "NOCs table full, cannot add another one" }), + Field({ + name: "InvalidAdminSubject", id: 0x6, conformance: "M", + description: "Invalid CaseAdminSubject field for an AddNOC command." + }), + Field({ + name: "FabricConflict", id: 0x9, conformance: "M", + description: "Trying to AddNOC instead of UpdateNOC against an existing Fabric." + }), + Field({ + name: "LabelConflict", id: 0xa, conformance: "M", + description: "Label already exists on another Fabric." + }), + Field({ name: "InvalidFabricIndex", id: 0xb, conformance: "M", description: "FabricIndex argument is invalid." }) + ), + + Datatype( + { + name: "NOCStruct", type: "struct", + details: "This encodes a fabric sensitive NOC chain, underpinning a commissioned Operational Identity for a " + + "given Node." + + "\n" + + "Note that the Trusted Root CA Certificate is not included in this structure. The roots are " + + "available in the TrustedRootCertificates attribute of the Node Operational Credentials cluster.", + xref: { document: "core", section: "11.18.4.4" } + }, + + Field({ + name: "Noc", id: 0x1, type: "octstr", access: "S", conformance: "M", constraint: "max 400", + details: "This field shall contain the NOC for the struct’s associated fabric, encoded using Matter " + + "Certificate Encoding.", + xref: { document: "core", section: "11.18.4.4.1" } + }), + + Field({ + name: "Icac", id: 0x2, type: "octstr", access: "S", conformance: "M", constraint: "max 400", + quality: "X", + details: "This field shall contain the ICAC or the struct’s associated fabric, encoded using Matter " + + "Certificate Encoding. If no ICAC is present in the chain, this field shall be set to null.", + xref: { document: "core", section: "11.18.4.4.2" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "FabricDescriptorStruct", type: "struct", + details: "This structure encodes a Fabric Reference for a fabric within which a given Node is currently " + + "commissioned.", + xref: { document: "core", section: "11.18.4.5" } + }, + + Field({ + name: "RootPublicKey", id: 0x1, type: "octstr", access: "F", conformance: "M", constraint: "65", + details: "This field shall contain the public key for the trusted root that scopes the fabric referenced by " + + "FabricIndex and its associated operational credential (see Section 6.4.5.3, “Trusted Root CA " + + "Certificates”). The format for the key shall be the same as that used in the ec-pub-key field of " + + "the Matter Certificate Encoding for the root in the operational certificate chain.", + xref: { document: "core", section: "11.18.4.5.1" } + }), + + Field({ + name: "VendorId", id: 0x2, type: "vendor-id", access: "F", conformance: "M", constraint: "desc", + + details: "This field shall contain the value of AdminVendorID provided in the AddNOC command that led to the " + + "creation of this FabricDescriptorStruct. The set of allowed values is defined in AdminVendorID." + + "\n" + + "The intent is to provide some measure of user transparency about which entities have Administer " + + "privileges on the Node." + + "\n" + + "Clients shall consider the VendorID field value to be untrustworthy until the NOC chain associated " + + "with the fabric has passed the Vendor ID Validation Procedure against the associated RCAC.", + + xref: { document: "core", section: "11.18.4.5.2" } + }), + + Field({ + name: "FabricId", id: 0x3, type: "fabric-id", access: "F", conformance: "M", + details: "This field shall contain the FabricID allocated to the fabric referenced by FabricIndex. This field " + + "shall match the value found in the matter-fabric-id field from the operational certificate " + + "providing the operational identity under this Fabric.", + xref: { document: "core", section: "11.18.4.5.3" } + }), + + Field({ + name: "NodeId", id: 0x4, type: "node-id", access: "F", conformance: "M", + details: "This field shall contain the NodeID in use within the fabric referenced by FabricIndex. This field " + + "shall match the value found in the matter-node-id field from the operational certificate providing " + + "this operational identity.", + xref: { document: "core", section: "11.18.4.5.4" } + }), + + Field({ + name: "Label", id: 0x5, type: "string", access: "F", conformance: "M", constraint: "max 32", + default: "", + details: "This field shall contain a commissioner-set label for the fabric referenced by FabricIndex. This " + + "label is set by the UpdateFabricLabel command.", + xref: { document: "core", section: "11.18.4.5.5" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) + ), + + Cluster( + { + name: "AdministratorCommissioning", id: 0x3c, classification: "node", pics: "CADMIN", + + details: "This cluster is used to trigger a Node to allow a new Administrator to commission it. It defines " + + "Attributes, Commands and Responses needed for this purpose." + + "\n" + + "There are two methods of commissioning, Basic Commissioning which may be supported and is described " + + "in Section 5.6.2, “Basic Commissioning Method (BCM)” and Enhanced Commissioning which shall be " + + "supported and is described in Section 5.6.3, “Enhanced Commissioning Method (ECM)”." + + "\n" + + "For the management of Operational Credentials and Trusted Root Certificates, the Node Operational " + + "Credentials cluster is used." + + "\n" + + "If the Administrator Commissioning Cluster server instance is present on an endpoint with the Root " + + "Node device type in the Descriptor cluster DeviceTypeList, then:" + + "\n" + + " • The Commissioning Window shall be opened or closed on the node that the Root Node endpoint is " + + " on." + + "\n" + + " • The attributes shall indicate the state of the node that the Root Node endpoint is on." + + "\n" + + "If the Administrator Commissioning Cluster server instance is present on an endpoint with the " + + "Bridged Node device type in the Descriptor cluster DeviceTypeList, then:" + + "\n" + + " • The Commissioning Window shall be opened or closed on the node represented by the Bridged Node." + + "\n" + + " • The attributes shall indicate the state of the node that is represented by the Bridged Node.", + + xref: { document: "core", section: "11.19" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.19.4" } }, + Field({ name: "BC", constraint: "0", description: "Basic", details: "Node supports Basic Commissioning Method." }) + ), + + Attribute({ + name: "WindowStatus", id: 0x0, type: "CommissioningWindowStatusEnum", access: "R V", + conformance: "M", + + details: "Indicates whether a new Commissioning window has been opened by an Administrator, using either the " + + "OpenCommissioningWindow command or the OpenBasicCommissioningWindow command." + + "\n" + + "This attribute shall revert to WindowNotOpen upon expiry of a commissioning window." + + "\n" + + "NOTE" + + "\n" + + "An initial commissioning window is not opened using either the OpenCommissioningWindow command or " + + "the OpenBasicCommissioningWindow command, and therefore this attribute shall be set to " + + "WindowNotOpen on initial commissioning.", + + xref: { document: "core", section: "11.19.7.1" } + }), + + Attribute({ + name: "AdminFabricIndex", id: 0x1, type: "fabric-idx", access: "R V", conformance: "M", + quality: "X", + + details: "When the WindowStatus attribute is not set to WindowNotOpen, this attribute shall indicate the " + + "FabricIndex associated with the Fabric scoping of the Administrator that opened the window. This " + + "may be used to cross-reference in the Fabrics attribute of the Node Operational Credentials cluster." + + "\n" + + "If, during an open commissioning window, the fabric for the Administrator that opened the window is " + + "removed, then this attribute shall be set to null." + + "\n" + + "When the WindowStatus attribute is set to WindowNotOpen, this attribute shall be set to null.", + + xref: { document: "core", section: "11.19.7.2" } + }), + + Attribute({ + name: "AdminVendorId", id: 0x2, type: "vendor-id", access: "R V", conformance: "M", quality: "X", + + details: "When the WindowStatus attribute is not set to WindowNotOpen, this attribute shall indicate the " + + "Vendor ID associated with the Fabric scoping of the Administrator that opened the window. This " + + "field shall match the VendorID field of the Fabrics attribute list entry associated with the " + + "Administrator having opened the window, at the time of window opening. If the fabric for the " + + "Administrator that opened the window is removed from the node while the commissioning window is " + + "still open, this attribute shall NOT be updated." + + "\n" + + "When the WindowStatus attribute is set to WindowNotOpen, this attribute shall be set to null.", + + xref: { document: "core", section: "11.19.7.3" } + }), + + Command( + { + name: "OpenCommissioningWindow", id: 0x0, access: "A T", conformance: "M", direction: "request", + response: "status", + + details: "This command is used by a current Administrator to instruct a Node to go into commissioning mode. " + + "The Enhanced Commissioning Method specifies a window of time during which an already commissioned " + + "Node accepts PASE sessions. The current Administrator MUST specify a timeout value for the duration " + + "of the OpenCommissioningWindow command." + + "\n" + + "When the OpenCommissioningWindow command expires or commissioning completes, the Node shall remove " + + "the Passcode by deleting the PAKE passcode verifier as well as stop publishing the DNS-SD record " + + "corresponding to this command as described in Section 4.3.1, “Commissionable" + + "\n" + + "Node Discovery”. The commissioning into a new Fabric completes when the Node successfully receives " + + "a CommissioningComplete command, see Section 5.5, “Commissioning Flows”." + + "\n" + + "The parameters for OpenCommissioningWindow command are as follows:" + + "\n" + + "A current Administrator may invoke this command to put a node in commissioning mode for the next " + + "Administrator. On completion, the command shall return a cluster specific status code from the " + + "Section 11.19.6, “Status Codes” below reflecting success or reasons for failure of the operation. " + + "The new Administrator shall discover the Node on the IP network using DNS-based Service Discovery " + + "(DNS-SD) for commissioning." + + "\n" + + "If any format or validity errors related to the PAKEPasscodeVerifier, Iterations or Salt arguments " + + "arise, this command shall fail with a cluster specific status code of PAKEParameterError." + + "\n" + + "If a commissioning window is already currently open, this command shall fail with a cluster " + + "specific status code of Busy." + + "\n" + + "If the fail-safe timer is currently armed, this command shall fail with a cluster specific status " + + "code of Busy, since it is likely that concurrent commissioning operations from multiple separate " + + "Commissioners are about to take place." + + "\n" + + "In case of any other parameter error, this command shall fail with a status code of COMMAND_INVALID.", + + xref: { document: "core", section: "11.19.8.1" } + }, + + Field({ + name: "CommissioningTimeout", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + details: "This field shall specify the time in seconds during which commissioning session establishment is " + + "allowed by the Node. This timeout value shall follow guidance as specified in the initial " + + "Announcement Duration. The CommissioningTimeout applies only to cessation of any announcements and " + + "to accepting of new commissioning sessions; it does not apply to abortion of connections, i.e., a " + + "commissioning session SHOULD NOT abort prematurely upon expiration of this timeout.", + xref: { document: "core", section: "11.19.8.1.1" } + }), + + Field({ + name: "PakePasscodeVerifier", id: 0x1, type: "octstr", conformance: "M", + + details: "This field shall specify an ephemeral PAKE passcode verifier (see Section 3.10, " + + "“Password-Authenticated Key Exchange (PAKE)”) computed by the existing Administrator to be used for " + + "this commissioning. The field is concatenation of two values (w0 || L) shall be " + + "(CRYPTO_GROUP_SIZE_BYTES + CRYPTO_PUBLIC_KEY_SIZE_BYTES)-octets long as detailed in " + + "Crypto_PAKEValues_Responder. It shall be derived from an ephemeral passcode (See PAKE). It shall be " + + "deleted by the Node at the end of commissioning or expiration of the OpenCommissioningWindow " + + "command, and shall be deleted by the existing Administrator after sending it to the Node(s).", + + xref: { document: "core", section: "11.19.8.1.2" } + }), + + Field({ + name: "Discriminator", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 4095", + details: "This field shall be used by the Node as the long discriminator for DNS-SD advertisement (see " + + "Commissioning Discriminator) for discovery by the new Administrator. The new Administrator can find " + + "and filter DNS-SD records by long discriminator to locate and initiate commissioning with the " + + "appropriate Node.", + xref: { document: "core", section: "11.19.8.1.3" } + }), + + Field({ + name: "Iterations", id: 0x3, type: "uint32", conformance: "M", constraint: "1000 to 100000", + details: "This field shall be used by the Node as the PAKE iteration count associated with the ephemeral PAKE " + + "passcode verifier to be used for this commissioning, which shall be sent by the Node to the new " + + "Administrator’s software as response to the PBKDFParamRequest during PASE negotiation. The " + + "permitted range of values shall match the range specified in Section 3.9, “Password-Based Key " + + "Derivation Function (PBKDF)”, within the definition of the Crypto_PBKDFParameterSet.", + xref: { document: "core", section: "11.19.8.1.4" } + }), + + Field({ + name: "Salt", id: 0x4, type: "octstr", conformance: "M", constraint: "16 to 32", + + details: "This field shall be used by the Node as the PAKE Salt associated with the ephemeral PAKE passcode " + + "verifier to be used for this commissioning, which shall be sent by the Node to the new " + + "Administrator’s software as response to the PBKDFParamRequest during PASE negotiation. The " + + "constraints on the value shall match those specified in Section 3.9, “Password-Based Key Derivation " + + "Function (PBKDF)”, within the definition of the Crypto_PBKDFParameterSet." + + "\n" + + "When a Node receives the Open Commissioning Window command, it shall begin advertising on DNS-SD as " + + "described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as described in " + + "CommissioningTimeout. When the command is received by a ICD, it shall enter into active mode. The " + + "ICD shall remain in Active Mode as long as one of these conditions is met:" + + "\n" + + " • A commissioning window is open." + + "\n" + + " • There is an armed fail-safe timer.", + + xref: { document: "core", section: "11.19.8.1.5" } + }) + ), + + Command( + { + name: "OpenBasicCommissioningWindow", id: 0x1, access: "A T", conformance: "BC", + direction: "request", response: "status", + + details: "This command may be used by a current Administrator to instruct a Node to go into commissioning " + + "mode, if the node supports the Basic Commissioning Method. The Basic Commissioning Method specifies " + + "a window of time during which an already commissioned Node accepts PASE sessions. The current " + + "Administrator shall specify a timeout value for the duration of the OpenBasicCommissioningWindow " + + "command." + + "\n" + + "If a commissioning window is already currently open, this command shall fail with a cluster " + + "specific status code of Busy." + + "\n" + + "If the fail-safe timer is currently armed, this command shall fail with a cluster specific status " + + "code of Busy, since it is likely that concurrent commissioning operations from multiple separate " + + "Commissioners are about to take place." + + "\n" + + "In case of any other parameter error, this command shall fail with a status code of COMMAND_INVALID." + + "\n" + + "The commissioning into a new Fabric completes when the Node successfully receives a " + + "CommissioningComplete command, see Section 5.5, “Commissioning Flows”. The new Administrator shall " + + "discover the Node on the IP network using DNS-based Service Discovery (DNS-SD) for commissioning.", + + xref: { document: "core", section: "11.19.8.2" } + }, + + Field({ + name: "CommissioningTimeout", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", + + details: "This field shall specify the time in seconds during which commissioning session establishment is " + + "allowed by the Node. This timeout shall follow guidance as specified in the initial Announcement " + + "Duration." + + "\n" + + "When a Node receives the OpenBasicCommissioningWindow command, it shall begin advertising on DNS-SD " + + "as described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as described " + + "in CommissioningTimeout. When the command is received by a ICD, it shall enter into active mode. " + + "The ICD shall remain in Active Mode as long as one of these conditions is met:" + + "\n" + + " • A commissioning window is open." + + "\n" + + " • There is an armed fail-safe timer.", + + xref: { document: "core", section: "11.19.8.2.1" } + }) + ), + + Command({ + name: "RevokeCommissioning", id: 0x2, access: "A T", conformance: "M", direction: "request", + response: "status", + + details: "This command is used by a current Administrator to instruct a Node to revoke any active " + + "OpenCommissioningWindow or OpenBasicCommissioningWindow command. This is an idempotent command and " + + "the Node shall (for ECM) delete the temporary PAKEPasscodeVerifier and associated data, and stop " + + "publishing the DNS-SD record associated with the OpenCommissioningWindow or " + + "OpenBasicCommissioningWindow command, see Section 4.3.1, “Commissionable Node Discovery”." + + "\n" + + "If no commissioning window was open at time of receipt, this command shall fail with a cluster " + + "specific status code of WindowNotOpen." + + "\n" + + "If the commissioning window was open and the fail-safe was armed when this command is received, the " + + "device shall immediately expire the fail-safe and perform the cleanup steps outlined" + + "\n" + + "in Section 11.10.7.2.2, “Behavior on expiry of Fail-Safe timer”.", + + xref: { document: "core", section: "11.19.8.3" } + }), + + Datatype( + { name: "CommissioningWindowStatusEnum", type: "enum8", xref: { document: "core", section: "11.19.5.1" } }, + Field({ name: "WindowNotOpen", id: 0x0, conformance: "M", description: "Commissioning window not open" }), + Field({ + name: "EnhancedWindowOpen", id: 0x1, conformance: "M", + description: "An Enhanced Commissioning Method window is open" + }), + Field({ + name: "BasicWindowOpen", id: 0x2, conformance: "BC", + description: "A Basic Commissioning Method window is open" + }) + ), + + Datatype( + { name: "StatusCodeEnum", type: "enum8", xref: { document: "core", section: "11.19.6.1" } }, + Field({ + name: "Busy", id: 0x2, conformance: "M", + description: "Could not be completed because another commissioning is in progress" + }), + Field({ + name: "PakeParameterError", id: 0x3, conformance: "M", + description: "Provided PAKE parameters were incorrectly formatted or otherwise invalid" + }), + Field({ + name: "WindowNotOpen", id: 0x4, conformance: "M", + description: "No commissioning window was currently open" + }) + ) + ), + + Cluster( + { + name: "OtaSoftwareUpdateProvider", id: 0x29, classification: "node", pics: "OTAP", + xref: { document: "core", section: "11.20.6" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Command( + { + name: "QueryImage", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "QueryImageResponse", + details: "Upon receipt, this command shall trigger an attempt to find an updated Software Image by the OTA " + + "Provider to match the OTA Requestor’s constraints provided in the payload fields.", + xref: { document: "core", section: "11.20.6.5.1" } + }, + + Field({ + name: "VendorId", id: 0x0, type: "vendor-id", conformance: "M", + details: "The value shall be the Vendor ID applying to the OTA Requestor’s Node and shall match the value " + + "reported by the Basic Information Cluster VendorID attribute.", + xref: { document: "core", section: "11.20.6.5.1.1" } + }), + + Field({ + name: "ProductId", id: 0x1, type: "uint16", conformance: "M", + details: "The value shall be the Product ID applying to the OTA Requestor’s Node and shall match the value " + + "reported by the Basic Information Cluster ProductID attribute.", + xref: { document: "core", section: "11.20.6.5.1.2" } + }), + + Field({ + name: "SoftwareVersion", id: 0x2, type: "uint32", conformance: "M", + details: "The SoftwareVersion included in the request payload shall provide the value representing the " + + "current version running on the OTA Requestor invoking the command. This version shall be equal to " + + "the Software Version attribute of the Basic Information Cluster.", + xref: { document: "core", section: "11.20.6.5.1.3" } + }), + + Field( + { + name: "ProtocolsSupported", id: 0x3, type: "list", conformance: "M", constraint: "max 8", + + details: "This field shall contain a list of all download protocols supported by the OTA Requestor." + + "\n" + + "This field shall be used by the OTA Provider to generate the correct URI for the location of the " + + "Software Image when one is found to be available. The values of BDX Synchronous and BDX " + + "Asynchronous shall always be supported by an OTA Provider. Furthermore, OTA Providers with access " + + "to external networking SHOULD support the HTTPS protocol. OTA Providers may support other protocols." + + "\n" + + "The algorithm to select the specific protocol to use in a given Software Image URI is " + + "implementation-dependent, provided that the rules in Section 11.20.3.3.1, “Download Protocol " + + "selection” are followed." + + "\n" + + "See Section 11.20.3.2, “Querying the OTA Provider” and Section 11.20.3.5, “Transfer of OTA Software " + + "Update images” for more details about usage of this field.", + + xref: { document: "core", section: "11.20.6.5.1.4" } + }, + + Field({ name: "entry", type: "DownloadProtocolEnum" }) + ), + + Field({ + name: "HardwareVersion", id: 0x4, type: "uint16", conformance: "O", + details: "The value of this field, if present, shall contain the OTA Requestor’s hardware version, and shall " + + "be equal to the HardwareVersion attribute of the Basic Information Cluster.", + xref: { document: "core", section: "11.20.6.5.1.5" } + }), + + Field({ + name: "Location", id: 0x5, type: "string", conformance: "O", constraint: "2", + details: "The location, if present, shall provide the same value as the Basic Information Cluster Location" + + "\n" + + "attribute for the OTA Requestor as configured. This may be used by the OTA Provider logic to allow " + + "per-region selection of the Software Image.", + xref: { document: "core", section: "11.20.6.5.1.6" } + }), + + Field({ + name: "RequestorCanConsent", id: 0x6, type: "bool", conformance: "O", default: false, + details: "This field shall be set to true by an OTA Requestor that is capable of obtaining user consent for " + + "OTA application by virtue of built-in user interface capabilities. Otherwise, it shall be false." + + "\n" + + "See Section 11.20.3.4, “Obtaining user consent for updating software” for application details about " + + "usage.", + xref: { document: "core", section: "11.20.6.5.1.7" } + }), + + Field({ + name: "MetadataForProvider", id: 0x7, type: "octstr", conformance: "O", constraint: "max 512", + + details: "This optional field, if present, shall consist of a top-level anonymous list; each list element " + + "shall have a profile-specific tag encoded in fully-qualified form. Each list element shall contain " + + "a manufacturer-specific payload, which the OTA Requestor invoking this command wants to expose to " + + "the receiving OTA Provider. This payload may be used for any purpose and SHOULD be as small as " + + "practical." + + "\n" + + "The use of this field SHOULD be restricted to Vendor-specific usage and shall NOT be used as a " + + "selector required to match for the selection of a Software Image in production environments, unless " + + "absolutely necessary, as the interpretation of this field may be ambiguous to OTA Providers " + + "implementing the Cluster in a compliant but divergent way from the sender." + + "\n" + + "An example of usage for this field is for an OTA Requestor to provide specific data about grouping " + + "or authentication in field trial environments, where the OTA Provider is likely to understand it " + + "and be able to act upon it, either for special selection of image, or recording of activity." + + "\n" + + "An OTA Provider shall report the availability of Software Images, if one is found to be applicable " + + "using the other provided fields, even if the MetadataForProvider field is deemed to contain invalid " + + "or unknown information. That is, the contents of the MetadataForProvider field shall NOT be used to " + + "deny a software update to an OTA Requestor, unless both OTA Requestor and OTA Provider have an " + + "externally agreed-upon policy whereby strictly correct additional MetadataForProvider is expected " + + "to fulfill the OTA Software Update process." + + "\n" + + "Usage of the QueryImage Command" + + "\n" + + "OTA Requestors shall send a QueryImage command to the OTA Provider to determine the availability of " + + "a new Software Image." + + "\n" + + "See Section 11.20.3.2, “Querying the OTA Provider” for full details about the OTA Software Update " + + "Query flow which makes use of this command.", + + xref: { document: "core", section: "11.20.6.5.1.8" } + }) + ), + + Command( + { + name: "QueryImageResponse", id: 0x1, conformance: "M", direction: "response", + xref: { document: "core", section: "11.20.6.5.2" } + }, + + Field({ + name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", + details: "This field shall contain the primary response regarding the availability of a Software Image." + + "\n" + + "See Section 11.20.3.2, “Querying the OTA Provider” for details about the possible values for this " + + "field and their meaning.", + xref: { document: "core", section: "11.20.6.5.2.1" } + }), + + Field({ + name: "DelayedActionTime", id: 0x1, type: "uint32", conformance: "O", + + details: "This field shall convey the minimum time to wait, in seconds from the time of this response, before " + + "sending another QueryImage command or beginning a download from the OTA Provider. OTA Requestors " + + "shall respect this minimum delay, unless they had previously restarted and lost track of it. OTA " + + "Providers SHOULD expect OTA Requestors to follow this value to their best capability, however, a " + + "restarting Node may come back sooner, due to having lost track of this state response." + + "\n" + + "The DelayedActionTime field shall only be present if the Status field is set to Busy." + + "\n" + + "See Section 11.20.3.2, “Querying the OTA Provider” for details about the rules regarding this field.", + + xref: { document: "core", section: "11.20.6.5.2.2" } + }), + + Field( + { + name: "ImageUri", id: 0x2, type: "string", conformance: "O", constraint: "max 256", + + details: "This field, when present, shall contain a URI where the OTA Requestor SHOULD download a Software " + + "Image. The syntax of the ImageURI field shall follow the URI syntax as specified in RFC 3986." + + "\n" + + "This field shall be present if it appears in a QueryImageResponse with a Status of UpdateAvailable." + + "\n" + + "If the ImageURI specifies a BDX Protocol bdx: scheme, then the following rules describe the " + + "location to be used for download:" + + "\n" + + " 1. The URI’s scheme field shall be exactly bdx in lowercase characters." + + "\n" + + " 2. The URI’s authority field shall contain only the host portion and shall use string " + + " representation of the Operational Node ID of the Node where to proceed with the download, on " + + " the same Fabric on which the OTA Requestor received the QueryImageResponse." + + "\n" + + " 3. The encoding of the Node ID in the host field shall use an uppercase hexadecimal format, using " + + " exactly 16 characters to encode the network byte order value of the NodeID, in a similar " + + " fashion as the Node Identifier portion of the Operational Instance Name." + + "\n" + + " a. The Operational Node ID in the host field shall match the NodeID of the OTA Provider " + + " responding with the QueryImageResponse. The usage of a different Node ID than that of the " + + " provider is reserved for future use. This constraint reduces the number of independent CASE " + + " secure channel sessions that have to be maintained to proceed with OTA software updates, " + + " thus reducing energy and resource utilization for the software update process." + + "\n" + + " 4. The user section of the authority field shall be absent, as there are no \"users\" to be " + + " considered." + + "\n" + + " 5. The port section of the authority field shall be absent, as the port for transport shall be " + + " determined through Operational Discovery of the target Node." + + "\n" + + " 6. The URI shall NOT contain a query field." + + "\n" + + " 7. The URI shall NOT contain a fragment field." + + "\n" + + " 8. The path field shall employ absolute path representation and shall contain the file designator " + + " of the software image to download at the BDX server. When used with the BDX server, the " + + " leading / separating the URI authority from the path shall be omitted. When contacting the BDX " + + " server, further processing of the file designator shall NOT be done, including handling of " + + " URL-encoded escape sequences. Rather, the exact octets of the path, as received shall be the " + + " values used by both client and server in handling the file designator." + + "\n" + + " a. The path shall only contain valid URI characters." + + "\n" + + "These rules above for BDX URIs simplify parsing for OTA Requestors receiving Image URIs. The " + + "following example procedure shows how the format constraints simplify the extraction of the " + + "necessary data to reach the BDX server for download." + + "\n" + + " 1. Verify that the URI is 24 characters or longer, which is the minimum length of a valid BDX URI " + + " with all elements present, for example bdx://00112233AABBCCDD/0." + + "\n" + + " 2. Verify the presence of prefix bdx:// indicating a BDX URI." + + "\n" + + " 3. Extract the next 16 characters and convert from uppercase hexadecimal to a 64-bit scalar " + + " value, considering network byte order. This is the destination Node ID." + + "\n" + + " 4. Verify the presence of a path separator / and skip it." + + "\n" + + " 5. Extract the remaining characters of the string as the file designator to employ when " + + " initiating the BDX transfer." + + "\n" + + "Example ImageURI values are below, and illustrate some but not all of valid and invalid cases:" + + "\n" + + " • Synchronous or Asynchronous BDX Protocol:" + + "\n" + + " ◦ Valid: bdx://8899AABBCCDDEEFF/the_file_designator123" + + "\n" + + " ▪ Node ID: 0x8899AABBCCDDEEFF" + + "\n" + + " ▪ File designator: the_file_designator123" + + "\n" + + " ◦ Valid: bdx://0099AABBCCDDEE77/the%20file%20designator/some_more" + + "\n" + + " ▪ Node ID: 0x0099AABBCCDDEE77" + + "\n" + + " ▪ File designator: the%20file%20designator/some_more. Note that the %20 are retained and not " + + " converted to ASCII 0x20 (space). The file designator is the path as received verbatim, " + + " after the first '/' (U+002F / SOLIDUS) following the host." + + "\n" + + " ◦ Invalid: bdx://99AABBCCDDEE77/the_file_designator123" + + "\n" + + " ▪ Node ID: Invalid since it is not exactly 16 characters long, due to having omitted leading " + + " zeros." + + "\n" + + " ◦ Invalid: bdx://0099aabbccddee77/the_file_designator123" + + "\n" + + " ▪ Node ID: Invalid since lowercase hexadecimal was used." + + "\n" + + " ◦ Invalid: bdx:8899AABBCCDDEEFF/the_file_designator123" + + "\n" + + " ▪ Invalid since bdx scheme does not contain an authority, that is, it does not have // after " + + " the first :." + + "\n" + + " • HTTP over TLS:" + + "\n" + + " ◦ Valid: https://example.domain:8466/software/image.bin" + + "\n" + + "See Section 11.20.3.2, “Querying the OTA Provider” for additional details about the flow.", + + xref: { document: "core", section: "11.20.6.5.2.3" } + } + ), + + Field({ + name: "SoftwareVersion", id: 0x3, type: "uint32", conformance: "O", + + details: "This field indicates the version of the image being provided to the OTA Requestor by the OTA " + + "Provider when the Status is UpdateAvailable." + + "\n" + + "This field shall be present if it appears in a QueryImageResponse with a Status of UpdateAvailable." + + "\n" + + "See Section 11.20.3.2, “Querying the OTA Provider” for additional details about the flow and " + + "acceptable values.", + + xref: { document: "core", section: "11.20.6.5.2.4" } + }), + + Field({ + name: "SoftwareVersionString", id: 0x4, type: "string", conformance: "O", constraint: "1 to 64", + + details: "This field provides a string version of the image being provided to the OTA Requestor by the OTA " + + "Provider when the Status is UpdateAvailable." + + "\n" + + "This field shall be present if it appears in a QueryImageResponse with a Status of UpdateAvailable." + + "\n" + + "See Section 11.20.3.2, “Querying the OTA Provider” for additional details about the flow and " + + "acceptable values.", + + xref: { document: "core", section: "11.20.6.5.2.5" } + }), + + Field({ + name: "UpdateToken", id: 0x5, type: "octstr", conformance: "O", constraint: "8 to 32", + details: "This optional field shall be present when the Status field contains UpdateAvailable." + + "\n" + + "See Section 11.20.3.6.1, “UpdateToken usage” for additional details about the generation and usage " + + "of UpdateToken.", + xref: { document: "core", section: "11.20.6.5.2.6" } + }), + + Field({ + name: "UserConsentNeeded", id: 0x6, type: "bool", conformance: "O", default: false, + + details: "This field, if present, shall only be interpreted if the OTA Requestor had previously indicated a " + + "value of True in the RequestorCanConsent field of the QueryImageRequest. This field, when present " + + "and set to True, shall indicate that a capable OTA Requestor must obtain user-visible consent prior " + + "to downloading the OTA Software Image." + + "\n" + + "See Section 11.20.3.4, “Obtaining user consent for updating software” for application details about " + + "usage.", + + xref: { document: "core", section: "11.20.6.5.2.7" } + }), + + Field({ + name: "MetadataForRequestor", id: 0x7, type: "octstr", conformance: "O", constraint: "max 512", + + details: "This optional field, if present, shall consist of a top-level anonymous list; each list element " + + "shall have a profile-specific tag encoded in fully-qualified form. Each list element shall contain " + + "a manufacturer-specific payload, which the OTA Provider wants to expose to the receiving OTA " + + "Requestor. This payload may be used for any purpose and SHOULD be as small as practical." + + "\n" + + "The presence of this field shall NOT be required for correct operation of any OTA Provider " + + "compliant with this Cluster specification." + + "\n" + + "The data for this field does not exist in any Distributed Compliance Ledger record and SHOULD only " + + "be emitted by an OTA Provider with this additional knowledge if it has knowledge that the receiving " + + "OTA Requestor may be able to use it.", + + xref: { document: "core", section: "11.20.6.5.2.8" } + }) + ), + + Command( + { + name: "ApplyUpdateRequest", id: 0x2, access: "O", conformance: "M", direction: "request", + response: "ApplyUpdateResponse", + xref: { document: "core", section: "11.20.6.5.3" } + }, + + Field({ + name: "UpdateToken", id: 0x0, type: "octstr", conformance: "M", constraint: "8 to 32", + details: "This field shall contain the UpdateToken as specified in Section 11.20.3.6.1, “UpdateToken usage”. " + + "This field may be used by the OTA Provider to track minimal lifecycle state to allow finer-grained " + + "scheduling of the application of Software Images by OTA Requestors.", + xref: { document: "core", section: "11.20.6.5.3.1" } + }), + + Field({ + name: "NewVersion", id: 0x1, type: "uint32", conformance: "M", + + details: "The NewVersion field included in the request payload shall provide the SoftwareVersion value of the " + + "new Software Image which the OTA Requestor is ready to start applying. The OTA Provider may use " + + "this new version to track or record Software Image application by OTA Requestors." + + "\n" + + "When Generated" + + "\n" + + "The ApplyUpdateRequest Command shall be invoked by an OTA Requestor once it is ready to apply a " + + "previously downloaded Software Image." + + "\n" + + "Effect on Receipt" + + "\n" + + "Upon receipt of this command the OTA Provider shall respond with an Action field consistent with " + + "the next action the OTA Requestor should take, including any possible time delay." + + "\n" + + "The OTA Provider shall NOT refer to previously stored state about any download progress to reply. " + + "If any state keeping is done by the OTA Provider, it shall only relate to the UpdateToken and the " + + "history of prior ApplyUpdateRequest commands." + + "\n" + + "See Section 11.20.3.6, “Applying a software update” for a description of the flow in response to an " + + "OTA Provider receiving an invocation of this command." + + "\n" + + "Handling Error Cases" + + "\n" + + "See Section 11.20.3.6, “Applying a software update” for all error-handling information.", + + xref: { document: "core", section: "11.20.6.5.3.2" } + }) + ), + + Command( + { + name: "ApplyUpdateResponse", id: 0x3, conformance: "M", direction: "response", + xref: { document: "core", section: "11.20.6.5.4" } + }, + + Field({ + name: "Action", id: 0x0, type: "ApplyUpdateActionEnum", conformance: "M", + details: "The Action field shall express the action that the OTA Provider requests from the OTA Requestor. " + + "See Section 11.20.3.6, “Applying a software update” for a description of the Action values provided " + + "in response to an OTA Provider receiving an invocation of this command.", + xref: { document: "core", section: "11.20.6.5.4.1" } + }), + + Field({ + name: "DelayedActionTime", id: 0x1, type: "uint32", conformance: "M", + details: "The minimum time period the OTA Requestor shall wait before executing the Action, in seconds from " + + "receipt." + + "\n" + + "If this field has a value higher than 86400 seconds (24 hours), then the OTA Requestor may assume a " + + "value of 86400, in order to reduce undue Software Image application delays.", + xref: { document: "core", section: "11.20.6.5.4.2" } + }) + ), + + Command( + { + name: "NotifyUpdateApplied", id: 0x4, access: "O", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.20.6.5.5" } + }, + Field({ + name: "UpdateToken", id: 0x0, type: "octstr", conformance: "M", constraint: "8 to 32", + details: "This field shall contain the UpdateToken as specified in Section 11.20.3.6.1, “UpdateToken usage”.", + xref: { document: "core", section: "11.20.6.5.5.1" } + }), + + Field({ + name: "SoftwareVersion", id: 0x1, type: "uint32", conformance: "M", + + details: "The SoftwareVersion included in the request payload shall provide the same value as the " + + "SoftwareVersion attribute in the invoking OTA Requestor’s Basic Information Cluster, and SHOULD be " + + "consistent with the value representing a new version running on the Node invoking the command." + + "\n" + + "When Generated" + + "\n" + + "The NotifyUpdateApplied command SHOULD be invoked in the following two circumstances:" + + "\n" + + " 1. An OTA Requestor has just successfully applied a Software Image it had obtained from a " + + " previous QueryImage response." + + "\n" + + " 2. An OTA Requestor has just successfully applied a Software Image it had obtained through means " + + " different than those of this Cluster." + + "\n" + + "An OTA Provider may use the state of invocation of this command to help track the progress of " + + "update for OTA Requestors it knows require a new OTA Software Image. However, due to the " + + "possibility that an OTA Requestor may never come back (e.g. device removed from Fabric altogether, " + + "or a critical malfunction), an OTA Provider shall NOT expect every OTA Requestor to invoke this " + + "command for correct operation of the OTA Provider." + + "\n" + + "This command shall be considered optional and shall NOT result in reduced availability of the OTA " + + "Provider functionality if OTA Requestors never invoke this command." + + "\n" + + "Effect on Receipt" + + "\n" + + "An OTA Provider receiving an invocation of this command may log it internally." + + "\n" + + "On receiving this command, an OTA Provider may use the information to update its bookkeeping of " + + "cached Software Images, or use it for other similar administrative purposes.", + + xref: { document: "core", section: "11.20.6.5.5.2" } + }) + ), + + Datatype( + { + name: "StatusEnum", type: "enum8", + details: "See Section 11.20.3.2, “Querying the OTA Provider” for the semantics of these values.", + xref: { document: "core", section: "11.20.6.4.1" } + }, + Field({ + name: "UpdateAvailable", id: 0x0, conformance: "M", + description: "Indicates that the OTA Provider has an update available." + }), + Field({ + name: "Busy", id: 0x1, conformance: "M", + description: "Indicates OTA Provider may have an update, but it is not ready yet." + }), + Field({ + name: "NotAvailable", id: 0x2, conformance: "M", + description: "Indicates that there is definitely no update currently available from the OTA Provider." + }), + Field({ + name: "DownloadProtocolNotSupported", id: 0x3, conformance: "M", + description: "Indicates that the requested download protocol is not supported by the OTA Provider." + }) + ), + + Datatype( + { + name: "ApplyUpdateActionEnum", type: "enum8", + details: "See Section 11.20.3.6, “Applying a software update” for the semantics of the values. This " + + "enumeration is used in the Action field of the ApplyUpdateResponse command. See (Action).", + xref: { document: "core", section: "11.20.6.4.2" } + }, + + Field({ name: "Proceed", id: 0x0, conformance: "M", description: "Apply the update." }), + Field({ name: "AwaitNextAction", id: 0x1, conformance: "M", description: "Wait at least the given delay time." }), + Field({ + name: "Discontinue", id: 0x2, conformance: "M", + description: "The OTA Provider is conveying a desire to rescind a previously provided Software Image." + }) + ), + + Datatype( + { + name: "DownloadProtocolEnum", type: "enum8", + details: "Note that only HTTP over TLS (HTTPS) is supported (see RFC 7230). Using HTTP without TLS shall NOT " + + "be supported, as there is no way to authenticate the involved participants.", + xref: { document: "core", section: "11.20.6.4.3" } + }, + + Field({ + name: "BdxSynchronous", id: 0x0, conformance: "M", + description: "Indicates support for synchronous BDX." + }), + Field({ + name: "BdxAsynchronous", id: 0x1, conformance: "O", + description: "Indicates support for asynchronous BDX." + }), + Field({ name: "Https", id: 0x2, conformance: "O", description: "Indicates support for HTTPS." }), + Field({ + name: "VendorSpecific", id: 0x3, conformance: "O", + description: "Indicates support for vendor specific protocol." + }) + ) + ), + + Cluster( + { + name: "OtaSoftwareUpdateRequestor", id: 0x2a, classification: "node", pics: "OTAR", + xref: { document: "core", section: "11.20.7" } + }, + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { + name: "DefaultOtaProviders", id: 0x0, type: "list", access: "RW F VA", conformance: "M", + constraint: "desc", default: [], quality: "N", + + details: "This field is a list of ProviderLocation whose entries shall be set by Administrators, either " + + "during Commissioning or at a later time, to set the ProviderLocation for the default OTA Provider " + + "Node to use for software updates on a given Fabric." + + "\n" + + "There shall NOT be more than one entry per Fabric. On a list update that would introduce more than " + + "one entry per fabric, the write shall fail with CONSTRAINT_ERROR status code." + + "\n" + + "Provider Locations obtained using the AnnounceOTAProvider command shall NOT overwrite values set in " + + "the DefaultOTAProviders attribute.", + + xref: { document: "core", section: "11.20.7.5.1" } + }, + + Field({ name: "entry", type: "ProviderLocation" }) + ), + + Attribute({ + name: "UpdatePossible", id: 0x1, type: "bool", access: "R V", conformance: "M", default: true, + details: "This field shall be set to True if the OTA Requestor is currently able to be updated. Otherwise, it " + + "shall be set to False in case of any condition preventing update being possible, such as " + + "insufficient capacity of an internal battery. This field is merely informational for diagnostics " + + "purposes and shall NOT affect the responses provided by an OTA Provider to an OTA Requestor.", + xref: { document: "core", section: "11.20.7.5.2" } + }), + + Attribute({ + name: "UpdateState", id: 0x2, type: "UpdateStateEnum", access: "R V", conformance: "M", default: 0, + details: "This field shall reflect the current state of the OTA Requestor with regards to obtaining software " + + "updates. See Section 11.20.7.4.2, “UpdateStateEnum Type” for possible values." + + "\n" + + "This field SHOULD be updated in a timely manner whenever OTA Requestor internal state updates.", + xref: { document: "core", section: "11.20.7.5.3" } + }), + + Attribute({ + name: "UpdateStateProgress", id: 0x3, type: "uint8", access: "R V", conformance: "M", + constraint: "0 to 100", default: null, quality: "X", + + details: "This field shall reflect the percentage value of progress, relative to the current UpdateState, if " + + "applicable to the state." + + "\n" + + "The value of this field shall be null if a progress indication does not apply to the current state." + + "\n" + + "A value of 0 shall indicate that the beginning has occurred. A value of 100 shall indicate " + + "completion." + + "\n" + + "This field may be updated infrequently. Some care SHOULD be taken by Nodes to avoid over- reporting " + + "progress when this attribute is part of a subscription.", + + xref: { document: "core", section: "11.20.7.5.4" } + }), + + Event( + { + name: "StateTransition", id: 0x0, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated when a change of the UpdateState attribute occurs due to an OTA " + + "Requestor moving through the states necessary to query for updates.", + xref: { document: "core", section: "11.20.7.7.1" } + }, + + Field({ + name: "PreviousState", id: 0x0, type: "UpdateStateEnum", conformance: "M", default: 0, + details: "This field shall be set to the state that preceded the transition causing this event to be " + + "generated, if such a state existed. If no previous state exists, the value shall be Unknown.", + xref: { document: "core", section: "11.20.7.7.1.1" } + }), + + Field({ + name: "NewState", id: 0x1, type: "UpdateStateEnum", conformance: "M", + details: "This field shall be set to the state now in effect through the transition causing this event to be " + + "generated.", + xref: { document: "core", section: "11.20.7.7.1.2" } + }), + + Field({ + name: "Reason", id: 0x2, type: "ChangeReasonEnum", conformance: "M", + details: "This field shall be set to the reason why this event was generated.", + xref: { document: "core", section: "11.20.7.7.1.3" } + }), + + Field({ + name: "TargetSoftwareVersion", id: 0x3, type: "uint32", conformance: "M", default: null, + quality: "X", + details: "This field shall be set to the target SoftwareVersion which is the subject of the operation, " + + "whenever the NewState is Downloading, Applying or RollingBack. Otherwise TargetSoftwareVersion " + + "shall be null.", + xref: { document: "core", section: "11.20.7.7.1.4" } + }) + ), + + Event( + { + name: "VersionApplied", id: 0x1, access: "V", conformance: "M", priority: "critical", + details: "This event shall be generated whenever a new version starts executing after being applied due to a " + + "software update. This event SHOULD be generated even if a software update was done using means " + + "outside of this cluster.", + xref: { document: "core", section: "11.20.7.7.2" } + }, + + Field({ + name: "SoftwareVersion", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall be set to the same value as the one available in the Software Version attribute of " + + "the Basic Information Cluster for the newly executing version.", + xref: { document: "core", section: "11.20.7.7.2.1" } + }), + + Field({ + name: "ProductId", id: 0x1, type: "uint16", conformance: "M", + details: "This field shall be set to the ProductID applying to the executing version, as reflected by the " + + "Basic Information Cluster. This can be used to detect a product updating its definition due to a " + + "large-scale functional update that may impact aspects of the product reflected in the DeviceModel " + + "schema of the Distributed Compliance Ledger.", + xref: { document: "core", section: "11.20.7.7.2.2" } + }) + ), + + Event( + { + name: "DownloadError", id: 0x2, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated whenever an error occurs during OTA Requestor download operation.", + xref: { document: "core", section: "11.20.7.7.3" } + }, + + Field({ + name: "SoftwareVersion", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall be set to the value of the SoftwareVersion being downloaded, matching the " + + "SoftwareVersion field of the QueryImageResponse that caused the failing download to take place.", + xref: { document: "core", section: "11.20.7.7.3.1" } + }), + + Field({ + name: "BytesDownloaded", id: 0x1, type: "uint64", conformance: "M", + details: "This field shall be set to the number of bytes that have been downloaded during the failing " + + "transfer that caused this event to be generated.", + xref: { document: "core", section: "11.20.7.7.3.2" } + }), + + Field({ + name: "ProgressPercent", id: 0x2, type: "uint8", conformance: "M", constraint: "0 to 100", + default: null, quality: "X", + details: "This field shall be set to the nearest integer percent value reflecting how far within the transfer " + + "the failure occurred during the failing transfer that caused this event to be generated, unless the " + + "total length of the transfer is unknown, in which case it shall be null.", + xref: { document: "core", section: "11.20.7.7.3.3" } + }), + + Field({ + name: "PlatformCode", id: 0x3, type: "int64", conformance: "M", default: null, quality: "X", + details: "This field SHOULD be set to some internal product-specific error code, closest in " + + "temporal/functional proximity to the failure that caused this event to be generated. Otherwise, it " + + "shall be null. This event field may be used for debugging purposes and no uniform definition exists " + + "related to its meaning.", + xref: { document: "core", section: "11.20.7.7.3.4" } + }) + ), + + Command( + { + name: "AnnounceOtaProvider", id: 0x0, access: "A", conformance: "O", direction: "request", + response: "status", + details: "This command may be invoked by Administrators to announce the presence of a particular OTA Provider." + + "\n" + + "This command shall be scoped to the accessing fabric." + + "\n" + + "If the accessing fabric index is 0, this command shall fail with an UNSUPPORTED_ACCESS status code.", + xref: { document: "core", section: "11.20.7.6.1" } + }, + + Field({ + name: "ProviderNodeId", id: 0x0, type: "node-id", access: "F", conformance: "M", + details: "This field shall contain the Node ID of a Node implementing the OTA Provider cluster server, on the " + + "accessing fabric.", + xref: { document: "core", section: "11.20.7.6.1.1" } + }), + + Field({ + name: "VendorId", id: 0x1, type: "vendor-id", access: "F", conformance: "M", + details: "This field shall contain the assigned Vendor ID of the Node invoking this command, as it would " + + "appear in that Node’s Basic Information Cluster VendorID attribute.", + xref: { document: "core", section: "11.20.7.6.1.2" } + }), + + Field({ + name: "AnnouncementReason", id: 0x2, type: "AnnouncementReasonEnum", access: "F", conformance: "M", + details: "This field shall contain a value expressing the reason for the announcement.", + xref: { document: "core", section: "11.20.7.6.1.3" } + }), + + Field({ + name: "MetadataForNode", id: 0x3, type: "octstr", access: "F", conformance: "O", + constraint: "max 512", + + details: "This optional field, if present, shall consist of a top-level anonymous list; each list element " + + "shall have a profile-specific tag encoded in fully-qualified form. Each list element shall contain " + + "a manufacturer-specific payload, which the Node invoking this command wants to expose to the " + + "receiving Node. This payload may be used for any purpose and SHOULD be as small as practical, " + + "especially if invoked to groups, in order to reduce networking burden of these payloads." + + "\n" + + "This field SHOULD only be included if the sending OTA Provider has knowledge that some recipient " + + "can make use of it.", + + xref: { document: "core", section: "11.20.7.6.1.4" } + }), + + Field({ + name: "Endpoint", id: 0x4, type: "endpoint-no", access: "F", conformance: "M", + + details: "This field shall contain the endpoint number which has the OTA Provider device type and OTA " + + "Software Update Provider cluster server on the ProviderNodeID. This is provided to avoid having to " + + "do discovery of the location of that endpoint by walking over all endpoints and checking their " + + "Descriptor Cluster." + + "\n" + + "When Generated" + + "\n" + + "An OTA Provider may invoke this command directly to an OTA Requestor, to announce its presence as " + + "an OTA Provider on the Fabric." + + "\n" + + "These announcements, if made, SHOULD be made at most once every 24 hours for any given target Node, " + + "to assist OTA Requestors in discovering available OTA Provider resources, unless the " + + "AnnouncementReason is UrgentUpdateAvailable, in which case this command may be more frequent." + + "\n" + + "Any invocation shall be made with a delay of at least 1 second between invocations from a given OTA " + + "Provider, to reduce burden on the networking infrastructure and affect a form of serialized jitter. " + + "It is recommended to offset the first announcement of a round (i.e. new set of announcements after " + + "a previous complete set) by a random delay time with a distribution span of >= 60 seconds to jitter " + + "announcement schedules over time." + + "\n" + + "Effect on Receipt" + + "\n" + + "On receipt of this command, an OTA Requestor SHOULD consider the new ProviderNodeID and " + + "AnnouncementReason to possibly query for new software sooner than it would have with its default " + + "behavior." + + "\n" + + "The OTA Requestor SHOULD NOT update entries in the DefaultOTAProviders list based on announcements." + + "\n" + + "The receiving Node may ignore the content of the announcement if it is unable or unwilling to " + + "further query OTA Providers temporarily, or if its provider list is full. If the announcement is " + + "ignored, the response SHOULD be SUCCESS." + + "\n" + + "Depending on the value of the AnnouncementReason field, the OTA Requestor may have to query the OTA " + + "Provider. See Section 11.20.7.6.1.3, “AnnouncementReason Field” for the different values and their " + + "meaning." + + "\n" + + "If present, the MetadataForNode field’s may be used by a receiving OTA Requestor in any way it " + + "deems satisfactory. The MetadataForNode field SHOULD be empty under most normal operational " + + "circumstance, but can be useful in environments such as field trials or integration test " + + "environments to hint at additional capabilities which OTA Requestors may use in a particular " + + "Vendor-specific context.", + + xref: { document: "core", section: "11.20.7.6.1.5" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "AnnouncementReasonEnum", type: "enum8", xref: { document: "core", section: "11.20.7.4.1" } }, + + Field({ + name: "SimpleAnnouncement", id: 0x0, conformance: "M", + description: "An OTA Provider is announcing its presence.", + details: "An OTA Provider is announcing its presence, but there is no implication that an OTA Requestor would " + + "have a new Software Image available if it queried immediately.", + xref: { document: "core", section: "11.20.7.4.1.1" } + }), + + Field({ + name: "UpdateAvailable", id: 0x1, conformance: "M", + description: "An OTA Provider is announcing, either to a single Node or to a group of Nodes, that a new Software Image MAY be available.", + details: "An OTA Provider is announcing, either to a single Node or to a group of Nodes, that a new Software " + + "Image may be available. The details may only be obtained by executing a OTA Software Update Query " + + "procedure. A receiving OTA Requestor SHOULD only query the indicated OTA Provider at the " + + "ProviderLocation at its next upcoming OTA Provider query.", + xref: { document: "core", section: "11.20.7.4.1.2" } + }), + + Field({ + name: "UrgentUpdateAvailable", id: 0x2, conformance: "M", + description: "An OTA Provider is announcing, either to a single Node or to a group of Nodes, that a new Software Image MAY be available, which contains an update that needs to be applied urgently.", + + details: "An OTA Provider is announcing, either to a single Node or to a group of Nodes, that a new Software " + + "Image may be available, which contains an update that needs to be applied urgently. The details may " + + "only be obtained by executing a OTA Software Update Query procedure. A receiving OTA Requestor " + + "SHOULD query the indicated OTA Provider at the ProviderLocation after a random jitter delay between " + + "1 and 600 seconds. This particular reason SHOULD only be employed when an urgent update is " + + "available, such as an important security update, or just after initial commissioning of a device, " + + "to assist OTA Requestors in more rapidly obtaining updated software.", + + xref: { document: "core", section: "11.20.7.4.1.3" } + }) + ), + + Datatype( + { name: "UpdateStateEnum", type: "enum8", xref: { document: "core", section: "11.20.7.4.2" } }, + + Field({ + name: "Unknown", id: 0x0, conformance: "M", description: "Current state is not yet determined.", + details: "This value shall indicate that the current state is not yet determined. Nodes SHOULD attempt a " + + "better state reporting.", + xref: { document: "core", section: "11.20.7.4.2.1" } + }), + + Field({ + name: "Idle", id: 0x1, conformance: "M", + description: "Indicate a Node not yet in the process of software update.", + details: "This value shall indicate a Node not yet in the process of software update, for example because it " + + "is awaiting the moment when a query will be made.", + xref: { document: "core", section: "11.20.7.4.2.2" } + }), + + Field({ + name: "Querying", id: 0x2, conformance: "M", + description: "Indicate a Node in the process of querying an OTA Provider.", + details: "This value shall indicate a Node in the process of querying an OTA Provider with QueryImage " + + "command, including during the process of awaiting a response to that command.", + xref: { document: "core", section: "11.20.7.4.2.3" } + }), + + Field({ + name: "DelayedOnQuery", id: 0x3, conformance: "M", + description: "Indicate a Node waiting after a Busy response.", + details: "This value shall indicate a Node waiting because it received a prior QueryImageResponse with a " + + "Status field indicating Busy.", + xref: { document: "core", section: "11.20.7.4.2.4" } + }), + + Field({ + name: "Downloading", id: 0x4, conformance: "M", + description: "Indicate a Node currently in the process of downloading a software update.", + details: "This value shall indicate a Node currently in the process of downloading a software update.", + xref: { document: "core", section: "11.20.7.4.2.5" } + }), + + Field({ + name: "Applying", id: 0x5, conformance: "M", + description: "Indicate a Node currently in the process of verifying and applying a software update.", + details: "This value shall indicate a Node currently in the process of verifying and applying a software " + + "update.", + xref: { document: "core", section: "11.20.7.4.2.6" } + }), + + Field({ + name: "DelayedOnApply", id: 0x6, conformance: "M", + description: "Indicate a Node waiting caused by AwaitNextAction response.", + details: "This value shall indicate a Node waiting because it received a prior ApplyUpdateResponse with an " + + "Action field set to AwaitNextAction.", + xref: { document: "core", section: "11.20.7.4.2.7" } + }), + + Field({ + name: "RollingBack", id: 0x7, conformance: "M", + description: "Indicate a Node in the process of recovering to a previous version.", + details: "This value shall indicate a Node in the process of recovering to a previous version from a new " + + "version that was applied, but that could not remain in force, for reasons such as invalid data " + + "detected on boot, or significant runtime issues such as reboot loops. Eventually, the next state " + + "seen SHOULD be Unknown or Idle.", + xref: { document: "core", section: "11.20.7.4.2.8" } + }), + + Field({ + name: "DelayedOnUserConsent", id: 0x8, conformance: "M", + description: "Indicate a Node is capable of user consent." + }) + ), + + Datatype( + { name: "ChangeReasonEnum", type: "enum8", xref: { document: "core", section: "11.20.7.4.3" } }, + + Field({ + name: "Unknown", id: 0x0, conformance: "M", + description: "The reason for a state change is unknown.", + details: "This value shall indicate that the reason for a state change is unknown.", + xref: { document: "core", section: "11.20.7.4.3.1" } + }), + + Field({ + name: "Success", id: 0x1, conformance: "M", + description: "The reason for a state change is the success of a prior operation.", + details: "This value shall indicate that the reason for a state change is the success of a prior operation.", + xref: { document: "core", section: "11.20.7.4.3.2" } + }), + + Field({ + name: "Failure", id: 0x2, conformance: "M", + description: "The reason for a state change is the failure of a prior operation.", + details: "This value shall indicate that the reason for a state change is the failure of a prior operation.", + xref: { document: "core", section: "11.20.7.4.3.3" } + }), + + Field({ + name: "TimeOut", id: 0x3, conformance: "M", + description: "The reason for a state change is a time-out.", + details: "This value shall indicate that the reason for a state change is a time-out condition as determined " + + "by the OTA Requestor.", + xref: { document: "core", section: "11.20.7.4.3.4" } + }), + + Field({ + name: "DelayByProvider", id: 0x4, conformance: "O", + description: "The reason for a state change is a request by the OTA Provider to wait.", + details: "This value shall indicate that the reason for a state change is a request by the OTA Provider to " + + "await for a delay.", + xref: { document: "core", section: "11.20.7.4.3.5" } + }) + ), + + Datatype( + { + name: "ProviderLocation", type: "struct", + details: "This structure encodes a fabric-scoped location of an OTA provider on a given fabric.", + xref: { document: "core", section: "11.20.7.4.4" } + }, + + Field({ + name: "ProviderNodeId", id: 0x1, type: "node-id", access: "F", conformance: "M", + details: "This field shall contain the Node ID of the OTA Provider to contact within the Fabric identified by " + + "the FabricIndex.", + xref: { document: "core", section: "11.20.7.4.4.1" } + }), + + Field({ + name: "Endpoint", id: 0x2, type: "endpoint-no", access: "F", conformance: "M", + details: "This field shall contain the endpoint number which has the OTA Provider device type and OTA " + + "Software Update Provider cluster server on the ProviderNodeID. This is provided to avoid having to " + + "do discovery of the location of that endpoint by walking over all endpoints and checking their " + + "Descriptor Cluster.", + xref: { document: "core", section: "11.20.7.4.4.2" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) + ), + + Datatype( + { + name: "SoftwareVersionCertificationStatusEnum", type: "enum8", + details: "The values 0 through 2 shall correspond to the values 0 through 2 used in certification_type in the " + + "Certification Declaration.", + xref: { document: "core", section: "11.23.8.2" } + }, + + Field({ + name: "DevTest", id: 0x0, conformance: "M", + description: "used for development and test purposes (These will typically not be placed in DCL)" + }), + Field({ + name: "Provisional", id: 0x1, conformance: "M", + description: "used for a SoftwareVersion when going into certification testing (These might or might not be placed in DCL, depending on CSA policy and procedures)" + }), + Field({ + name: "Certified", id: 0x2, conformance: "M", + description: "used for a SoftwareVersion which has been certified" + }), + Field({ + name: "Revoked", id: 0x3, conformance: "M", + description: "used for a SoftwareVersion which has been revoked" + }) + ), + + Cluster( + { + name: "JointFabricDatastoreCluster", id: 0x752, classification: "node", pics: "JFDS", + + details: "The Joint Fabric Datastore Cluster is a cluster that provides a mechanism for the Joint Fabric " + + "Administrators to manage the set of Nodes, Groups, and Group membership among Nodes in the Joint " + + "Fabric." + + "\n" + + "When an Ecosystem Administrator Node is commissioned onto the Joint Fabric, the Ecosystem " + + "Administrator Node has no knowledge of what Nodes and Groups are present, or what set-up " + + "information related to the Joint Fabric is provided by the user. To address lack of knowledge, the " + + "Joint Fabric Datastore provides the information required for all Ecosystem Administrators to " + + "maintain a consistent view of the Joint Fabric including Nodes, Groups, settings and privileges." + + "\n" + + "The Joint Fabric Datastore cluster server shall only be accessible on a Node which is acting as the " + + "Joint Fabric Anchor Administrator. When not acting as the Joint Fabric Anchor Administrator, the " + + "Joint Fabric Datastore cluster shall NOT be accessible." + + "\n" + + "The Admin level of access to the Joint Fabric Datastore cluster server shall be limited to JF " + + "Administrator Nodes identified using the Administrator CAT." + + "\n" + + "NOTE Support for Joint Fabric Datastore cluster is provisional.", + + xref: { document: "core", section: "11.24" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "AnchorRootCa", id: 0x0, type: "octstr", access: "R S A", conformance: "M", + details: "This shall indicate the Anchor Root CA used to sign all NOC Issuers in the Joint Fabric. A null " + + "value indicates that the Joint Fabric is not yet formed.", + xref: { document: "core", section: "11.24.6.1" } + }), + + Attribute({ + name: "AnchorNodeId", id: 0x1, type: "node-id", access: "R S A", conformance: "M", + details: "This shall indicate the Node identifier of the Joint Fabric Anchor Root CA.", + xref: { document: "core", section: "11.24.6.2" } + }), + Attribute({ + name: "AnchorVendorId", id: 0x2, type: "vendor-id", access: "R S A", conformance: "M", + details: "This shall indicate the Vendor identifier of the Joint Fabric Anchor Root CA.", + xref: { document: "core", section: "11.24.6.3" } + }), + + Attribute({ + name: "FriendlyName", id: 0x3, type: "string", access: "R S A", conformance: "M", + constraint: "max 32", + details: "Friendly name for this fabric which can be propagated to nodes.", + xref: { document: "core", section: "11.24.6.4" } + }), + + Attribute( + { + name: "GroupKeySetList", id: 0x4, type: "list", access: "R S A", conformance: "M", + details: "This shall indicate the list of GroupKeySetStruct used in the Joint Fabric." + + "\n" + + "This attribute shall contain at least one entry, the IPK, which has GroupKeySetID of 0.", + xref: { document: "core", section: "11.24.6.5" } + }, + + Field({ name: "entry", type: "GroupKeyManagement.GroupKeySetStruct" }) + ), + + Attribute( + { + name: "GroupList", id: 0x5, type: "list", access: "R S A", conformance: "M", + details: "This shall indicate the list of groups in the Joint Fabric.", + xref: { document: "core", section: "11.24.6.6" } + }, + Field({ name: "entry", type: "DatastoreGroupInformationEntry" }) + ), + + Attribute( + { + name: "NodeList", id: 0x6, type: "list", access: "R S A", conformance: "M", + details: "This shall indicate the list of nodes in the Joint Fabric.", + xref: { document: "core", section: "11.24.6.7" } + }, + Field({ name: "entry", type: "DatastoreNodeInformationEntry" }) + ), + + Attribute( + { + name: "AdminList", id: 0x7, type: "list", access: "R S A", conformance: "M", + + details: "This shall indicate the list of administrators in the Joint Fabric." + + "\n" + + "Only one Administrator may serve as the Anchor Root CA and Anchor Fabric Administrator and shall " + + "have index value 0. All other Joint Fabric Administrators shall be referenced at index 1 or greater." + + "\n" + + "A null value or empty list indicates that the Joint Fabric is not yet formed.", + + xref: { document: "core", section: "11.24.6.8" } + }, + + Field({ name: "entry", type: "DatastoreAdministratorInformationEntry" }) + ), + + Attribute({ + name: "StatusEntry", id: 0x8, type: "DatastoreAdministratorInformationEntry", access: "R S A", + conformance: "M", + details: "This shall indicate the current state of the Joint Fabric Datastore Cluster." + + "\n" + + "The Committed status indicates the DataStore is ready for use. The Pending status indicates that " + + "the DataStore is not yet ready for use. The DeletePending status indicates that the DataStore is in " + + "the process of being transferred to another Joint Fabric Anchor Administrator.", + xref: { document: "core", section: "11.24.6.9" } + }), + + Command({ + name: "Section112471", id: 0x0, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112472", id: 0x1, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112473", id: 0x2, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112474", id: 0x3, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112475", id: 0x4, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112476", id: 0x5, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112477", id: 0x6, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112478", id: 0x7, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112479", id: 0x8, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124710", id: 0x9, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124711", id: 0xa, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124712", id: 0xb, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124713", id: 0xc, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124714", id: 0xd, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124715", id: 0xe, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124716", id: 0xf, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124717", id: 0x10, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124718", id: 0x11, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124719", id: 0x12, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124720", id: 0x13, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + + Datatype( + { name: "DatastoreStateEnum", type: "enum8", xref: { document: "core", section: "11.24.5.1" } }, + Field({ name: "Pending", id: 0x0, conformance: "M", description: "Target device operation is pending" }), + Field({ name: "Committed", id: 0x1, conformance: "M", description: "Target device operation has been committed" }), + Field({ + name: "DeletePending", id: 0x2, conformance: "M", + description: "Target device delete operation is pending" + }) + ), + + Datatype( + { name: "DatastoreStatusEntry", type: "struct", xref: { document: "core", section: "11.24.5.2" } }, + Field({ + name: "State", id: 0x0, type: "DatastoreStateEnum", access: "R F V", conformance: "M", default: 0, + details: "This field shall contain the current state of the target device operation.", + xref: { document: "core", section: "11.24.5.2.1" } + }), + Field({ + name: "UpdateTimestamp", id: 0x1, type: "epoch-s", access: "R F V", conformance: "M", default: null, + details: "This field shall contain the timestamp of the last update.", + xref: { document: "core", section: "11.24.5.2.2" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreNodeKeyEntry", type: "struct", xref: { document: "core", section: "11.24.5.3" } }, + Field({ name: "GroupKeySetId", id: 0x0, type: "uint16", access: "R F V", conformance: "M" }), + Field({ + name: "StatusEntry", id: 0x1, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether entry in this list is pending, committed, or delete-pending.", + xref: { document: "core", section: "11.24.5.3.2" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "DatastoreGroupInformationEntry", type: "struct", + xref: { document: "core", section: "11.24.5.4" } + }, + Field({ + name: "GroupId", id: 0x0, type: "uint64", access: "R F V", conformance: "M", + details: "The unique identifier for the group.", + xref: { document: "core", section: "11.24.5.4.1" } + }), + + Field({ + name: "FriendlyName", id: 0x1, type: "string", access: "R F V", conformance: "M", + constraint: "max 32", + details: "The friendly name for the group.", + xref: { document: "core", section: "11.24.5.4.2" } + }), + + Field({ + name: "GroupKeySetId", id: 0x2, type: "uint16", access: "R F V", conformance: "M", + constraint: "1 to 65535", + details: "The unique identifier for the group key set.", + xref: { document: "core", section: "11.24.5.4.3" } + }), + + Field({ + name: "GroupCat", id: 0x3, type: "uint16", access: "R F V", conformance: "M", + constraint: "1 to 65535", + details: "CAT value for this group. This is used for control of individual members of a group (non-broadcast " + + "commands).", + xref: { document: "core", section: "11.24.5.4.4" } + }), + + Field({ + name: "GroupCatVersion", id: 0x4, type: "uint16", access: "R F V", conformance: "M", + constraint: "1 to 65535", + details: "Current version number for this CAT.", + xref: { document: "core", section: "11.24.5.4.5" } + }), + + Field({ + name: "GroupPermission", id: 0x5, type: "AccessControl.AccessControlEntryPrivilegeEnum", + access: "R F V", conformance: "M", + details: "The permission level associated with ACL entries for this group. There should be only one " + + "Administrator group per fabric, and at most one Manage group per Ecosystem (Vendor Entry).", + xref: { document: "core", section: "11.24.5.4.6" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreBindingEntry", type: "struct", xref: { document: "core", section: "11.24.5.4.7" } }, + Field({ + name: "ListId", id: 0x0, type: "uint16", access: "R F V", conformance: "M", + details: "The unique identifier for the Binding entry in the Datastore’s list of DatastoreBindingEntry.", + xref: { document: "core", section: "11.24.5.4.7.1" } + }), + + Field({ + name: "Binding", id: 0x1, type: "Binding.TargetStruct", access: "R F V", conformance: "M", + constraint: "desc", + details: "The binding target structure.", + xref: { document: "core", section: "11.24.5.4.7.2" } + }), + + Field({ + name: "StatusEntry", id: 0x2, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether entry in this list is pending, committed, or delete-pending.", + xref: { document: "core", section: "11.24.5.4.7.3" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreGroupIDEntry", type: "struct", xref: { document: "core", section: "11.24.5.5" } }, + Field({ + name: "GroupId", id: 0x0, type: "group-id", access: "R F V", conformance: "M", + details: "The unique identifier for the group.", + xref: { document: "core", section: "11.24.5.5.1" } + }), + Field({ + name: "StatusEntry", id: 0x1, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether entry in this list is pending, committed, or delete-pending.", + xref: { document: "core", section: "11.24.5.5.2" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreEndpointEntry", type: "struct", xref: { document: "core", section: "11.24.5.6" } }, + Field({ + name: "EndpointId", id: 0x0, type: "endpoint-no", access: "R F V", conformance: "M", + details: "The unique identifier for the endpoint.", + xref: { document: "core", section: "11.24.5.6.1" } + }), + Field({ + name: "NodeId", id: 0x1, type: "node-id", access: "R F V", conformance: "M", + details: "The unique identifier for the node.", + xref: { document: "core", section: "11.24.5.6.2" } + }), + + Field({ + name: "FriendlyName", id: 0x2, type: "string", access: "R F V", conformance: "M", + constraint: "max 32", + details: "Friendly name for this endpoint which is propagated to nodes. Any changes to Friendly Name or Group " + + "Id List (add/remove entry) must follow the pending→committed workflow with current state reflected " + + "in the Status Entry.", + xref: { document: "core", section: "11.24.5.6.3" } + }), + + Field({ + name: "StatusEntry", id: 0x3, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether changes to Friendly Name are pending or committed.", + xref: { document: "core", section: "11.24.5.6.4" } + }), + + Field( + { + name: "GroupIdList", id: 0x4, type: "list", access: "R F V", conformance: "M", + details: "List of Group IDs that this endpoint is a member of. Any changes to Group Id List (add/remove " + + "entry) must follow the pending→committed workflow with current state reflected in the Status Entry.", + xref: { document: "core", section: "11.24.5.6.5" } + }, + + Field({ name: "entry", type: "DatastoreGroupIDEntry" }) + ), + + Field( + { + name: "BindingList", id: 0x5, type: "list", access: "R F V", conformance: "M", + details: "List of Binding Targets for this endpoint. Any changes to Binding List (add/remove entry) must " + + "follow the pending→committed workflow with current state reflected in the Status Entry.", + xref: { document: "core", section: "11.24.5.6.6" } + }, + + Field({ name: "entry", type: "DatastoreBindingEntry" }) + ), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreACLEntry", type: "struct", xref: { document: "core", section: "11.24.5.7" } }, + Field({ + name: "ListId", id: 0x0, type: "uint16", access: "R F V", conformance: "M", + details: "The unique identifier for the ACL entry in the Datastore’s list of DatastoreACLEntry.", + xref: { document: "core", section: "11.24.5.7.1" } + }), + + Field({ + name: "AclEntry", id: 0x1, type: "AccessControl.AccessControlEntryStruct", access: "R F V", + conformance: "M", + details: "The Access Control Entry structure.", + xref: { document: "core", section: "11.24.5.7.2" } + }), + + Field({ + name: "StatusEntry", id: 0x2, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether entry in this list is pending, committed, or delete-pending.", + xref: { document: "core", section: "11.24.5.7.3" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreNodeInformationEntry", type: "struct", xref: { document: "core", section: "11.24.5.8" } }, + Field({ + name: "NodeId", id: 0x1, type: "node-id", access: "R F V", conformance: "M", + details: "The unique identifier for the node.", + xref: { document: "core", section: "11.24.5.8.1" } + }), + + Field({ + name: "FriendlyName", id: 0x2, type: "string", access: "R F V", conformance: "M", + constraint: "max 32", + details: "Friendly name for this node which is not propagated to nodes.", + xref: { document: "core", section: "11.24.5.8.2" } + }), + + Field({ + name: "CommissioningStatusEntry", id: 0x3, type: "DatastoreStatusEntry", access: "R F V", + conformance: "M", + details: "Set to pending prior to completing commissioning, and set to completed after commissioning complete " + + "is successful.", + xref: { document: "core", section: "11.24.5.8.3" } + }), + + Field( + { + name: "NodeKeySetList", id: 0x4, type: "list", access: "R F V", conformance: "M", + details: "List of Key Set information for the given Node. Updates to the Group Key List must follow the " + + "pending→committed workflow with current state reflected in the Status Entry for the corresponding " + + "entry in the list.", + xref: { document: "core", section: "11.24.5.8.4" } + }, + + Field({ name: "entry", type: "DatastoreNodeKeyEntry" }) + ), + + Field( + { + name: "AclList", id: 0x5, type: "list", access: "R F V", conformance: "M", + details: "List of ACL entries. Group membership for this node is inferred from the ACLs. Client access to a " + + "Node Information Entry will be determined from the ACL List. Any changes to ACL List (add/remove " + + "entry) must follow the pending→committed workflow with current state reflected in the Status Entry " + + "for the corresponding entry in the list.", + xref: { document: "core", section: "11.24.5.8.5" } + }, + + Field({ name: "entry", type: "DatastoreACLEntry" }) + ), + + Field( + { + name: "EndpointList", id: 0x6, type: "list", access: "R F V", conformance: "M", + details: "The list of endpoints for this node. Any changes to Endpoint List (add/remove entry) must follow " + + "the pending→committed workflow with current state reflected in the Status Entry for the " + + "corresponding entry in the list.", + xref: { document: "core", section: "11.24.5.8.6" } + }, + + Field({ name: "entry", type: "DatastoreEndpointEntry" }) + ), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "DatastoreAdministratorInformationEntry", type: "struct", + xref: { document: "core", section: "11.24.5.9" } + }, + Field({ + name: "NodeId", id: 0x1, type: "node-id", access: "R F V", conformance: "M", + details: "The unique identifier for the node.", + xref: { document: "core", section: "11.24.5.9.1" } + }), + + Field({ + name: "FriendlyName", id: 0x2, type: "string", access: "R F V", conformance: "M", + constraint: "max 32", + details: "Friendly name for this node which is not propagated to nodes.", + xref: { document: "core", section: "11.24.5.9.2" } + }), + + Field({ + name: "VendorId", id: 0x3, type: "vendor-id", access: "R F V", conformance: "M", + details: "The Vendor ID for the node.", + xref: { document: "core", section: "11.24.5.9.3" } + }), + Field({ + name: "Icac", id: 0x4, type: "octstr", access: "R F V", conformance: "M", constraint: "max 400", + details: "The ICAC used to issue the NOC.", + xref: { document: "core", section: "11.24.5.9.4" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) + ), + + Cluster( + { + name: "JointFabricPki", id: 0x753, classification: "node", pics: "JFPKI", + details: "An instance of the Joint Fabric PKI Cluster only applies to Joint Fabric Administrator nodes " + + "fulfilling the role of Anchor CA." + + "\n" + + "NOTE Support for Joint Fabric PKI Cluster is provisional.", + xref: { document: "core", section: "11.25" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Command( + { + name: "IcacsrRequest", id: 0x0, access: "A", conformance: "M", direction: "request", + response: "IcacsrResponse", + details: "This command shall be generated and executed during the Joint Commissioning Method steps and " + + "subsequently respond in the form of an ICACSRResponse command." + + "\n" + + "Check ICA Cross Signing for details about the generation and contents of the ICACSR.", + xref: { document: "core", section: "11.25.5.1" } + }, + + Field({ name: "Icacsr", id: 0x0, type: "octstr", conformance: "M", constraint: "max 400" }) + ), + + Command( + { + name: "IcacsrResponse", id: 0x1, access: "A", conformance: "M", direction: "response", + details: "This command shall be generated in response to the ICACSRRequest command. Check ICA Cross Signing " + + "for details about the generation and contents of ICAC.", + xref: { document: "core", section: "11.25.5.2" } + }, + + Field({ + name: "StatusCode", id: 0x0, type: "IcacsrRequestStatusEnum", conformance: "M", + details: "This field shall contain an ICACSRRequestStatusEnum value representing the status of the Section " + + "11.25.5.1, “ICACSRRequest Command” operation.", + xref: { document: "core", section: "11.25.5.2.1" } + }), + + Field({ + name: "Icac", id: 0x1, type: "octstr", conformance: "O", constraint: "max 400", + details: "If present, it shall contain the NOC Issuer Certificate in PEM format.", + xref: { document: "core", section: "11.25.5.2.2" } + }) + ), + + Command({ + name: "TransferAnchorRequest", id: 0x2, access: "A", conformance: "M", direction: "request", + response: "TransferAnchorResponse", + xref: { document: "core", section: "11.25.5" } + }), + Command({ + name: "TransferAnchorResponse", id: 0x3, access: "A", conformance: "M", direction: "response", + xref: { document: "core", section: "11.25.5" } + }), + Command({ + name: "TransferAnchorComplete", id: 0x4, access: "A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.25.5" } + }), + + Datatype( + { + name: "IcacsrRequestStatusEnum", type: "enum8", + details: "This enumeration is used by the ICACSRResponse command to convey the detailed outcome of this " + + "cluster’s ICACSRRequest command.", + xref: { document: "core", section: "11.25.4.1" } + }, + + Field({ name: "Ok", id: 0x0, conformance: "M", description: "No error" }), + Field({ + name: "InvalidIcaCsrFormat", id: 0x1, conformance: "M", + description: "The ICACSR in the request is not compliant to PKCS #10 rules" + }), + Field({ + name: "InvalidIcaCsrSignature", id: 0x2, conformance: "M", + description: "The ICACSR in the request has an incorrect signature" + }), + Field({ + name: "FailedDclVendorIdValidation", id: 0x3, conformance: "M", + description: "DCL Vendor ID validation failed" + }), + Field({ name: "NotAnIcac", id: 0x4, conformance: "M", description: "DCL returned certificate is not an ICAC" }), + Field({ + name: "BusyAnchorTransfer", id: 0x5, conformance: "M", + description: "Error due to an in progress Anchor Transfer" + }), + Field({ name: "IcaCsrSigningFailed", id: 0x6, conformance: "M", description: "Signing the ICA CSR failed" }), + Field({ name: "IcaCsrRequestNoUserConsent", id: 0x7, conformance: "M", description: "No user consent" }) + ), + + Datatype( + { + name: "TransferAnchorResponseStatusEnum", type: "enum8", + details: "This enumeration is used by the TransferAnchorResponse command to convey the detailed outcome of " + + "this cluster’s TransferAnchorRequest command.", + xref: { document: "core", section: "11.25.4.2" } + }, + + Field({ name: "Ok", id: 0x0, conformance: "M", description: "No error" }), + Field({ + name: "TransferAnchorStatusDatastoreBusy", id: 0x1, conformance: "M", + description: "Anchor Transfer was not started due to on- going Datastore operations" + }), + Field({ + name: "TransferAnchorStatusNoUserConsent", id: 0x2, conformance: "M", + description: "User has not consented for Anchor Transfer" + }) + ) + ), + + Cluster( + { + name: "CommissionerControl", id: 0x751, classification: "node", pics: "CCTRL", + + details: "The Commissioner Control Cluster supports the ability for clients to request the commissioning of " + + "themselves or other nodes onto a fabric which the cluster server can commission onto. An example " + + "use case is ecosystem to ecosystem Fabric Synchronization setup." + + "\n" + + "The generalized flow supported by the Commissioner Control Cluster can be seen in the following " + + "diagram." + + "\n" + + "Figure 101. Commissioner Control Cluster - General Flow", + + xref: { document: "core", section: "11.26" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "SupportedDeviceCategories", id: 0x0, type: "SupportedDeviceCategoryBitmap", access: "R M", + conformance: "M", default: 0, + details: "Indicates the device categories specified in SupportedDeviceCategoryBitmap that are supported by " + + "this Commissioner Control Cluster server." + + "\n" + + "A client shall NOT send the RequestCommissioningApproval command if the intended node to be " + + "commissioned does not conform to any of the values specified in SupportedDeviceCategories.", + xref: { document: "core", section: "11.26.5.1" } + }), + + Event( + { + name: "CommissioningRequestResult", id: 0x0, access: "S M", conformance: "M", priority: "info", + + details: "This event shall be generated by the server following a RequestCommissioningApproval command which " + + "the server responded to with SUCCESS." + + "\n" + + "NOTE" + + "\n" + + "The approval is valid for a period determined by the manufacturer and characteristics of the node " + + "presenting the Commissioner Control Cluster. Clients SHOULD send the CommissionNode command " + + "immediately upon receiving a CommissioningRequestResult event." + + "\n" + + "11.26.7.2. RequestID / ClientNodeID Fields" + + "\n" + + "The RequestID shall match the RequestID provided to RequestCommissioningApproval and the " + + "ClientNodeID shall match the NodeID of the client which generated the RequestCommissioningAp" + + "\n" + + "proval command.", + + xref: { document: "core", section: "11.26.7.1" } + }, + + Field({ name: "RequestId", id: 0x0, type: "uint64", access: "S", conformance: "M" }), + Field({ name: "ClientNodeId", id: 0x1, type: "node-id", access: "S", conformance: "M" }), + Field({ name: "StatusCode", id: 0x2, type: "status", access: "S", conformance: "M", constraint: "desc" }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Command( + { + name: "RequestCommissioningApproval", id: 0x0, access: "M", conformance: "M", direction: "request", + response: "status", + + details: "This command is sent by a client to request approval for a future CommissionNode call. This is " + + "required to be a separate step in order to provide the server time for interacting with a user " + + "before informing the client that the CommissionNode operation may be successful." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "The server may request approval from the user, but it is not required." + + "\n" + + "The server shall always return SUCCESS to a correctly formatted RequestCommissioningApproval " + + "command, and then generate a CommissioningRequestResult event associated with the command’s" + + "\n" + + "accessing fabric once the result is ready." + + "\n" + + "Clients SHOULD avoid using the same RequestID. If the RequestID and client NodeID of a " + + "RequestCommissioningApproval match a previously received RequestCommissioningApproval and the " + + "server has not returned an error or completed commissioning of a device for the prior request, then " + + "the server SHOULD return FAILURE." + + "\n" + + "The parameters for RequestCommissioningApproval command are as follows:", + + xref: { document: "core", section: "11.26.6.1" } + }, + + Field({ name: "RequestId", id: 0x0, type: "uint64", conformance: "M" }), + Field({ name: "VendorId", id: 0x1, type: "vendor-id", conformance: "M" }), + Field({ name: "ProductId", id: 0x2, type: "uint16", conformance: "M" }), + Field({ name: "Label", id: 0x3, type: "string", conformance: "O", constraint: "max 64" }) + ), + + Command( + { + name: "CommissionNode", id: 0x1, access: "M", conformance: "M", direction: "request", + response: "ReverseOpenCommissioningWindow", + + details: "This command is sent by a client to request that the server begins commissioning a previously " + + "approved request." + + "\n" + + "The server shall return FAILURE if the CommissionNode command is not sent from the same NodeID and " + + "on the same fabric as the RequestCommissioningApproval or if the provided RequestID to " + + "CommissionNode does not match the value provided to RequestCommissioningApproval." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of" + + "\n" + + "UNSUPPORTED_ACCESS." + + "\n" + + "Upon receipt, the server shall respond with ReverseOpenCommissioningWindow if " + + "CommissioningRequestResult was generated with StatusCode of SUCCESS for the matching RequestID " + + "field and NodeID of the client." + + "\n" + + "The server shall return FAILURE if the CommissionNode command is received after the server has " + + "already responded to a client with ReverseOpenCommissioningWindow for a matching RequestID field " + + "and NodeID of the client unless the client has sent another RequestCommissioningApproval and " + + "received an additional CommissioningRequestResult." + + "\n" + + "The parameters for CommissionNode command are as follows:", + + xref: { document: "core", section: "11.26.6.5" } + }, + + Field({ name: "RequestId", id: 0x0, type: "uint64", conformance: "M" }), + Field({ + name: "ResponseTimeoutSeconds", id: 0x1, type: "uint16", conformance: "M", constraint: "30 to 120", + default: 30 + }) + ), + + Command( + { + name: "ReverseOpenCommissioningWindow", id: 0x2, conformance: "M", direction: "response", + + details: "When received within the timeout specified by ResponseTimeoutSeconds in the CommissionNode command, " + + "the client shall open a commissioning window on a node which matches the VendorID and ProductID " + + "provided in the associated RequestCommissioningApproval command." + + "\n" + + "When commissioning this node, the server shall check that the VendorID and ProductID fields " + + "provided in the RequestCommissioningApproval command match the VendorID and ProductID attributes of " + + "the Basic Information Cluster which have already been verified during the Device Attestation " + + "Procedure. If they do not match, the server shall NOT complete commissioning and SHOULD indicate an " + + "error to the user." + + "\n" + + "NOTE" + + "\n" + + "This is an alias onto the Open Commissioning Window command within the Administrator Commissioning " + + "Cluster. Refer to the Open Commissioning Window command for a description of the command behavior " + + "and parameters." + + "\n" + + "The parameters for ReverseOpenCommissioningWindow command are as follows:", + + xref: { document: "core", section: "11.26.6.8" } + }, + + Field({ name: "CommissioningTimeout", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }), + Field({ name: "PakePasscodeVerifier", id: 0x1, type: "octstr", conformance: "M" }), + Field({ name: "Discriminator", id: 0x2, type: "uint16", conformance: "M", constraint: "max 4095" }), + Field({ name: "Iterations", id: 0x3, type: "uint32", conformance: "M", constraint: "1000 to 100000" }), + Field({ name: "Salt", id: 0x4, type: "octstr", conformance: "M", constraint: "16 to 32" }) + ), + + Datatype( + { name: "SupportedDeviceCategoryBitmap", type: "map32", xref: { document: "core", section: "11.26.4.1" } }, + + Field({ + name: "FabricSynchronization", constraint: "0", + description: "Aggregators which support Fabric Synchronization may be commissioned.", + details: "The FabricSynchronization bit shall be set to 1 if and only if the server supports commissioning " + + "nodes that support Fabric Synchronization.", + xref: { document: "core", section: "11.26.4.1.1" } + }) + ) + ), + + DeviceType( + { name: "Base", classification: "base", xref: { document: "device", section: "1.1" } }, + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "Zha", description: "Zigbee Home Automation standard", + xref: { document: "device", section: "1.1.3.1" } + }), + Field({ + name: "Zse", description: "Zigbee Smart Energy standard", + xref: { document: "device", section: "1.1.3.1" } + }), + Field({ + name: "Gp", description: "Zigbee Green Power standard", + xref: { document: "device", section: "1.1.3.1" } + }), + Field({ name: "Zigbee", description: "Zigbee standard", xref: { document: "device", section: "1.1.3.1" } }), + Field({ + name: "SuZi", description: "Zigbee PRO Sub-GHz standard", + xref: { document: "device", section: "1.1.3.1" } + }), + Field({ name: "Matter", description: "Matter standard", xref: { document: "device", section: "1.1.3.1" } }), + Field({ + name: "LanguageLocale", + description: "The node supports localization for conveying text to the user", + xref: { document: "device", section: "1.1.3.3" } + }), + Field({ + name: "TimeLocale", description: "The node supports localization for conveying time to the user", + xref: { document: "device", section: "1.1.3.3" } + }), + Field({ + name: "UnitLocale", + description: "The node supports localization for conveying units of measure to the user", + xref: { document: "device", section: "1.1.3.3" } + }), + Field({ + name: "Sit", description: "The node is a short idle time intermittently connected device", + xref: { document: "device", section: "1.1.4" } + }), + Field({ + name: "Lit", description: "The node is a long idle time intermittently connected device", + xref: { document: "device", section: "1.1.4" } + }), + Field({ + name: "Active", description: "The node is always able to communicate", + xref: { document: "device", section: "1.1.4" } + }), + Field({ name: "Node", xref: { document: "device", section: "1.1.5" } }), + Field({ name: "App", xref: { document: "device", section: "1.1.5" } }), + Field({ name: "Simple", xref: { document: "device", section: "1.1.5" } }), + Field({ name: "Dynamic", xref: { document: "device", section: "1.1.5" } }), + Field({ name: "Composed", xref: { document: "device", section: "1.1.5" } }), + Field({ name: "Client", xref: { document: "device", section: "1.1.6" } }), + Field({ name: "Server", xref: { document: "device", section: "1.1.6" } }), + Field({ name: "Duplicate", xref: { document: "device", section: "1.1.6" } }), + Field({ name: "BridgedPowerSourceInfo", xref: { document: "device", section: "1.1.6" } }) + ), + + Requirement( + { + name: "Descriptor", id: 0x1d, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "1.1.7" } + }, + Requirement({ name: "TAGLIST", conformance: "Duplicate", element: "feature" }) + ), + + Requirement({ + name: "Binding", id: 0x1e, conformance: "Simple & Client", element: "serverCluster", + xref: { document: "device", section: "1.1.7" } + }), + Requirement({ + name: "FixedLabel", id: 0x40, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "1.1.7" } + }), + Requirement({ + name: "UserLabel", id: 0x41, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "1.1.7" } + }) + ), + + DeviceType( + { + name: "RootNode", id: 0x16, category: "Utility", classification: "node", + + details: "This defines conformance for a root node endpoint (see System Model specification). This endpoint " + + "is akin to a \"read me first\" endpoint that describes itself and the other endpoints that make up " + + "the node." + + "\n" + + " • Device types with Endpoint scope shall NOT be supported on the same endpoint as this device " + + " type." + + "\n" + + " • Clusters with an Application role shall NOT be supported on the same endpoint as this device " + + " type." + + "\n" + + " • Other device types with Node scope may be supported on the same endpoint as this device type.", + + xref: { document: "device", section: "2.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 22, revision: 3 } ], element: "attribute" }) + ), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "CustomNetworkConfig", + description: "The node only supports out-of-band-configured networking (e.g. rich user interface, manufacturer-specific means, custom commissioning flows, or future IP-compliant network technology not yet directly supported by NetworkCommissioning cluster).", + xref: { document: "device", section: "2.1.3" } + }), + Field({ + name: "ManagedAclAllowed", + description: "The node has at least one endpoint where some Device Type present on the endpoint has a Device Library element requirement table entry that sets this condition to true.", + xref: { document: "device", section: "2.1.3" } + }) + ), + + Requirement({ + name: "BasicInformation", id: 0x28, conformance: "M", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + + Requirement( + { + name: "AccessControl", id: 0x1f, conformance: "M", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }, + Requirement({ name: "MNGD", conformance: "[ManagedAclAllowed]", constraint: "desc", element: "feature" }) + ), + + Requirement({ + name: "PowerSourceConfiguration", id: 0x2e, conformance: "O, D", element: "serverCluster", + quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "TimeSynchronization", id: 0x38, conformance: "O", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "GroupKeyManagement", id: 0x3f, conformance: "M", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "GeneralCommissioning", id: 0x30, conformance: "M", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "NetworkCommissioning", id: 0x31, conformance: "!CustomNetworkConfig", + element: "serverCluster", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "AdministratorCommissioning", id: 0x3c, conformance: "M", element: "serverCluster", + quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "OperationalCredentials", id: 0x3e, conformance: "M", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "LocalizationConfiguration", id: 0x2b, conformance: "LanguageLocale", + element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "TimeFormatLocalization", id: 0x2c, conformance: "TimeLocale", element: "serverCluster", + quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "UnitLocalization", id: 0x2d, conformance: "UnitLocale", element: "serverCluster", + quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "GeneralDiagnostics", id: 0x33, conformance: "M", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "DiagnosticLogs", id: 0x32, conformance: "O", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "SoftwareDiagnostics", id: 0x34, conformance: "O", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "EthernetNetworkDiagnostics", id: 0x37, conformance: "[Ethernet]", element: "serverCluster", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "WiFiNetworkDiagnostics", id: 0x36, conformance: "[Wi, Fi]", element: "serverCluster", + xref: { document: "device", section: "2.1.5" } + }), + Requirement({ + name: "ThreadNetworkDiagnostics", id: 0x35, conformance: "[Thread]", element: "serverCluster", + xref: { document: "device", section: "2.1.5" } + }), + + Requirement( + { + name: "IcdManagement", id: 0x46, conformance: "SIT | LIT", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }, + Requirement({ name: "LONGIDLETIMESUPPORT", conformance: "LIT", element: "feature" }) + ) + ), + + DeviceType( + { + name: "PowerSource", id: 0x11, category: "Utility", classification: "utility", + xref: { document: "device", section: "2.2" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 17, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "PowerSource", id: 0x2f, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.2.3" } + }) + ), + + DeviceType( + { + name: "OtaRequestor", id: 0x12, category: "Utility", classification: "utility", + details: "An OTA Requestor is a device that is capable of receiving an OTA software update.", + xref: { document: "device", section: "2.3" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 18, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "OtaSoftwareUpdateRequestor", id: 0x2a, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.3.3" } + }), + Requirement({ + name: "OtaSoftwareUpdateProvider", id: 0x29, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "2.3.3" } + }) + ), + + DeviceType( + { + name: "OtaProvider", id: 0x14, category: "Utility", classification: "utility", + details: "An OTA Provider is a node that is capable of providing an OTA software update to other nodes on the " + + "same fabric.", + xref: { document: "device", section: "2.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 20, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "OtaSoftwareUpdateRequestor", id: 0x2a, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "2.4.3" } + }), + Requirement({ + name: "OtaSoftwareUpdateProvider", id: 0x29, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.4.3" } + }) + ), + + DeviceType( + { + name: "BridgedNode", id: 0x13, category: "Utility", classification: "utility", + details: "This defines conformance for a Bridged Node root endpoint. This endpoint is akin to a \"read me " + + "first\" endpoint that describes itself and any other endpoints that make up the Bridged Node. A " + + "Bridged Node endpoint represents a device on a foreign network, but is not the root endpoint of the " + + "bridge itself.", + xref: { document: "device", section: "2.5" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 19, revision: 3 } ], element: "attribute" }) + ), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "FabricSynchronizedNode", description: "See description below.", + xref: { document: "device", section: "2.5.3" } + }) + ), + + Requirement({ + name: "BridgedDeviceBasicInformation", id: 0x39, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.5.5" } + }), + Requirement({ + name: "PowerSourceConfiguration", id: 0x2e, conformance: "BridgedPowerSourceInfo, D", + element: "serverCluster", + xref: { document: "device", section: "2.5.5" } + }), + Requirement({ + name: "PowerSource", id: 0x2f, conformance: "BridgedPowerSourceInfo", element: "serverCluster", + xref: { document: "device", section: "2.5.5" } + }), + Requirement({ + name: "EcosystemInformation", id: 0x750, conformance: "FabricSynchronizedNode, O", + element: "serverCluster", + xref: { document: "device", section: "2.5.5" } + }), + Requirement({ + name: "AdministratorCommissioning", id: 0x3c, conformance: "FabricSynchronizedNode", + element: "serverCluster", + xref: { document: "device", section: "2.5.5" } + }) + ), + + DeviceType( + { + name: "ElectricalSensor", id: 0x510, category: "Utility", classification: "utility", + details: "An Electrical Sensor device measures the electrical power and/or energy being imported and/or " + + "exported.", + xref: { document: "device", section: "2.6" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 1296, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "PowerTopology", id: 0x9c, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.6.4" } + }), + Requirement({ + name: "ElectricalPowerMeasurement", id: 0x90, conformance: "O.a+", element: "serverCluster", + xref: { document: "device", section: "2.6.4" } + }), + Requirement({ + name: "ElectricalEnergyMeasurement", id: 0x91, conformance: "O.a+", element: "serverCluster", + xref: { document: "device", section: "2.6.4" } + }) + ), + + DeviceType( + { + name: "DeviceEnergyManagement", id: 0x50d, category: "Utility", classification: "utility", + details: "A Device Energy Management device provides reporting and optionally adjustment of the electrical " + + "power planned on being consumed or produced by the device.", + xref: { document: "device", section: "2.7" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 1293, revision: 2 } ], element: "attribute" }) + ), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "ControllableEsa", + description: "The DEM cluster on this endpoint accepts commands to adjust its energy operation.", + xref: { document: "device", section: "2.7.3" } + }) + ), + + Requirement( + { + name: "DeviceEnergyManagement", id: 0x98, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.7.4" } + }, + Requirement({ name: "POWERADJUSTMENT", conformance: "ControllableESA.a+", element: "feature" }), + Requirement({ name: "STARTTIMEADJUSTMENT", conformance: "ControllableESA.a+", element: "feature" }), + Requirement({ name: "PAUSABLE", conformance: "ControllableESA.a+", element: "feature" }), + Requirement({ name: "FORECASTADJUSTMENT", conformance: "ControllableESA.a+", element: "feature" }), + Requirement({ name: "CONSTRAINTBASEDADJUSTMENT", conformance: "ControllableESA.a+", element: "feature" }) + ), + + Requirement({ + name: "DeviceEnergyManagementMode", id: 0x9f, conformance: "ControllableESA, O", + element: "serverCluster", + xref: { document: "device", section: "2.7.4" } + }) + ), + + DeviceType( + { + name: "SecondaryNetworkInterface", id: 0x19, category: "Utility", classification: "utility", + + details: "A Secondary Network Interface device provides an additional network interface supported by the " + + "Node, supplementing the primary interface hosted by the Root Node endpoint." + + "\n" + + "A Node supporting multiple network interfaces shall include the primary interface on the Root Node " + + "endpoint, along with secondary interfaces on other endpoints. The priorities of these network " + + "interfaces are determined by the order of their endpoints, where interfaces with smaller endpoint " + + "numbers are higher priority.", + + xref: { document: "device", section: "2.8" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 25, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "NetworkCommissioning", id: 0x31, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.8.3" } + }), + Requirement({ + name: "EthernetNetworkDiagnostics", id: 0x37, conformance: "[Ethernet]", element: "serverCluster", + xref: { document: "device", section: "2.8.3" } + }), + Requirement({ + name: "WiFiNetworkDiagnostics", id: 0x36, conformance: "[Wi, Fi]", element: "serverCluster", + xref: { document: "device", section: "2.8.3" } + }), + Requirement({ + name: "ThreadNetworkDiagnostics", id: 0x35, conformance: "[Thread]", element: "serverCluster", + xref: { document: "device", section: "2.8.3" } + }) + ), + + DeviceType( + { + name: "JointFabricAdministrator", id: 0x130, category: "Utility", classification: "utility", + + details: "A Joint Fabric Administrator device provides capabilities to manage the Joint Fabric Datastore and " + + "issue an ICAC signed by the Joint Fabric Anchor Root CA." + + "\n" + + "A client wanting to access the capabilities of the Joint Fabric Administrator may use the Joint " + + "Commissioning Method to be commissioned onto the Joint Fabric. Once commissioned, a client may " + + "access the capabilities of the Joint Fabric Administrator.", + + xref: { document: "device", section: "2.9" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 304, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "JointFabricDatastore", id: 0x752, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.9.4" } + }), + Requirement({ + name: "JointFabricPki", id: 0x753, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.9.4" } + }) + ), + + DeviceType( + { + name: "OnOffLight", id: 0x100, category: "Lighting", classification: "simple", + details: "The On/Off Light is a lighting device that is capable of being switched on or off by means of a " + + "bound controller device such as an On/Off Light Switch or a Dimmer Switch. In addition, an on/off " + + "light is also capable of being switched by means of a bound occupancy sensor.", + xref: { document: "device", section: "4.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 256, revision: 3 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.1.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.1.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "4.1.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.1.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "4.1.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "4.1.4" } + }) + ), + + DeviceType( + { + name: "DimmableLight", id: 0x101, type: "OnOffLight", category: "Lighting", + classification: "simple", + details: "A Dimmable Light is a lighting device that is capable of being switched on or off and the intensity " + + "of its light adjusted by means of a bound controller device such as a Dimmer Switch or a Color " + + "Dimmer Switch. In addition, a Dimmable Light device is also capable of being switched by means of a " + + "bound occupancy sensor or other device(s).", + xref: { document: "device", section: "4.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 257, revision: 3 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.2.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.2.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "4.2.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.2.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.2.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "4.2.4" } + }) + ), + + DeviceType( + { + name: "ColorTemperatureLight", id: 0x10c, type: "DimmableLight", category: "Lighting", + classification: "simple", + details: "A Color Temperature Light is a lighting device that is capable of being switched on or off, the " + + "intensity of its light adjusted, and its color temperature adjusted by means of a bound controller " + + "device such as a Color Dimmer Switch.", + xref: { document: "device", section: "4.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 268, revision: 4 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.3.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.3.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "4.3.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.3.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.3.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement( + { + name: "ColorControl", id: 0x300, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.3.4" } + }, + Requirement({ name: "COLORTEMPERATURE", conformance: "M", element: "feature" }), + Requirement({ name: "RemainingTime", conformance: "M", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "4.3.4" } + }) + ), + + DeviceType( + { + name: "ExtendedColorLight", id: 0x10d, type: "ColorTemperatureLight", category: "Lighting", + classification: "simple", + details: "An Extended Color Light is a lighting device that is capable of being switched on or off, the " + + "intensity of its light adjusted, and its color adjusted by means of a bound controller device such " + + "as a Color Dimmer Switch or Control Bridge. The device supports adjustment of color by means of " + + "hue/saturation, enhanced hue, color looping, XY coordinates, and color temperature. In addition, " + + "the extended color light is also capable of being switched by means of a bound occupancy sensor.", + xref: { document: "device", section: "4.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 269, revision: 4 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.4.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.4.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "4.4.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.4.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.4.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement( + { + name: "ColorControl", id: 0x300, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "4.4.4" } + }, + Requirement({ name: "HUESATURATION", conformance: "O", element: "feature" }), + Requirement({ name: "ENHANCEDHUE", conformance: "O", element: "feature" }), + Requirement({ name: "COLORLOOP", conformance: "O", element: "feature" }), + Requirement({ name: "XY", conformance: "M", element: "feature" }), + Requirement({ name: "COLORTEMPERATURE", conformance: "M", element: "feature" }), + Requirement({ name: "RemainingTime", conformance: "M", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "4.4.4" } + }) + ), + + DeviceType( + { + name: "OnOffPlugInUnit", id: 0x10a, category: "Smart Plugs/Outlets and other Actuators", + classification: "simple", + details: "An On/Off Plug-in Unit is a device that provides power to another device that is plugged into it, " + + "and is capable of switching that provided power on or off.", + xref: { document: "device", section: "5.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 266, revision: 3 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.1.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.1.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "5.1.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.1.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.1.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.1.4" } + }) + ), + + DeviceType( + { + name: "DimmablePlugInUnit", id: 0x10b, category: "Smart Plugs/Outlets and other Actuators", + classification: "simple", + details: "A Dimmable Plug-In Unit is a device that provides power to another device that is plugged into it, " + + "and is capable of being switched on or off and have its level adjusted. The Dimmable Plug-in Unit " + + "is typically used to control a conventional non-communicating light through its mains connection " + + "using phase cutting.", + xref: { document: "device", section: "5.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 267, revision: 4 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.2.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.2.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "5.2.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.2.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.2.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.2.4" } + }) + ), + + DeviceType( + { + name: "MountedOnOffControl", id: 0x10f, category: "Smart Plugs/Outlets and other Actuators", + classification: "simple", + details: "A Mounted On/Off Control is a fixed device that provides power to another device that is plugged " + + "into it, and is capable of switching that provided power on or off.", + xref: { document: "device", section: "5.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 271, revision: 1 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.3.4" } + }) + ), + + DeviceType( + { + name: "MountedDimmableLoadControl", id: 0x110, category: "Smart Plugs/Outlets and other Actuators", + classification: "simple", + details: "A Mounted Dimmable Load Control is a fixed device that provides power to another device that is " + + "plugged into it, and is capable of being switched on or off and have its level adjusted. The " + + "Mounted Dimmable Load Control is typically used to control a conventional non-communicating light " + + "through its mains connection using phase cutting.", + xref: { document: "device", section: "5.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 272, revision: 1 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.4.4" } + }) + ), + + DeviceType( + { + name: "Pump", id: 0x303, category: "Smart Plugs/Outlets and other Actuators", + classification: "simple", + details: "A Pump device is a pump that may have variable speed. It may have optional built-in sensors and a " + + "regulation mechanism. It is typically used for pumping fluids like water.", + xref: { document: "device", section: "5.5" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 771, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "PumpConfigurationAndControl", id: 0x200, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "PressureMeasurement", id: 0x403, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "FlowMeasurement", id: 0x404, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "PressureMeasurement", id: 0x403, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "FlowMeasurement", id: 0x404, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.5.4" } + }), + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.5.4" } + }) + ), + + DeviceType( + { + name: "WaterValve", id: 0x42, category: "Smart Plugs/Outlets and other Actuators", + classification: "simple", + details: "This defines conformance to the Water Valve device type.", + xref: { document: "device", section: "5.6" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 66, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.6.4" } + }), + Requirement({ + name: "ValveConfigurationAndControl", id: 0x81, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.6.4" } + }), + Requirement({ + name: "FlowMeasurement", id: 0x404, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.6.4" } + }), + Requirement({ + name: "FlowMeasurement", id: 0x404, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.6.4" } + }) + ), + + DeviceType( + { + name: "OnOffLightSwitch", id: 0x103, category: "Switches and Controls", classification: "simple", + details: "An On/Off Light Switch is a controller device that, when bound to a lighting device such as an " + + "On/Off Light, is capable of being used to switch the device on or off.", + xref: { document: "device", section: "6.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 259, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "6.1.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.1.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.1.4" } + }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.1.4" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "clientCluster", + xref: { document: "device", section: "6.1.4" } + }) + ), + + DeviceType( + { + name: "DimmerSwitch", id: 0x104, type: "OnOffLightSwitch", category: "Switches and Controls", + classification: "simple", + details: "A Dimmer Switch is a controller device that, when bound to a lighting device such as a Dimmable " + + "Light, is capable of being used to switch the device on or off and adjust the intensity of the " + + "light being emitted.", + xref: { document: "device", section: "6.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 260, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "6.2.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.2.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.2.4" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "clientCluster", + xref: { document: "device", section: "6.2.4" } + }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.2.4" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.2.4" } + }) + ), + + DeviceType( + { + name: "ColorDimmerSwitch", id: 0x105, type: "DimmerSwitch", category: "Switches and Controls", + classification: "simple", + details: "A Color Dimmer Switch is a controller device that, when bound to a lighting device such as an " + + "Extended Color Light, is capable of being used to adjust the color of the light being emitted.", + xref: { document: "device", section: "6.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 261, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "6.3.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.3.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.3.4" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "clientCluster", + xref: { document: "device", section: "6.3.4" } + }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.3.4" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.3.4" } + }), + Requirement({ + name: "ColorControl", id: 0x300, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.3.4" } + }) + ), + + DeviceType( + { + name: "ControlBridge", id: 0x840, category: "Switches and Controls", classification: "simple", + details: "A Control Bridge is a controller device that, when bound to a lighting device such as an Extended " + + "Color Light, is capable of being used to switch the device on or off, adjust the intensity of the " + + "light being emitted and adjust the color of the light being emitted. In addition, a Control Bridge " + + "device is capable of being used for setting scenes.", + xref: { document: "device", section: "6.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 2112, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "6.4.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.4.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.4.4" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "clientCluster", + xref: { document: "device", section: "6.4.4" } + }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.4.4" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.4.4" } + }), + Requirement({ + name: "ColorControl", id: 0x300, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.4.4" } + }), + Requirement({ + name: "IlluminanceMeasurement", id: 0x400, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.4.4" } + }), + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.4.4" } + }) + ), + + DeviceType( + { + name: "PumpController", id: 0x304, category: "Switches and Controls", classification: "simple", + details: "A Pump Controller device is capable of configuring and controlling a Pump device.", + xref: { document: "device", section: "6.5" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 772, revision: 4 } ], element: "attribute" }) + ), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "PumpConfigurationAndControl", id: 0x200, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "PressureMeasurement", id: 0x403, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }), + Requirement({ + name: "FlowMeasurement", id: 0x404, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "6.5.3" } + }) + ), + + DeviceType( + { + name: "GenericSwitch", id: 0xf, category: "Switches and Controls", classification: "simple", + details: "This defines conformance for the Generic Switch device type.", + xref: { document: "device", section: "6.6" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 15, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "6.6.4" } + }), + Requirement({ + name: "Switch", id: 0x3b, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "6.6.4" } + }) + ), + + DeviceType( + { + name: "ContactSensor", id: 0x15, category: "Sensor", classification: "simple", + details: "This defines conformance to the Contact Sensor device type.", + xref: { document: "device", section: "7.1" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 21, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.1.4" } + }), + Requirement({ + name: "BooleanState", id: 0x45, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.1.4" } + }), + Requirement({ + name: "BooleanStateConfiguration", id: 0x80, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.1.4" } + }) + ), + + DeviceType( + { + name: "LightSensor", id: 0x106, category: "Sensor", classification: "simple", + details: "A Light Sensor device is a measurement and sensing device that is capable of measuring and " + + "reporting the intensity of light (illuminance) to which the sensor is being subjected.", + xref: { document: "device", section: "7.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 262, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.2.4" } + }), + Requirement({ + name: "IlluminanceMeasurement", id: 0x400, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.2.4" } + }) + ), + + DeviceType( + { + name: "OccupancySensor", id: 0x107, category: "Sensor", classification: "simple", + details: "An Occupancy Sensor is a measurement and sensing device that is capable of measuring and reporting " + + "the occupancy state in a designated area.", + xref: { document: "device", section: "7.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 263, revision: 4 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.3.4" } + }), + Requirement({ + name: "BooleanStateConfiguration", id: 0x80, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.3.4" } + }), + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.3.4" } + }) + ), + + DeviceType( + { + name: "TemperatureSensor", id: 0x302, category: "Sensor", classification: "simple", + details: "A Temperature Sensor device reports measurements of temperature.", + xref: { document: "device", section: "7.4" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 770, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.4.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.4.4" } + }) + ), + + DeviceType( + { + name: "PressureSensor", id: 0x305, category: "Sensor", classification: "simple", + details: "A Pressure Sensor device measures and reports the pressure of a fluid.", + xref: { document: "device", section: "7.5" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 773, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "PressureMeasurement", id: 0x403, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.5.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.5.4" } + }) + ), + + DeviceType( + { + name: "FlowSensor", id: 0x306, category: "Sensor", classification: "simple", + details: "A Flow Sensor device measures and reports the flow rate of a fluid.", + xref: { document: "device", section: "7.6" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 774, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "FlowMeasurement", id: 0x404, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.6.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.6.4" } + }) + ), + + DeviceType( + { + name: "HumiditySensor", id: 0x307, category: "Sensor", classification: "simple", + details: "A humidity sensor (in most cases a Relative humidity sensor) reports humidity measurements.", + xref: { document: "device", section: "7.7" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 775, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.7.4" } + }), + Requirement({ + name: "RelativeHumidityMeasurement", id: 0x405, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.7.4" } + }) + ), + + DeviceType( + { + name: "OnOffSensor", id: 0x850, category: "Sensor", classification: "simple", + details: "An On/Off Sensor is a measurement and sensing device that, when bound to a lighting device such as " + + "a Dimmable Light, is capable of being used to switch the device on or off.", + xref: { document: "device", section: "7.8" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 2128, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.8.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "7.8.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "7.8.4" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "clientCluster", + xref: { document: "device", section: "7.8.4" } + }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "7.8.4" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "7.8.4" } + }), + Requirement({ + name: "ColorControl", id: 0x300, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "7.8.4" } + }) + ), + + DeviceType( + { + name: "SmokeCoAlarm", id: 0x76, category: "Sensor", classification: "simple", + + details: "A Smoke CO Alarm device is capable of sensing smoke, carbon monoxide or both. It is capable of " + + "issuing a visual and audible alert to indicate elevated concentration of smoke or carbon monoxide." + + "\n" + + "Smoke CO Alarms are capable of monitoring themselves and issuing visual and audible alerts for " + + "hardware faults, critical low battery conditions, and end of service. Optionally, some of the " + + "audible alerts can be temporarily silenced. Smoke CO Alarms are capable of performing a self-test " + + "which performs a diagnostic of the primary sensor and issuing a cycle of the audible and visual " + + "life safety alarm indications." + + "\n" + + "Some smoke alarms may be capable of adjusting sensitivity. Smoke CO Alarm may have the ability to " + + "detect and report humidity levels, temperature levels, and contamination levels.", + + xref: { document: "device", section: "7.9" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 118, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.9.5" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.9.5" } + }), + Requirement({ + name: "SmokeCoAlarm", id: 0x5c, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.9.5" } + }), + Requirement({ + name: "RelativeHumidityMeasurement", id: 0x405, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.9.5" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.9.5" } + }), + Requirement({ + name: "CarbonMonoxideConcentrationMeasurement", id: 0x40c, conformance: "O", + element: "serverCluster", + xref: { document: "device", section: "7.9.5" } + }) + ), + + DeviceType( + { + name: "AirQualitySensor", id: 0x2c, category: "Sensor", classification: "simple", + details: "This defines conformance for the Air Quality Sensor device type." + + "\n" + + "An air quality sensor is a device designed to monitor and measure various parameters related to the " + + "quality of ambient air in indoor or outdoor environments.", + xref: { document: "device", section: "7.10" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 44, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "AirQuality", id: 0x5b, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "RelativeHumidityMeasurement", id: 0x405, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "CarbonMonoxideConcentrationMeasurement", id: 0x40c, conformance: "O", + element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "CarbonDioxideConcentrationMeasurement", id: 0x40d, conformance: "O", + element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "NitrogenDioxideConcentrationMeasurement", id: 0x413, conformance: "O", + element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "OzoneConcentrationMeasurement", id: 0x415, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "FormaldehydeConcentrationMeasurement", id: 0x42b, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "Pm1ConcentrationMeasurement", id: 0x42c, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "Pm25ConcentrationMeasurement", id: 0x42a, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "Pm10ConcentrationMeasurement", id: 0x42d, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "RadonConcentrationMeasurement", id: 0x42f, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }), + Requirement({ + name: "TotalVolatileOrganicCompoundsConcentrationMeasurement", id: 0x42e, conformance: "O", + element: "serverCluster", + xref: { document: "device", section: "7.10.4" } + }) + ), + + DeviceType( + { + name: "WaterFreezeDetector", id: 0x41, category: "Sensor", classification: "simple", + details: "This defines conformance to the Water Freeze Detector device type.", + xref: { document: "device", section: "7.11" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 65, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.11.4" } + }), + + Requirement( + { + name: "BooleanState", id: 0x45, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.11.4" } + }, + Requirement({ name: "StateChange", conformance: "M", element: "event" }) + ), + + Requirement({ + name: "BooleanStateConfiguration", id: 0x80, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.11.4" } + }) + ), + + DeviceType( + { + name: "WaterLeakDetector", id: 0x43, category: "Sensor", classification: "simple", + details: "This defines conformance to the Water Leak Detector device type.", + xref: { document: "device", section: "7.12" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 67, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.12.4" } + }), + + Requirement( + { + name: "BooleanState", id: 0x45, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.12.4" } + }, + Requirement({ name: "StateChange", conformance: "M", element: "event" }) + ), + + Requirement({ + name: "BooleanStateConfiguration", id: 0x80, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.12.4" } + }) + ), + + DeviceType( + { + name: "RainSensor", id: 0x44, category: "Sensor", classification: "simple", + details: "This defines conformance to the Rain Sensor device type.", + xref: { document: "device", section: "7.13" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 68, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.13.4" } + }), + + Requirement( + { + name: "BooleanState", id: 0x45, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "7.13.4" } + }, + Requirement({ name: "StateChange", conformance: "M", element: "event" }) + ), + + Requirement({ + name: "BooleanStateConfiguration", id: 0x80, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.13.4" } + }) + ), + + DeviceType( + { + name: "DoorLock", id: 0xa, category: "Closure", classification: "simple", + details: "A Door Lock is a device used to secure a door. It is possible to actuate a door lock either by " + + "means of a manual or a remote method.", + xref: { document: "device", section: "8.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 10, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "8.1.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "X", element: "serverCluster", + xref: { document: "device", section: "8.1.4" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "X", element: "serverCluster", + xref: { document: "device", section: "8.1.4" } + }), + + Requirement( + { + name: "DoorLock", id: 0x101, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "8.1.4" } + }, + Requirement({ name: "USER", conformance: "Matter & (PIN | RID | FPG | FACE | ALIRO)", element: "feature" }), + Requirement({ name: "RFIDCREDENTIAL", conformance: "P, O", element: "feature" }), + Requirement({ name: "AlarmMask", conformance: "[Alarms]", element: "attribute" }) + ) + ), + + DeviceType( + { + name: "DoorLockController", id: 0xb, category: "Closure", classification: "simple", + details: "A Door Lock Controller is a device capable of controlling a door lock.", + xref: { document: "device", section: "8.2" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 11, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "8.2.4" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "clientCluster", + xref: { document: "device", section: "8.2.4" } + }), + Requirement({ + name: "TimeSynchronization", id: 0x38, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "8.2.4" } + }), + Requirement({ + name: "DoorLock", id: 0x101, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "8.2.4" } + }) + ), + + DeviceType( + { + name: "WindowCovering", id: 0x202, category: "Closure", classification: "simple", + details: "This defines conformance to the Window Covering device type.", + xref: { document: "device", section: "8.3" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 514, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "8.3.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "Active, O", element: "serverCluster", + xref: { document: "device", section: "8.3.4" } + }), + Requirement({ + name: "WindowCovering", id: 0x102, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "8.3.4" } + }) + ), + + DeviceType( + { + name: "WindowCoveringController", id: 0x203, category: "Closure", classification: "simple", + details: "A Window Covering Controller is a device that controls an automatic window covering.", + xref: { document: "device", section: "8.4" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 515, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "8.4.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "8.4.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "Active, O", element: "clientCluster", + xref: { document: "device", section: "8.4.4" } + }), + Requirement({ + name: "WindowCovering", id: 0x102, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "8.4.4" } + }) + ), + + DeviceType( + { + name: "Thermostat", id: 0x301, category: "HVAC", classification: "simple", + details: "A Thermostat device is capable of having either built-in or separate sensors for temperature, " + + "humidity or occupancy. It allows the desired temperature to be set either remotely or locally. The " + + "thermostat is capable of sending heating and/or cooling requirement notifications to a " + + "heating/cooling unit (for example, an indoor air handler) or is capable of including a mechanism to " + + "control a heating or cooling unit directly.", + xref: { document: "device", section: "9.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 769, revision: 4 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "9.1.4" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "Active", element: "serverCluster", + xref: { document: "device", section: "9.1.4" } + }), + + Requirement( + { + name: "Thermostat", id: 0x201, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "9.1.4" } + }, + Requirement({ name: "SCHEDULECONFIGURATION", conformance: "X", element: "feature" }), + Requirement({ name: "AlarmMask", conformance: "X", element: "attribute" }), + Requirement({ name: "GetRelayStatusLog", conformance: "X", element: "command" }), + Requirement({ name: "GetRelayStatusLogResponse", conformance: "X", element: "command" }) + ), + + Requirement({ + name: "ThermostatUserInterfaceConfiguration", id: 0x204, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.1.4" } + }), + Requirement({ + name: "EnergyPreference", id: 0x9b, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.1.4" } + }), + Requirement({ + name: "FanControl", id: 0x202, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "9.1.4" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "9.1.4" } + }), + Requirement({ + name: "RelativeHumidityMeasurement", id: 0x405, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "9.1.4" } + }), + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "9.1.4" } + }) + ), + + DeviceType( + { + name: "Fan", id: 0x2b, category: "HVAC", classification: "simple", + details: "A Fan device is typically standalone or mounted on a ceiling or wall and is used to circulate air " + + "in a room.", + xref: { document: "device", section: "9.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 43, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "9.2.5" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "9.2.5" } + }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.2.5" } + }), + + Requirement( + { + name: "FanControl", id: 0x202, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "9.2.5" } + }, + Requirement({ name: "FanModeSequence", access: "R V", conformance: "Matter", element: "attribute" }) + ) + ), + + DeviceType( + { + name: "AirPurifier", id: 0x2d, category: "HVAC", classification: "simple", + details: "An Air Purifier is a standalone device that is designed to clean the air in a room." + + "\n" + + "It is a device that has a fan to control the air speed while it is operating. Optionally, it can " + + "report on the condition of its filters.", + xref: { document: "device", section: "9.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 45, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "9.3.5" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.3.5" } + }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.3.5" } + }), + Requirement({ + name: "FanControl", id: 0x202, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "9.3.5" } + }), + Requirement({ + name: "HepaFilterMonitoring", id: 0x71, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.3.5" } + }), + Requirement({ + name: "ActivatedCarbonFilterMonitoring", id: 0x72, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.3.5" } + }) + ), + + DeviceType( + { + name: "BasicVideoPlayer", id: 0x28, category: "Media", classification: "simple", + + details: "This defines conformance to the Basic Video Player device type." + + "\n" + + "A Video Player (either Basic or Casting) represents a device that is able to play media to a " + + "physical output or to a display screen which is part of the device." + + "\n" + + "A Basic Video Player has playback controls (play, pause, etc.) and keypad remote controls (up, " + + "down, number input), but is not able to launch content and is not a content app platform (the " + + "Casting Video Player device type is used for these functions)." + + "\n" + + "For example, a Basic Video Player can be a traditional TV device a physical media playback device " + + "such as a DVD Player, or a device that provides input to another device like a TV or computer " + + "monitor." + + "\n" + + "Please see Video Player Architecture for additional Basic Video Player requirements relating to " + + "Video Player device endpoint composition, commissioning, feature representation in clusters, and UI " + + "context.", + + xref: { document: "device", section: "10.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 40, revision: 2 } ], element: "attribute" }) + ), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "PhysicalInputs", description: "The device has physical inputs for media.", + xref: { document: "device", section: "10.2.3" } + }) + ), + + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "WakeOnLan", id: 0x503, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "Channel", id: 0x504, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "TargetNavigator", id: 0x505, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "MediaPlayback", id: 0x506, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "MediaInput", id: 0x507, conformance: "PhysicalInputs", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "LowPower", id: 0x508, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "KeypadInput", id: 0x509, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "AudioOutput", id: 0x50b, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "ContentControl", id: 0x50f, conformance: "P, O", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }), + Requirement({ + name: "Messages", id: 0x97, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.2.4" } + }) + ), + + DeviceType( + { + name: "CastingVideoPlayer", id: 0x23, category: "Media", classification: "simple", + + details: "This defines conformance to the Casting Video Player device type." + + "\n" + + "A Video Player (either Basic or Casting) represents a device that is able to play media to a " + + "physical output or to a display screen which is part of the device." + + "\n" + + "A Casting Video Player has basic controls for playback (play, pause, etc.) and keypad input (up, " + + "down, number input), and is able to launch content." + + "\n" + + "For example, a Casting Video Player can be a smart TV device, a TV Set Top Box, or a content " + + "streaming device that provides input to another device like a TV or computer monitor." + + "\n" + + "Please see Video Player Architecture for additional Casting Video Player requirements relating to " + + "Video Player device endpoint composition, commissioning, feature representation in clusters, and UI " + + "context.", + + xref: { document: "device", section: "10.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 35, revision: 2 } ], element: "attribute" }) + ), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "ContentAppPlatform", + description: "The device includes a Content App Platform. A Content App is usually an application built by a Content Provider. A Casting Video Player with a Content App Platform is able to launch Content Apps and represent these apps as separate endpoints.", + xref: { document: "device", section: "10.3.3" } + }), + Field({ + name: "PhysicalInputs", description: "The device has physical inputs for media.", + xref: { document: "device", section: "10.3.3" } + }) + ), + + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "WakeOnLan", id: 0x503, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "Channel", id: 0x504, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "TargetNavigator", id: 0x505, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "MediaPlayback", id: 0x506, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "MediaInput", id: 0x507, conformance: "PhysicalInputs", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "LowPower", id: 0x508, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "KeypadInput", id: 0x509, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "ContentLauncher", id: 0x50a, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "AudioOutput", id: 0x50b, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + + Requirement( + { + name: "ApplicationLauncher", id: 0x50c, conformance: "ContentAppPlatform", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }, + Requirement({ name: "APPLICATIONPLATFORM", conformance: "M", element: "feature" }) + ), + + Requirement({ + name: "AccountLogin", id: 0x50e, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "ContentControl", id: 0x50f, conformance: "P, O", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }), + Requirement({ + name: "Messages", id: 0x97, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.3.4" } + }) + ), + + DeviceType( + { + name: "Speaker", id: 0x22, category: "Media", classification: "simple", + + details: "This defines conformance to the Speaker device type. This feature controls the speaker volume of " + + "the device." + + "\n" + + "To control unmute/mute, the On/Off cluster shall be used. A value of TRUE for the OnOff attribute " + + "shall represent the volume on (not muted) state, while a value of FALSE shall represent the volume " + + "off (muted) state. For volume level control, the Level cluster shall be used." + + "\n" + + "A dedicated endpoint is needed because the On/Off cluster can also be used for other purposes, such " + + "as for power control." + + "\n" + + "The decision to use Level and On/Off clusters for volume (rather than defining a new audio control " + + "cluster) was made in order to treat volume in a fashion consistent with lighting which also uses " + + "these clusters and has matching functional requirements.", + + xref: { document: "device", section: "10.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 34, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.4.4" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.4.4" } + }) + ), + + DeviceType( + { + name: "ContentApp", id: 0x24, category: "Media", classification: "simple", + details: "This defines conformance to the Content App device type." + + "\n" + + "A Content App is usually an application built by a Content Provider. A Casting Video Player with a " + + "Content App Platform is able to launch Content Apps and represent these apps as separate endpoints.", + xref: { document: "device", section: "10.5" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 36, revision: 2 } ], element: "attribute" }) + ), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "ObserverClient", description: "The node is a client for ContentAppObservers.", + xref: { document: "device", section: "10.5.3" } + }) + ), + + Requirement({ + name: "Binding", id: 0x1e, conformance: "ObserverClient", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }), + Requirement({ + name: "Channel", id: 0x504, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }), + Requirement({ + name: "TargetNavigator", id: 0x505, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }), + Requirement({ + name: "MediaPlayback", id: 0x506, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }), + Requirement({ + name: "KeypadInput", id: 0x509, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }), + Requirement({ + name: "ContentLauncher", id: 0x50a, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }), + + Requirement( + { + name: "ApplicationLauncher", id: 0x50c, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }, + Requirement({ name: "APPLICATIONPLATFORM", conformance: "X", element: "feature" }) + ), + + Requirement({ + name: "ApplicationBasic", id: 0x50d, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }), + Requirement({ + name: "AccountLogin", id: 0x50e, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.5.4" } + }), + Requirement({ + name: "ContentAppObserver", id: 0x510, conformance: "ObserverClient", element: "clientCluster", + xref: { document: "device", section: "10.5.4" } + }) + ), + + DeviceType( + { + name: "CastingVideoClient", id: 0x29, category: "Media", classification: "simple", + details: "This defines conformance to the Casting Video Client device type." + + "\n" + + "A Casting Video Client is a client that can launch content on a Casting Video Player, for example, " + + "a Smart Speaker or a Content Provider phone app.", + xref: { document: "device", section: "10.6" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 41, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "WakeOnLan", id: 0x503, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "Channel", id: 0x504, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "TargetNavigator", id: 0x505, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "MediaPlayback", id: 0x506, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "MediaInput", id: 0x507, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "LowPower", id: 0x508, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "KeypadInput", id: 0x509, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "ContentLauncher", id: 0x50a, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "AudioOutput", id: 0x50b, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "ApplicationLauncher", id: 0x50c, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "ApplicationBasic", id: 0x50d, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "AccountLogin", id: 0x50e, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "ContentControl", id: 0x50f, conformance: "P, O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "ContentAppObserver", id: 0x510, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "10.6.4" } + }), + Requirement({ + name: "Messages", id: 0x97, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.6.4" } + }) + ), + + DeviceType( + { + name: "VideoRemoteControl", id: 0x2a, category: "Media", classification: "simple", + details: "This defines conformance to the Video Remote Control device type." + + "\n" + + "A Video Remote Control is a client that can control a Video Player, for example, a traditional " + + "universal remote control.", + xref: { document: "device", section: "10.7" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 42, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "LevelControl", id: 0x8, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "WakeOnLan", id: 0x503, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "Channel", id: 0x504, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "TargetNavigator", id: 0x505, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "MediaPlayback", id: 0x506, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "MediaInput", id: 0x507, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "LowPower", id: 0x508, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "KeypadInput", id: 0x509, conformance: "M", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "ContentLauncher", id: 0x50a, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "AudioOutput", id: 0x50b, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "ApplicationLauncher", id: 0x50c, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "AccountLogin", id: 0x50e, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }), + Requirement({ + name: "ContentControl", id: 0x50f, conformance: "P, O", element: "clientCluster", + xref: { document: "device", section: "10.7.4" } + }) + ), + + DeviceType( + { + name: "ModeSelect", id: 0x27, category: "Generic", classification: "simple", + details: "This defines conformance to the Mode Select device type.", + xref: { document: "device", section: "11.1" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 39, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "ModeSelect", id: 0x50, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "11.1.4" } + }) + ), + + DeviceType( + { + name: "Aggregator", id: 0xe, category: "Generic", classification: "simple", + + details: "This device type aggregates endpoints as a collection. Clusters on the endpoint indicating this " + + "device type provide functionality for the collection of descendant endpoints present in the " + + "PartsList of the endpoint’s descriptor, for example the Actions cluster." + + "\n" + + "The purpose of this device type is to aggregate functionality for a collection of endpoints. The " + + "definition of the collection or functionality is not defined here." + + "\n" + + "When using this device type as a collection of bridged nodes, please see the \"Bridge\" section in " + + "the System Model specification.", + + xref: { document: "device", section: "11.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 14, revision: 2 } ], element: "attribute" }) + ), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "FabricSynchronization", description: "See description below.", + xref: { document: "device", section: "11.2.3" } + }) + ), + + Requirement({ + name: "Actions", id: 0x25, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "11.2.4" } + }), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "11.2.4" } + }), + Requirement({ + name: "CommissionerControl", id: 0x751, conformance: "FabricSynchronization", + element: "serverCluster", + xref: { document: "device", section: "11.2.4" } + }) + ), + + DeviceType( + { + name: "RoboticVacuumCleaner", id: 0x74, category: "Robotic", classification: "simple", + details: "This defines conformance for the Robotic Vacuum Cleaner device type.", + xref: { document: "device", section: "12.1" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 116, revision: 3 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "12.1.4" } + }), + Requirement({ + name: "RvcRunMode", id: 0x54, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "12.1.4" } + }), + Requirement({ + name: "RvcCleanMode", id: 0x55, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "12.1.4" } + }), + Requirement({ + name: "RvcOperationalState", id: 0x61, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "12.1.4" } + }), + Requirement({ + name: "ServiceArea", id: 0x150, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "12.1.4" } + }) + ), + + DeviceType( + { + name: "LaundryWasher", id: 0x73, category: "Appliances", classification: "simple", + details: "A Laundry Washer represents a device that is capable of laundering consumer items. Any laundry " + + "washer product may utilize this device type." + + "\n" + + "A Laundry Washer shall be composed of at least one endpoint with the Laundry Washer device type.", + xref: { document: "device", section: "13.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 115, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.1.4" } + }), + + Requirement( + { + name: "LaundryWasherMode", id: 0x51, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.1.4" } + }, + Requirement({ name: "StartUpMode", conformance: "X", element: "attribute" }), + Requirement({ name: "ONOFF", conformance: "X", element: "feature" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.1.4" } + }, + Requirement({ name: "DEADFRONTBEHAVIOR", conformance: "M", element: "feature" }) + ), + + Requirement({ + name: "LaundryWasherControls", id: 0x53, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.1.4" } + }), + Requirement({ + name: "TemperatureControl", id: 0x56, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.1.4" } + }), + Requirement({ + name: "OperationalState", id: 0x60, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.1.4" } + }) + ), + + DeviceType( + { + name: "Refrigerator", id: 0x70, category: "Appliances", classification: "simple", + details: "A refrigerator represents a device that contains one or more cabinets that are capable of chilling " + + "or freezing food. Examples of consumer products that may make use of this device type include " + + "refrigerators, freezers, and wine coolers.", + xref: { document: "device", section: "13.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 112, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.2.6" } + }), + + Requirement( + { + name: "RefrigeratorAndTemperatureControlledCabinetMode", id: 0x52, conformance: "O", + element: "serverCluster", + xref: { document: "device", section: "13.2.6" } + }, + Requirement({ name: "StartUpMode", conformance: "X", element: "attribute" }), + Requirement({ name: "ONOFF", conformance: "X", element: "feature" }) + ), + + Requirement({ + name: "RefrigeratorAlarm", id: 0x57, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.2.6" } + }) + ), + + DeviceType( + { + name: "RoomAirConditioner", id: 0x72, category: "Appliances", classification: "simple", + details: "This defines conformance to the Room Air Conditioner device type." + + "\n" + + "A Room Air Conditioner is a device with the primary function of controlling the air temperature in " + + "a single room.", + xref: { document: "device", section: "13.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 114, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }), + Requirement({ + name: "Groups", id: 0x4, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }), + Requirement({ + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }, + Requirement({ name: "DEADFRONTBEHAVIOR", conformance: "M", element: "feature" }) + ), + + Requirement({ + name: "Thermostat", id: 0x201, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }), + Requirement({ + name: "FanControl", id: 0x202, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }), + + Requirement( + { + name: "ThermostatUserInterfaceConfiguration", id: 0x204, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }, + Requirement({ name: "KeypadLockout", conformance: "O", element: "attribute" }) + ), + + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }), + Requirement({ + name: "RelativeHumidityMeasurement", id: 0x405, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.3.6" } + }) + ), + + DeviceType( + { + name: "TemperatureControlledCabinet", id: 0x71, category: "Appliances", classification: "simple", + details: "A Temperature Controlled Cabinet only exists composed as part of another device type. It represents " + + "a single cabinet that is capable of having its temperature controlled. Such a cabinet may be " + + "chilling or freezing food, for example as part of a refrigerator, freezer, wine chiller, or other " + + "similar device. Equally, such a cabinet may be warming or heating food, for example as part of an " + + "oven, range, or similar device.", + xref: { document: "device", section: "13.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 113, revision: 3 } ], element: "attribute" }) + ), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "Cooler", description: "The device has cooling functionality.", + xref: { document: "device", section: "13.4.3" } + }), + Field({ + name: "Heater", description: "The device has heating functionality.", + xref: { document: "device", section: "13.4.3" } + }) + ), + + Requirement({ + name: "TemperatureControl", id: 0x56, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.4.4" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.4.4" } + }), + + Requirement( + { + name: "RefrigeratorAndTemperatureControlledCabinetMode", id: 0x52, conformance: "[Cooler]", + element: "serverCluster", + xref: { document: "device", section: "13.4.4" } + }, + Requirement({ name: "StartUpMode", conformance: "X", element: "attribute" }), + Requirement({ name: "ONOFF", conformance: "X", element: "feature" }) + ), + + Requirement( + { + name: "OvenMode", id: 0x49, conformance: "[Heater]", element: "serverCluster", + xref: { document: "device", section: "13.4.4" } + }, + Requirement({ name: "StartUpMode", conformance: "X", element: "attribute" }), + Requirement({ name: "ONOFF", conformance: "X", element: "feature" }) + ), + + Requirement( + { + name: "OvenCavityOperationalState", id: 0x48, conformance: "[Heater]", element: "serverCluster", + xref: { document: "device", section: "13.4.4" } + }, + Requirement({ name: "Pause", conformance: "X", element: "command" }), + Requirement({ name: "Resume", conformance: "X", element: "command" }) + ) + ), + + DeviceType( + { + name: "Dishwasher", id: 0x75, category: "Appliances", classification: "simple", + details: "A dishwasher is a device that is generally installed in residential homes and is capable of washing " + + "dishes, cutlery, and other items associate with food preparation and consumption. The device can be " + + "permanently installed or portable and can have variety of filling and draining methods.", + xref: { document: "device", section: "13.5" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 117, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.5.4" } + }), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.5.4" } + }, + Requirement({ name: "DEADFRONTBEHAVIOR", conformance: "M", element: "feature" }) + ), + + Requirement({ + name: "TemperatureControl", id: 0x56, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.5.4" } + }), + + Requirement( + { + name: "DishwasherMode", id: 0x59, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.5.4" } + }, + Requirement({ name: "StartUpMode", conformance: "X", element: "attribute" }), + Requirement({ name: "ONOFF", conformance: "X", element: "feature" }) + ), + + Requirement({ + name: "DishwasherAlarm", id: 0x5d, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.5.4" } + }), + Requirement({ + name: "OperationalState", id: 0x60, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.5.4" } + }) + ), + + DeviceType( + { + name: "LaundryDryer", id: 0x7c, category: "Appliances", classification: "simple", + details: "A Laundry Dryer represents a device that is capable of drying laundry items.", + xref: { document: "device", section: "13.6" } + }, + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 124, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.6.4" } + }), + + Requirement( + { + name: "LaundryWasherMode", id: 0x51, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.6.4" } + }, + Requirement({ name: "StartUpMode", conformance: "X", element: "attribute" }), + Requirement({ name: "ONOFF", conformance: "X", element: "feature" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.6.4" } + }, + Requirement({ name: "DEADFRONTBEHAVIOR", conformance: "M", element: "feature" }) + ), + + Requirement({ + name: "LaundryDryerControls", id: 0x4a, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.6.4" } + }), + Requirement({ + name: "TemperatureControl", id: 0x56, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.6.4" } + }), + Requirement({ + name: "OperationalState", id: 0x60, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.6.4" } + }) + ), + + DeviceType( + { + name: "CookSurface", id: 0x77, category: "Appliances", classification: "simple", + details: "A Cook Surface device type represents a heating object on a cooktop or other similar device. It " + + "shall only be used when composed as part of another device type.", + xref: { document: "device", section: "13.7" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 119, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "TemperatureControl", id: 0x56, conformance: "O.a+", element: "serverCluster", + xref: { document: "device", section: "13.7.4" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O.a+", element: "serverCluster", + xref: { document: "device", section: "13.7.4" } + }), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.7.4" } + }, + Requirement({ name: "OFFONLY", conformance: "M", element: "feature" }) + ) + ), + + DeviceType( + { + name: "Cooktop", id: 0x78, category: "Appliances", classification: "simple", + details: "A cooktop is a cooking surface that heats food either by transferring currents from an " + + "electromagnetic field located below the glass surface directly to the magnetic induction cookware " + + "placed above or through traditional gas or electric burners.", + xref: { document: "device", section: "13.8" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 120, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.8.5" } + }), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.8.5" } + }, + Requirement({ name: "OFFONLY", conformance: "M", element: "feature" }) + ) + ), + + DeviceType( + { + name: "Oven", id: 0x7b, category: "Appliances", classification: "simple", + details: "An oven represents a device that contains one or more cabinets, and optionally a single cooktop, " + + "that are all capable of heating food. Examples of consumer products implementing this device type " + + "include ovens, wall ovens, convection ovens, etc.", + xref: { document: "device", section: "13.9" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 123, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.9.6" } + }) + ), + + DeviceType( + { + name: "ExtractorHood", id: 0x7a, category: "Appliances", classification: "simple", + + details: "An Extractor Hood is a device that is generally installed above a cooking surface in residential " + + "kitchens. An Extractor Hood’s primary purpose is to reduce odors that arise during the cooking " + + "process by either extracting the air above the cooking surface or by recirculating and filtering " + + "it. It may also contain a light for illuminating the cooking surface." + + "\n" + + "Extractor Hoods may also be known by the following names:" + + "\n" + + " • Hoods" + + "\n" + + " • Extractor Fans" + + "\n" + + " • Extractors" + + "\n" + + " • Range Hoods" + + "\n" + + " • Telescoping Hoods" + + "\n" + + " • Telescoping Extractors", + + xref: { document: "device", section: "13.10" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 122, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.10.5" } + }), + Requirement({ + name: "HepaFilterMonitoring", id: 0x71, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.10.5" } + }), + Requirement({ + name: "ActivatedCarbonFilterMonitoring", id: 0x72, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.10.5" } + }), + + Requirement( + { + name: "FanControl", id: 0x202, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.10.5" } + }, + Requirement({ name: "ROCKING", conformance: "X", element: "feature" }), + Requirement({ name: "WIND", conformance: "X", element: "feature" }), + Requirement({ name: "AIRFLOWDIRECTION", conformance: "X", element: "feature" }) + ) + ), + + DeviceType( + { + name: "MicrowaveOven", id: 0x79, category: "Appliances", classification: "simple", + details: "This defines conformance to the Microwave Oven device type." + + "\n" + + "A Microwave Oven is a device with the primary function of heating foods and beverages using a " + + "magnetron.", + xref: { document: "device", section: "13.11" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 121, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.11.6" } + }), + + Requirement( + { + name: "OperationalState", id: 0x60, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.11.6" } + }, + Requirement({ name: "CountdownTime", conformance: "M", element: "attribute" }) + ), + + Requirement( + { + name: "FanControl", id: 0x202, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "13.11.6" } + }, + Requirement({ name: "WIND", conformance: "X", element: "feature" }), + Requirement({ name: "AIRFLOWDIRECTION", conformance: "X", element: "feature" }) + ), + + Requirement({ + name: "MicrowaveOvenMode", id: 0x5e, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.11.6" } + }), + Requirement({ + name: "MicrowaveOvenControl", id: 0x5f, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "13.11.6" } + }) + ), + + DeviceType( + { + name: "EnergyEvse", id: 0x50c, category: "Energy", classification: "simple", + details: "An EVSE (Electric Vehicle Supply Equipment) is a device that allows an EV (Electric Vehicle) to be " + + "connected to the mains electricity supply to allow it to be charged (or discharged in case of " + + "Vehicle to Grid / Vehicle to Home applications).", + xref: { document: "device", section: "14.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 1292, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.1.6" } + }), + Requirement({ + name: "EnergyEvse", id: 0x99, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.1.6" } + }), + Requirement({ + name: "EnergyEvseMode", id: 0x9d, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.1.6" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.1.6" } + }) + ), + + DeviceType( + { + name: "WaterHeater", id: 0x50f, category: "Energy", classification: "simple", + details: "A water heater is a device that is generally installed in properties to heat water for showers, " + + "baths etc.", + xref: { document: "device", section: "14.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 1295, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.2.6" } + }), + + Requirement( + { + name: "Thermostat", id: 0x201, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.2.6" } + }, + Requirement({ name: "HEATING", conformance: "M", element: "feature" }) + ), + + Requirement({ + name: "WaterHeaterManagement", id: 0x94, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.2.6" } + }), + Requirement({ + name: "WaterHeaterMode", id: 0x9e, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.2.6" } + }) + ), + + DeviceType( + { + name: "SolarPower", id: 0x17, category: "Energy", classification: "simple", + details: "A Solar Power device is a device that allows a solar panel array, which can optionally be comprised " + + "of a set parallel strings of solar panels, and its associated controller and, if appropriate, " + + "inverter, to be monitored and controlled by an Energy Management System.", + xref: { document: "device", section: "14.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 23, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.3.6" } + }) + ), + + DeviceType( + { + name: "BatteryStorage", id: 0x18, category: "Energy", classification: "simple", + + details: "A Battery Storage device is a device that allows a DC battery, which can optionally be comprised of " + + "a set parallel strings of battery packs and associated controller, and an AC inverter, to be " + + "monitored and controlled by an Energy Management System in order to manage the peaks and troughs of " + + "supply and demand, and/or to optimize cost of the energy consumed in premises. It is not intended " + + "to be used for a UPS directly supplying a set of appliances, nor for portable battery storage " + + "devices.", + + xref: { document: "device", section: "14.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 24, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.4.6" } + }) + ), + + DeviceType( + { + name: "HeatPump", id: 0x309, category: "Energy", classification: "simple", + + details: "A Heat Pump device is a device that uses electrical energy to heat either spaces or water tanks " + + "using ground, water or air as the heat source. These typically can heat the air or can pump water " + + "via central heating radiators or underfloor heating systems. It is typical to also heat hot water " + + "and store the heat in a hot water tank." + + "\n" + + "Note that the Water Heater device type can also be heated by a heat pump and has similar " + + "requirements, but that cannot be used for space heating.", + + xref: { document: "device", section: "14.5" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 777, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.5.6" } + }), + Requirement({ + name: "Thermostat", id: 0x201, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "14.5.6" } + }) + ), + + DeviceType( + { + name: "NetworkInfrastructureManager", id: 0x90, category: "Network Infrastructure", + classification: "simple", + + details: "A Network Infrastructure Manager provides interfaces that allow for the management of the Wi-Fi, " + + "Thread, and Ethernet networks underlying a Matter deployment, realizing the Star Network Topology " + + "described in [MatterCore]." + + "\n" + + "Examples of physical devices that implement the Matter Network Infrastructure Manager device type " + + "include Wi-Fi gateway routers." + + "\n" + + "Relevant hardware and software requirements for Network Infrastructure Manager devices are defined " + + "in Section 15.2.6, “Other Requirements” and within the clusters mandated by this device type." + + "\n" + + "A Network Infrastructure Manager device may be managed by a service associated with the device " + + "vendor, for example, an Internet Service Provider. Sometimes this managing service will have " + + "policies that require the use of the Managed Device feature of the Access Control Cluster (see " + + "Section 15.2.5.1, “Access Control MNGD Conformance”). Consequently, Commissioners of this device " + + "type should be aware of this feature and its use.", + + xref: { document: "device", section: "15.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 144, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "WiFiNetworkManagement", id: 0x451, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "15.2.4" } + }), + Requirement({ + name: "ThreadBorderRouterManagement", id: 0x452, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "15.2.4" } + }), + Requirement({ + name: "ThreadNetworkDirectory", id: 0x453, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "15.2.4" } + }) + ), + + SemanticNamespace( + { + name: "Closure", id: 0x1, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a feature of a Closure, e.g. the button to activate opening a garage door.", + xref: { document: "namespace", section: "2" } + }, + + SemanticTag({ name: "Opening", id: 0x0, description: "Move toward open position" }), + SemanticTag({ name: "Closing", id: 0x1, description: "Move toward closed position" }), + SemanticTag({ name: "Stop", id: 0x2, description: "Stop any movement" }) + ), + + SemanticNamespace( + { + name: "CompassDirection", id: 0x2, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a movement into a certain compass direction. Note the difference with Chapter 4, " + + "Common Compass Location Semantic Tag Namespace.", + xref: { document: "namespace", section: "3" } + }, + + SemanticTag({ name: "Northward", id: 0x0 }), + SemanticTag({ name: "North-Eastward", id: 0x1 }), + SemanticTag({ name: "Eastward", id: 0x2 }), + SemanticTag({ name: "South-Eastward", id: 0x3 }), + SemanticTag({ name: "Southward", id: 0x4 }), + SemanticTag({ name: "South-Westward", id: 0x5 }), + SemanticTag({ name: "Westward", id: 0x6 }), + SemanticTag({ name: "North-Westward", id: 0x7 }) + ), + + SemanticNamespace( + { + name: "CompassLocation", id: 0x3, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a position in a certain compass direction (e.g. an outdoor sensor in the North " + + "garden). Note the difference with Chapter 3, Common Compass Direction Semantic Tag Namespace.", + xref: { document: "namespace", section: "4" } + }, + + SemanticTag({ name: "North", id: 0x0 }), + SemanticTag({ name: "North-East", id: 0x1 }), + SemanticTag({ name: "East", id: 0x2 }), + SemanticTag({ name: "South-East", id: 0x3 }), + SemanticTag({ name: "South", id: 0x4 }), + SemanticTag({ name: "South-West", id: 0x5 }), + SemanticTag({ name: "West", id: 0x6 }), + SemanticTag({ name: "North-West", id: 0x7 }) + ), + + SemanticNamespace( + { + name: "Direction", id: 0x4, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a movement in a certain direction relative to the device. Note the difference with " + + "Chapter 9, Common Position Semantic Tag Namespace.", + xref: { document: "namespace", section: "5" } + }, + + SemanticTag({ name: "Upward", id: 0x0 }), + SemanticTag({ name: "Downward", id: 0x1 }), + SemanticTag({ name: "Leftward", id: 0x2 }), + SemanticTag({ name: "Rightward", id: 0x3 }), + SemanticTag({ name: "Forward", id: 0x4 }), + SemanticTag({ name: "Backward", id: 0x5 }) + ), + + SemanticNamespace( + { + name: "Level", id: 0x5, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a certain level for a feature of a device (e.g. a button to set the speed of a " + + "fan).", + xref: { document: "namespace", section: "6" } + }, + + SemanticTag({ name: "Low", id: 0x0 }), + SemanticTag({ name: "Medium", id: 0x1 }), + SemanticTag({ name: "High", id: 0x2 }) + ), + + SemanticNamespace( + { + name: "Location", id: 0x6, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a location of a device (e.g. an outdoor temperature sensor).", + xref: { document: "namespace", section: "7" } + }, + + SemanticTag({ + name: "Indoor", id: 0x0, + description: "Element is indoors or related to indoor equipment/conditions (e.g. the \"indoor\" temperature)." + }), + SemanticTag({ + name: "Outdoor", id: 0x1, + description: "Element is outdoors or related to outdoor equipment/conditions (e.g. the \"outdoor\" temperature)." + }), + SemanticTag({ + name: "Inside", id: 0x2, + description: "Element is located inside the equipment (e.g. a sensor \"inside\" a cabinet)." + }), + SemanticTag({ + name: "Outside", id: 0x3, + description: "Element is located outside the equipment (e.g. a sensor \"outside\" a cabinet)" + }) + ), + + SemanticNamespace( + { + name: "Number", id: 0x7, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a certain numeric feature of a device (e.g. a numeric input button).", + xref: { document: "namespace", section: "8" } + }, + + SemanticTag({ name: "Zero", id: 0x0 }), + SemanticTag({ name: "One", id: 0x1 }), + SemanticTag({ name: "Two", id: 0x2 }), + SemanticTag({ name: "Three", id: 0x3 }), + SemanticTag({ name: "Four", id: 0x4 }), + SemanticTag({ name: "Five", id: 0x5 }), + SemanticTag({ name: "Six", id: 0x6 }), + SemanticTag({ name: "Seven", id: 0x7 }), + SemanticTag({ name: "Eight", id: 0x8 }), + SemanticTag({ name: "Nine", id: 0x9 }), + SemanticTag({ name: "Ten", id: 0xa }) + ), + + SemanticNamespace( + { + name: "Position", id: 0x8, + + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a position relative to the device (e.g. the temperature sensor in the top drawer " + + "of a refrigerator, or location of the buttons on a multi-button switch device). Note the difference " + + "with Chapter 5, Common Direction Semantic Tag Namespace." + + "\n" + + "When multiple endpoints are used for device types, and the associated consumer-facing locations of " + + "those endpoints are organized in a straight line, grid or matrix, these endpoints SHOULD be " + + "allocated in top-to-bottom, left-to-right order." + + "\n" + + "For grids or arrays larger than 3 elements in any direction, the Row and Column tags SHOULD be used." + + "\n" + + "If the Row or Column tags are used, the Label field in the same Semantic Tag structure shall be " + + "filled with a number comprised of Arabic numerals encoded as a string to indicate the row/column of " + + "the item. Number words (e.g. \"one\", \"two\", etc.) shall NOT be used to describe the position of the " + + "item. The first row/column shall use Label \"1\".", + + xref: { document: "namespace", section: "9" } + }, + + SemanticTag({ name: "Left", id: 0x0 }), + SemanticTag({ name: "Right", id: 0x1 }), + SemanticTag({ name: "Top", id: 0x2 }), + SemanticTag({ name: "Bottom", id: 0x3 }), + SemanticTag({ name: "Middle", id: 0x4 }), + SemanticTag({ name: "Row", id: 0x5, description: "Numeric value provided in Label field" }), + SemanticTag({ name: "Column", id: 0x6, description: "Numeric value provided in Label field" }) + ), + + SemanticNamespace( + { + name: "LandmarkNamespace", id: 0x11, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a home landmark.", + xref: { document: "namespace", section: "10" } + }, + + SemanticTag({ name: "Air Conditioner", id: 0x0 }), + SemanticTag({ name: "Air Purifier", id: 0x1 }), + SemanticTag({ name: "Back Door", id: 0x2 }), + SemanticTag({ name: "Bar Stool", id: 0x3 }), + SemanticTag({ name: "Bath Mat", id: 0x4 }), + SemanticTag({ name: "Bathtub", id: 0x5 }), + SemanticTag({ name: "Bed", id: 0x6 }), + SemanticTag({ name: "Bookshelf", id: 0x7 }), + SemanticTag({ name: "Chair", id: 0x8 }), + SemanticTag({ name: "Christmas Tree", id: 0x9 }), + SemanticTag({ name: "Coat Rack", id: 0xa }), + SemanticTag({ name: "Coffee Table", id: 0xb }), + SemanticTag({ name: "Cooking Range", id: 0xc }), + SemanticTag({ name: "Couch", id: 0xd }), + SemanticTag({ name: "Countertop", id: 0xe }), + SemanticTag({ name: "Cradle", id: 0xf }), + SemanticTag({ name: "Crib", id: 0x10 }), + SemanticTag({ name: "Desk", id: 0x11 }), + SemanticTag({ name: "Dining Table", id: 0x12 }), + SemanticTag({ name: "Dishwasher", id: 0x13 }), + SemanticTag({ name: "Door", id: 0x14 }), + SemanticTag({ name: "Dresser", id: 0x15 }), + SemanticTag({ name: "Laundry Dryer", id: 0x16 }), + SemanticTag({ name: "Fan", id: 0x17 }), + SemanticTag({ name: "Fireplace", id: 0x18 }), + SemanticTag({ name: "Freezer", id: 0x19 }), + SemanticTag({ name: "Front Door", id: 0x1a }), + SemanticTag({ name: "High Chair", id: 0x1b }), + SemanticTag({ name: "Kitchen Island", id: 0x1c }), + SemanticTag({ name: "Lamp", id: 0x1d }), + SemanticTag({ name: "Litter Box", id: 0x1e }), + SemanticTag({ name: "Mirror", id: 0x1f }), + SemanticTag({ name: "Nightstand", id: 0x20 }), + SemanticTag({ name: "Oven", id: 0x21 }), + SemanticTag({ name: "Pet Bed", id: 0x22 }), + SemanticTag({ name: "Pet Bowl", id: 0x23 }), + SemanticTag({ name: "Pet Crate", id: 0x24 }), + SemanticTag({ name: "Refrigerator", id: 0x25 }), + SemanticTag({ name: "Scratching Post", id: 0x26 }), + SemanticTag({ name: "Shoe Rack", id: 0x27 }), + SemanticTag({ name: "Shower", id: 0x28 }), + SemanticTag({ name: "Side Door", id: 0x29 }), + SemanticTag({ name: "Sink", id: 0x2a }), + SemanticTag({ name: "Sofa", id: 0x2b }), + SemanticTag({ name: "Stove", id: 0x2c }), + SemanticTag({ name: "Table", id: 0x2d }), + SemanticTag({ name: "Toilet", id: 0x2e }), + SemanticTag({ name: "Trash Can", id: 0x2f }), + SemanticTag({ name: "Laundry Washer", id: 0x30 }), + SemanticTag({ name: "Window", id: 0x31 }), + SemanticTag({ name: "Wine Cooler", id: 0x32 }) + ), + + SemanticNamespace( + { + name: "RelativePosition", id: 0x12, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a position relative to some reference, which must be specified by the user of " + + "these tags. For example, the position may be relative to a household item, such as a dining table, " + + "and the user of these tags must indicate that. Note the difference with Chapter 9, Common Position " + + "Semantic Tag Namespace, which contains tags indicating the position relative to the device.", + xref: { document: "namespace", section: "11" } + }, + + SemanticTag({ name: "Under", id: 0x0 }), + SemanticTag({ name: "Next To", id: 0x1, description: "Area in proximity to the point of reference" }), + SemanticTag({ name: "Around", id: 0x2, description: "The area surrounding the point the reference" }), + SemanticTag({ name: "On", id: 0x3 }), + SemanticTag({ name: "Above", id: 0x4 }), + SemanticTag({ name: "Front Of", id: 0x5 }), + SemanticTag({ name: "Behind", id: 0x6 }) + ), + + SemanticNamespace( + { + name: "ElectricalMeasurement", id: 0xa, + details: "The tags contained in this namespace are restricted for use in the electrical measurement domain " + + "and shall NOT be used in any other domain or context.", + xref: { document: "namespace", section: "12" } + }, + + SemanticTag({ name: "DC", id: 0x0, description: "Indicates values measured for a DC load" }), + SemanticTag({ + name: "AC", id: 0x1, + description: "Indicates values measured for a single-phase AC load, or values measured for the collective load on a polyphase AC power supply" + }), + SemanticTag({ + name: "ACPhase1", id: 0x2, + description: "Indicates values measured for an AC load on phase 1 of a polyphase power supply" + }), + SemanticTag({ + name: "ACPhase2", id: 0x3, + description: "Indicates values measured for an AC load on phase 2 of a polyphase power supply" + }), + SemanticTag({ + name: "ACPhase3", id: 0x4, + description: "Indicates values measured for an AC load on phase 3 of a polyphase power supply" + }) + ), + + SemanticNamespace( + { + name: "AreaNamespace", id: 0x10, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with an indoor or outdoor area of a home.", + xref: { document: "namespace", section: "13" } + }, + + SemanticTag({ name: "Aisle", id: 0x0 }), + SemanticTag({ name: "Attic", id: 0x1 }), + SemanticTag({ name: "Back Door", id: 0x2 }), + SemanticTag({ name: "Back Yard", id: 0x3 }), + SemanticTag({ name: "Balcony", id: 0x4 }), + SemanticTag({ name: "Ballroom", id: 0x5 }), + SemanticTag({ name: "Bathroom", id: 0x6, description: "Also known as Restroom" }), + SemanticTag({ name: "Bedroom", id: 0x7 }), + SemanticTag({ name: "Border", id: 0x8 }), + SemanticTag({ name: "Boxroom", id: 0x9, description: "A small room typically used for storage" }), + SemanticTag({ name: "Breakfast Room", id: 0xa }), + SemanticTag({ name: "Carport", id: 0xb }), + SemanticTag({ name: "Cellar", id: 0xc }), + SemanticTag({ name: "Cloakroom", id: 0xd }), + SemanticTag({ name: "Closet", id: 0xe }), + SemanticTag({ name: "Conservatory", id: 0xf }), + SemanticTag({ name: "Corridor", id: 0x10 }), + SemanticTag({ name: "Craft Room", id: 0x11 }), + SemanticTag({ name: "Cupboard", id: 0x12 }), + SemanticTag({ name: "Deck", id: 0x13 }), + SemanticTag({ + name: "Den", id: 0x14, + description: "A small, comfortable room for individual activities such as work or hobbies" + }), + SemanticTag({ name: "Dining", id: 0x15 }), + SemanticTag({ name: "Drawing Room", id: 0x16 }), + SemanticTag({ name: "Dressing Room", id: 0x17 }), + SemanticTag({ name: "Driveway", id: 0x18 }), + SemanticTag({ name: "Elevator", id: 0x19 }), + SemanticTag({ name: "Ensuite", id: 0x1a, description: "A bathroom directly accessible from a bedroom" }), + SemanticTag({ name: "Entrance", id: 0x1b }), + SemanticTag({ name: "Entryway", id: 0x1c }), + SemanticTag({ name: "Family Room", id: 0x1d }), + SemanticTag({ name: "Foyer", id: 0x1e }), + SemanticTag({ name: "Front Door", id: 0x1f }), + SemanticTag({ name: "Front Yard", id: 0x20 }), + SemanticTag({ name: "Game Room", id: 0x21 }), + SemanticTag({ name: "Garage", id: 0x22 }), + SemanticTag({ name: "Garage Door", id: 0x23 }), + SemanticTag({ name: "Garden", id: 0x24 }), + SemanticTag({ name: "Garden Door", id: 0x25 }), + SemanticTag({ name: "Guest Bathroom", id: 0x26, description: "Also known as Guest Restroom" }), + SemanticTag({ name: "Guest Bedroom", id: 0x27 }), + SemanticTag({ name: "Guest Room", id: 0x28 }), + SemanticTag({ name: "Gym", id: 0x29 }), + SemanticTag({ name: "Hallway", id: 0x2a }), + SemanticTag({ name: "Hearth Room", id: 0x2b, description: "A cozy room containing a fireplace or other point heat source" }), + SemanticTag({ name: "Kids Room", id: 0x2c }), + SemanticTag({ name: "Kids Bedroom", id: 0x2d }), + SemanticTag({ name: "Kitchen", id: 0x2e }), + SemanticTag({ name: "Laundry Room", id: 0x2f }), + SemanticTag({ name: "Lawn", id: 0x30 }), + SemanticTag({ name: "Library", id: 0x31 }), + SemanticTag({ name: "Living Room", id: 0x32 }), + SemanticTag({ name: "Lounge", id: 0x33 }), + SemanticTag({ name: "Media/TV Room", id: 0x34 }), + SemanticTag({ + name: "Mud Room", id: 0x35, + description: "A space used to remove soiled garments prior to entering the domicile proper" + }), + SemanticTag({ name: "Music Room", id: 0x36 }), + SemanticTag({ name: "Nursery", id: 0x37 }), + SemanticTag({ name: "Office", id: 0x38 }), + SemanticTag({ name: "Outdoor Kitchen", id: 0x39 }), + SemanticTag({ name: "Outside", id: 0x3a }), + SemanticTag({ name: "Pantry", id: 0x3b, description: "AKA a larder, a place where food is stored" }), + SemanticTag({ name: "Parking Lot", id: 0x3c }), + SemanticTag({ name: "Parlor", id: 0x3d }), + SemanticTag({ name: "Patio", id: 0x3e }), + SemanticTag({ name: "Play Room", id: 0x3f }), + SemanticTag({ name: "Pool Room", id: 0x40 }), + SemanticTag({ name: "Porch", id: 0x41 }), + SemanticTag({ name: "Primary Bathroom", id: 0x42 }), + SemanticTag({ name: "Primary Bedroom", id: 0x43 }), + SemanticTag({ name: "Ramp", id: 0x44 }), + SemanticTag({ name: "Reception Room", id: 0x45 }), + SemanticTag({ name: "Recreation Room", id: 0x46 }), + SemanticTag({ name: "Roof", id: 0x47 }), + SemanticTag({ name: "Sauna", id: 0x48 }), + SemanticTag({ name: "Scullery", id: 0x49, description: "A utility space for cleaning dishes and laundry" }), + SemanticTag({ name: "Sewing Room", id: 0x4a }), + SemanticTag({ name: "Shed", id: 0x4b }), + SemanticTag({ name: "Side Door", id: 0x4c }), + SemanticTag({ name: "Side Yard", id: 0x4d }), + SemanticTag({ name: "Sitting Room", id: 0x4e }), + SemanticTag({ + name: "Snug", id: 0x4f, + description: "An informal space meant to be 'cozy', 'snug', relaxed, meant to share with family or friends" + }), + SemanticTag({ name: "Spa", id: 0x50 }), + SemanticTag({ name: "Staircase", id: 0x51 }), + SemanticTag({ name: "Steam Room", id: 0x52 }), + SemanticTag({ name: "Storage Room", id: 0x53 }), + SemanticTag({ name: "Studio", id: 0x54 }), + SemanticTag({ name: "Study", id: 0x55 }), + SemanticTag({ name: "Sun Room", id: 0x56 }), + SemanticTag({ name: "Swimming Pool", id: 0x57 }), + SemanticTag({ name: "Terrace", id: 0x58 }), + SemanticTag({ name: "Toilet", id: 0x59, description: "A room dedicated to a toilet; a water closet / WC" }), + SemanticTag({ name: "Utility Room", id: 0x5a }), + SemanticTag({ name: "Ward", id: 0x5b }), + SemanticTag({ name: "Workshop", id: 0x5c }) + ), + + SemanticNamespace( + { + name: "Laundry", id: 0xe, + details: "The tags contained in this namespace are restricted for use in the laundry domain and shall NOT be " + + "used in any other domain or context.", + xref: { document: "namespace", section: "14" } + }, + + SemanticTag({ name: "Normal", id: 0x0 }), + SemanticTag({ name: "Light Dry", id: 0x1 }), + SemanticTag({ name: "Extra Dry", id: 0x2 }), + SemanticTag({ name: "No Dry", id: 0x3 }) + ), + + SemanticNamespace( + { + name: "PowerSource", id: 0xf, + details: "The tags contained in this namespace are restricted for use in the power source domain and shall " + + "NOT be used in any other domain or context.", + xref: { document: "namespace", section: "15" } + }, + + SemanticTag({ + name: "Unknown", id: 0x0, + description: "The Power Source cluster is related to power provided from an unknown source" + }), + + SemanticTag({ + name: "Grid", id: 0x1, + description: "The Power Source cluster is related to power provided from the electrical grid", + details: "Power Source clusters with this tag shall implement the WIRED feature.", + xref: { document: "namespace", section: "15.1" } + }), + + SemanticTag({ + name: "Solar", id: 0x2, + description: "The Power Source cluster is related to power provided from a solar panel array", + details: "Power Source clusters with this tag shall implement the WIRED feature.", + xref: { document: "namespace", section: "15.2" } + }), + + SemanticTag({ + name: "Battery", id: 0x3, + description: "The Power Source cluster is related to power provided from a battery", + details: "Power Source clusters with this tag shall implement the BAT feature.", + xref: { document: "namespace", section: "15.3" } + }), + + SemanticTag({ + name: "EV", id: 0x4, + description: "The Power Source cluster is related to power provided from an electric vehicle", + details: "Power Source clusters with this tag shall implement the BAT feature.", + xref: { document: "namespace", section: "15.4" } + }) + ), + + SemanticNamespace( + { + name: "Refrigerator", id: 0x41, + details: "The tags contained in this namespace are restricted for use in the refrigerator domain and shall " + + "NOT be used in any other domain or context.", + xref: { document: "namespace", section: "16" } + }, + + SemanticTag({ name: "Refrigerator", id: 0x0 }), + SemanticTag({ name: "Freezer", id: 0x1 }) + ), + + SemanticNamespace( + { + name: "RoomAirConditioner", id: 0x42, + details: "The tags contained in this namespace are restricted for use in the room air conditioner domain and " + + "shall NOT be used in any other domain or context.", + xref: { document: "namespace", section: "17" } + }, + + SemanticTag({ name: "Evaporator", id: 0x0 }), + SemanticTag({ name: "Condenser", id: 0x1 }) + ), + + SemanticNamespace( + { + name: "Switches", id: 0x43, + + details: "The tags contained in this namespace are restricted for use in the switches domain and shall NOT be " + + "used in any other domain or context. They are intended to indicate the function of a button on a " + + "switch device to allow a client to make an optimized user interface which matches the actual device " + + "without requiring a-priori knowledge of the layout of each specific switch device." + + "\n" + + "Please see the rules for applying these and other tags for switch devices, e.g. from the Common " + + "Position Namespace and the Common Number Namespace in the Generic Switch device type section in the " + + "Device Library.", + + xref: { document: "namespace", section: "18" } + }, + + SemanticTag({ name: "On", id: 0x0 }), + SemanticTag({ name: "Off", id: 0x1 }), + SemanticTag({ name: "Toggle", id: 0x2 }), + SemanticTag({ name: "Up", id: 0x3, description: "e.g. dim up (light)" }), + SemanticTag({ name: "Down", id: 0x4, description: "e.g. dim down (light)" }), + SemanticTag({ name: "Next", id: 0x5, description: "e.g. select next scene" }), + SemanticTag({ name: "Previous", id: 0x6, description: "e.g. select previous scene" }), + SemanticTag({ name: "Enter/OK/Select", id: 0x7 }), + + SemanticTag({ + name: "Custom", id: 0x8, description: "Textual description provided in Label field", + details: "When this value is used, the Label field in the same Semantic Tag structure shall be filled with a " + + "textual description of the function indicated on the button, such as a label or icon printed on the " + + "button, e.g. \"dining\".", + xref: { document: "namespace", section: "18.1" } + }) + ) +) diff --git a/packages/cli-tool/src/tsconfig.json b/packages/cli-tool/src/tsconfig.json index 7f8d151312..c40d1b8130 100644 --- a/packages/cli-tool/src/tsconfig.json +++ b/packages/cli-tool/src/tsconfig.json @@ -26,6 +26,9 @@ { "path": "../../testing/src" }, + { + "path": "../../tools/src" + }, { "path": "../../types/src" } diff --git a/packages/create/src/formatting.ts b/packages/create/src/formatting.ts index e8bedb7be9..e18736a787 100644 --- a/packages/create/src/formatting.ts +++ b/packages/create/src/formatting.ts @@ -47,7 +47,7 @@ export function visibleWidthOf(str: string) { } export function fittedTextOf(text: string, width = stdout.columns) { - if (width <= 20) { + if (typeof width !== "number" || width <= 20) { return text; } @@ -69,7 +69,7 @@ export function fittedTextOf(text: string, width = stdout.columns) { return paragraphs.join("\n"); } -function wrap(text: string, width = stdout.columns) { +function wrap(text: string, width: number) { const words = text.trim().split(/\s+/); let lineWidth = 0; let line = ""; diff --git a/packages/create/src/tsconfig.json b/packages/create/src/tsconfig.json index 5623d22c4a..caea689cae 100644 --- a/packages/create/src/tsconfig.json +++ b/packages/create/src/tsconfig.json @@ -7,5 +7,9 @@ "node" ] }, - "references": [] + "references": [ + { + "path": "../../tools/src" + } + ] } \ No newline at end of file diff --git a/packages/examples/src/tsconfig.json b/packages/examples/src/tsconfig.json index e08d79bf58..fbe42346e4 100644 --- a/packages/examples/src/tsconfig.json +++ b/packages/examples/src/tsconfig.json @@ -14,6 +14,9 @@ }, { "path": "../../nodejs/src" + }, + { + "path": "../../tools/src" } ] } \ No newline at end of file diff --git a/packages/general/src/log/Diagnostic.ts b/packages/general/src/log/Diagnostic.ts index e896e36cb8..9f6970f775 100644 --- a/packages/general/src/log/Diagnostic.ts +++ b/packages/general/src/log/Diagnostic.ts @@ -390,12 +390,138 @@ export namespace Diagnostic { .map(([key]) => key) .join(" "); } + + /** + * Extract message and stack diagnostic details. + */ + export function messageAndStackFor( + error: any, + parentStack?: string[], + ): { message: string; stack?: unknown[]; stackLines?: string[] } { + let message: string | undefined; + let rawStack: string | undefined; + if (error !== undefined && error !== null) { + if (typeof error === "string" || typeof error === "number") { + return { message: `${error}` }; + } + if ("message" in error) { + ({ message, stack: rawStack } = error); + } else if (error.message) { + message = typeof error.message === "string" ? message : error.toString(); + } + } + if (message === undefined || message === null || message === "") { + if (error !== undefined && error !== null) { + message = error.constructor.name; + if (!message || message === "Error") { + message = "(unknown error)"; + } + } else { + message = "(unknown error)"; + } + } + if (!rawStack) { + return { message }; + } + + rawStack = rawStack.toString(); + + // Strip extra node garbage off stack from node asserts + rawStack = rawStack.replace(/^.*?\n\nError: /gs, "Error: "); + + // Strip off redundant error tag from v8 + if (rawStack.startsWith("Error: ")) { + rawStack = rawStack.slice(7); + } + + // Strip off redundant message from v8 + const pos = rawStack.indexOf(message); + if (pos !== -1) { + rawStack = rawStack.slice(pos + message.length).trim(); + } + + // Extract raw lines + let stackLines = rawStack + .split("\n") + .map(line => line.trim()) + .filter(line => line !== ""); + + // Node helpfully gives us this if there's no message. It's not even the name of the error class, just "Error" + if (stackLines[0] === "Error") { + stackLines.shift(); + } + + // If there's a parent stack, identify the portion of the stack in common so we don't have to repeat it. The stacks + // may be truncated by the VM so this is not 100% guaranteed correct with recursive functions, but accidental + // mismatches are unlikely + let truncatedToParent = false; + if (parentStack) { + let truncateTo = 0; + + // For each line in the stack, find the line in the parent. Skip the last two lines because truncating them + // won't save space + stackSearch: for (; truncateTo < stackLines.length - 1; truncateTo++) { + let parentPos = parentStack.indexOf(stackLines[truncateTo]); + if (parentPos === -1) { + continue; + } + + // Found the line. If all subsequent lines match then we truncate. If either stack terminates before the + // other, assume the stacks are truncated and consider a match + parentPos++; + for ( + let pos = truncateTo + 1; + pos < stackLines.length && parentPos < parentStack.length; + pos++, parentPos++ + ) { + if (stackLines[pos] !== parentStack[parentPos]) { + continue stackSearch; + } + } + + // Found a match. Truncate but leave the top-most shared frame to make it clear where the commonality + // with the parent starts + stackLines = stackLines.slice(0, truncateTo + 1); + truncatedToParent = true; + break; + } + } + + // Spiff up stack lines a bit + const stack = Array(); + for (const line of stackLines) { + const match1 = line.match(/^at\s+(?:(.+)\s+\(([^)]+)\)|())$/); + if (match1) { + const value = [Diagnostic.weak("at "), match1[1] ?? match1[3]]; + if (match1[2] !== undefined) { + value.push(Diagnostic.weak(" ("), Diagnostic.weak(match1[2]), Diagnostic.weak(")")); + } + stack.push(Diagnostic.squash(...value)); + continue; + } + + const match2 = line.match(/^at\s+(.+)(:\d+:\d+)$/); + if (match2) { + stack.push(Diagnostic.squash(Diagnostic.weak("at "), match2[1], Diagnostic.weak(match2[2]))); + continue; + } + + stack.push(line); + } + + // Add truncation note + if (truncatedToParent) { + stack.push(Diagnostic.weak("(see parent frames)")); + } + + return { message, stack, stackLines }; + } } function formatError(error: any, options: { messagePrefix?: string; parentStack?: string[] } = {}) { const { messagePrefix, parentStack } = options; - const messageAndStack = messageAndStackFor(error, parentStack); + const messageAndStack = Diagnostic.messageAndStackFor(error, parentStack); let { stack, stackLines } = messageAndStack; let { message } = messageAndStack; @@ -456,123 +582,3 @@ function formatError(error: any, options: { messagePrefix?: string; parentStack? return list as Diagnostic; } - -function messageAndStackFor(error: any, parentStack?: string[]) { - let message: string | undefined; - let rawStack: string | undefined; - if (error !== undefined && error !== null) { - if (typeof error === "string" || typeof error === "number") { - return { message: `${error}` }; - } - if ("message" in error) { - ({ message, stack: rawStack } = error); - } else if (error.message) { - message = typeof error.message === "string" ? message : error.toString(); - } - } - if (message === undefined || message === null || message === "") { - if (error !== undefined && error !== null) { - message = error.constructor.name; - if (!message || message === "Error") { - message = "(unknown error)"; - } - } else { - message = "(unknown error)"; - } - } - if (!rawStack) { - return { message }; - } - - rawStack = rawStack.toString(); - - // Strip extra node garbage off stack from node asserts - rawStack = rawStack.replace(/^.*?\n\nError: /gs, "Error: "); - - // Strip off redundant error tag from v8 - if (rawStack.startsWith("Error: ")) { - rawStack = rawStack.slice(7); - } - - // Strip off redundant message from v8 - const pos = rawStack.indexOf(message); - if (pos !== -1) { - rawStack = rawStack.slice(pos + message.length).trim(); - } - - // Extract raw lines - let stackLines = rawStack - .split("\n") - .map(line => line.trim()) - .filter(line => line !== ""); - - // Node helpfully gives us this if there's no message. It's not even the name of the error class, just "Error" - if (stackLines[0] === "Error") { - stackLines.shift(); - } - - // If there's a parent stack, identify the portion of the stack in common so we don't have to repeat it. The stacks - // may be truncated by the VM so this is not 100% guaranteed correct with recursive functions, but accidental - // mismatches are unlikely - let truncatedToParent = false; - if (parentStack) { - let truncateTo = 0; - - // For each line in the stack, find the line in the parent. Skip the last two lines because truncating them - // won't save space - stackSearch: for (; truncateTo < stackLines.length - 1; truncateTo++) { - let parentPos = parentStack.indexOf(stackLines[truncateTo]); - if (parentPos === -1) { - continue; - } - - // Found the line. If all subsequent lines match then we truncate. If either stack terminates before the - // other, assume the stacks are truncated and consider a match - parentPos++; - for ( - let pos = truncateTo + 1; - pos < stackLines.length && parentPos < parentStack.length; - pos++, parentPos++ - ) { - if (stackLines[pos] !== parentStack[parentPos]) { - continue stackSearch; - } - } - - // Found a match. Truncate but leave the top-most shared frame to make it clear where the commonality - // with the parent starts - stackLines = stackLines.slice(0, truncateTo + 1); - truncatedToParent = true; - break; - } - } - - // Spiff up stack lines a bit - const stack = Array(); - for (const line of stackLines) { - const match1 = line.match(/^at\s+(?:(.+)\s+\(([^)]+)\)|())$/); - if (match1) { - const value = [Diagnostic.weak("at "), match1[1] ?? match1[3]]; - if (match1[2] !== undefined) { - value.push(Diagnostic.weak(" ("), Diagnostic.weak(match1[2]), Diagnostic.weak(")")); - } - stack.push(Diagnostic.squash(...value)); - continue; - } - - const match2 = line.match(/^at\s+(.+)(:\d+:\d+)$/); - if (match2) { - stack.push(Diagnostic.squash(Diagnostic.weak("at "), match2[1], Diagnostic.weak(match2[2]))); - continue; - } - - stack.push(line); - } - - // Add truncation note - if (truncatedToParent) { - stack.push(Diagnostic.weak("(see parent frames)")); - } - - return { message, stack, stackLines }; -} diff --git a/packages/general/src/log/LogFormat.ts b/packages/general/src/log/LogFormat.ts index 40ed612417..cbffd1b984 100644 --- a/packages/general/src/log/LogFormat.ts +++ b/packages/general/src/log/LogFormat.ts @@ -691,3 +691,16 @@ function ensureIndented(text: string) { if (MatterError.formatterFor === MatterError.defaultFormatterFactory) { MatterError.formatterFor = LogFormat; } + +if (typeof MatterHooks !== "undefined") { + MatterHooks.messageAndStackFor = (error: unknown, parentStack?: string[]) => { + const { message, stack, stackLines } = Diagnostic.messageAndStackFor(error, parentStack); + + let stackStr; + if (stack) { + stackStr = stack.map(frame => LogFormat.ansi(frame).trim()).join("\n"); + } + + return { message, stack: stackStr, stackLines }; + }; +} diff --git a/packages/main/src/forwards/behaviors/access-control.ts b/packages/main/src/forwards/behaviors/access-control.ts index 72fe4069ef..9945ef80d3 100644 --- a/packages/main/src/forwards/behaviors/access-control.ts +++ b/packages/main/src/forwards/behaviors/access-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/account-login.ts b/packages/main/src/forwards/behaviors/account-login.ts index 945d414d65..def1aed6f4 100644 --- a/packages/main/src/forwards/behaviors/account-login.ts +++ b/packages/main/src/forwards/behaviors/account-login.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/actions.ts b/packages/main/src/forwards/behaviors/actions.ts index 4f2f281cdf..d20882370b 100644 --- a/packages/main/src/forwards/behaviors/actions.ts +++ b/packages/main/src/forwards/behaviors/actions.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/activated-carbon-filter-monitoring.ts b/packages/main/src/forwards/behaviors/activated-carbon-filter-monitoring.ts index 83d4592489..d81e3f9e3f 100644 --- a/packages/main/src/forwards/behaviors/activated-carbon-filter-monitoring.ts +++ b/packages/main/src/forwards/behaviors/activated-carbon-filter-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/administrator-commissioning.ts b/packages/main/src/forwards/behaviors/administrator-commissioning.ts index 07d277c197..953957c81c 100644 --- a/packages/main/src/forwards/behaviors/administrator-commissioning.ts +++ b/packages/main/src/forwards/behaviors/administrator-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/air-quality.ts b/packages/main/src/forwards/behaviors/air-quality.ts index 0d052d2fc2..396ae19525 100644 --- a/packages/main/src/forwards/behaviors/air-quality.ts +++ b/packages/main/src/forwards/behaviors/air-quality.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/alarm-base.ts b/packages/main/src/forwards/behaviors/alarm-base.ts index b8a98f3c16..f4cd894582 100644 --- a/packages/main/src/forwards/behaviors/alarm-base.ts +++ b/packages/main/src/forwards/behaviors/alarm-base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/application-basic.ts b/packages/main/src/forwards/behaviors/application-basic.ts index 6278f8636b..63460b4736 100644 --- a/packages/main/src/forwards/behaviors/application-basic.ts +++ b/packages/main/src/forwards/behaviors/application-basic.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/application-launcher.ts b/packages/main/src/forwards/behaviors/application-launcher.ts index 14b98e1e41..51ff128380 100644 --- a/packages/main/src/forwards/behaviors/application-launcher.ts +++ b/packages/main/src/forwards/behaviors/application-launcher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/audio-output.ts b/packages/main/src/forwards/behaviors/audio-output.ts index 1ebc800822..92ccb907bf 100644 --- a/packages/main/src/forwards/behaviors/audio-output.ts +++ b/packages/main/src/forwards/behaviors/audio-output.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/ballast-configuration.ts b/packages/main/src/forwards/behaviors/ballast-configuration.ts index fbe51a9b95..712dea7b6d 100644 --- a/packages/main/src/forwards/behaviors/ballast-configuration.ts +++ b/packages/main/src/forwards/behaviors/ballast-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/basic-information.ts b/packages/main/src/forwards/behaviors/basic-information.ts index d1fb201a34..a76a95b5ca 100644 --- a/packages/main/src/forwards/behaviors/basic-information.ts +++ b/packages/main/src/forwards/behaviors/basic-information.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/binding.ts b/packages/main/src/forwards/behaviors/binding.ts index 2dff6d33ec..2f36a55c5b 100644 --- a/packages/main/src/forwards/behaviors/binding.ts +++ b/packages/main/src/forwards/behaviors/binding.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/boolean-state-configuration.ts b/packages/main/src/forwards/behaviors/boolean-state-configuration.ts index 056a7a6aae..232acdcaf3 100644 --- a/packages/main/src/forwards/behaviors/boolean-state-configuration.ts +++ b/packages/main/src/forwards/behaviors/boolean-state-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/boolean-state.ts b/packages/main/src/forwards/behaviors/boolean-state.ts index c8c3c73dc3..10547c4e0c 100644 --- a/packages/main/src/forwards/behaviors/boolean-state.ts +++ b/packages/main/src/forwards/behaviors/boolean-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/bridged-device-basic-information.ts b/packages/main/src/forwards/behaviors/bridged-device-basic-information.ts index 0e36df3d65..b8f47e52e6 100644 --- a/packages/main/src/forwards/behaviors/bridged-device-basic-information.ts +++ b/packages/main/src/forwards/behaviors/bridged-device-basic-information.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/carbon-dioxide-concentration-measurement.ts b/packages/main/src/forwards/behaviors/carbon-dioxide-concentration-measurement.ts index 4e55786167..c8965b5d29 100644 --- a/packages/main/src/forwards/behaviors/carbon-dioxide-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/carbon-dioxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/carbon-monoxide-concentration-measurement.ts b/packages/main/src/forwards/behaviors/carbon-monoxide-concentration-measurement.ts index ffd0acce16..30419fa820 100644 --- a/packages/main/src/forwards/behaviors/carbon-monoxide-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/carbon-monoxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/channel.ts b/packages/main/src/forwards/behaviors/channel.ts index 74cacc523c..a4c45d021b 100644 --- a/packages/main/src/forwards/behaviors/channel.ts +++ b/packages/main/src/forwards/behaviors/channel.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/color-control.ts b/packages/main/src/forwards/behaviors/color-control.ts index b39ca2f509..2efc2dc663 100644 --- a/packages/main/src/forwards/behaviors/color-control.ts +++ b/packages/main/src/forwards/behaviors/color-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/pulse-width-modulation.ts b/packages/main/src/forwards/behaviors/commissioner-control.ts similarity index 58% rename from packages/main/src/forwards/clusters/pulse-width-modulation.ts rename to packages/main/src/forwards/behaviors/commissioner-control.ts index 9fac737934..689a57d14a 100644 --- a/packages/main/src/forwards/clusters/pulse-width-modulation.ts +++ b/packages/main/src/forwards/behaviors/commissioner-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,4 +8,4 @@ import "#platform"; -export * from "#clusters/pulse-width-modulation"; +export * from "#behaviors/commissioner-control"; diff --git a/packages/main/src/forwards/behaviors/concentration-measurement.ts b/packages/main/src/forwards/behaviors/concentration-measurement.ts index 06bc2ed1c9..7159c0a0e8 100644 --- a/packages/main/src/forwards/behaviors/concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/content-app-observer.ts b/packages/main/src/forwards/behaviors/content-app-observer.ts index db6d970769..3e63d91506 100644 --- a/packages/main/src/forwards/behaviors/content-app-observer.ts +++ b/packages/main/src/forwards/behaviors/content-app-observer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/content-control.ts b/packages/main/src/forwards/behaviors/content-control.ts index 3042efc495..e7e3bd29a3 100644 --- a/packages/main/src/forwards/behaviors/content-control.ts +++ b/packages/main/src/forwards/behaviors/content-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/content-launcher.ts b/packages/main/src/forwards/behaviors/content-launcher.ts index c8169b07de..25799c7fe1 100644 --- a/packages/main/src/forwards/behaviors/content-launcher.ts +++ b/packages/main/src/forwards/behaviors/content-launcher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/descriptor.ts b/packages/main/src/forwards/behaviors/descriptor.ts index f62aa22cff..42fa67b803 100644 --- a/packages/main/src/forwards/behaviors/descriptor.ts +++ b/packages/main/src/forwards/behaviors/descriptor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/device-energy-management-mode.ts b/packages/main/src/forwards/behaviors/device-energy-management-mode.ts index c87594950a..344b61d66a 100644 --- a/packages/main/src/forwards/behaviors/device-energy-management-mode.ts +++ b/packages/main/src/forwards/behaviors/device-energy-management-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/device-energy-management.ts b/packages/main/src/forwards/behaviors/device-energy-management.ts index cbd90f77cf..d529ded6c8 100644 --- a/packages/main/src/forwards/behaviors/device-energy-management.ts +++ b/packages/main/src/forwards/behaviors/device-energy-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/diagnostic-logs.ts b/packages/main/src/forwards/behaviors/diagnostic-logs.ts index e575cc85b7..5efa68beb8 100644 --- a/packages/main/src/forwards/behaviors/diagnostic-logs.ts +++ b/packages/main/src/forwards/behaviors/diagnostic-logs.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/dishwasher-alarm.ts b/packages/main/src/forwards/behaviors/dishwasher-alarm.ts index 4c9ffc48af..9641955fe0 100644 --- a/packages/main/src/forwards/behaviors/dishwasher-alarm.ts +++ b/packages/main/src/forwards/behaviors/dishwasher-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/dishwasher-mode.ts b/packages/main/src/forwards/behaviors/dishwasher-mode.ts index e1c477a0d5..5c2830995f 100644 --- a/packages/main/src/forwards/behaviors/dishwasher-mode.ts +++ b/packages/main/src/forwards/behaviors/dishwasher-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/door-lock.ts b/packages/main/src/forwards/behaviors/door-lock.ts index 8dfaa30ece..a82bf58f22 100644 --- a/packages/main/src/forwards/behaviors/door-lock.ts +++ b/packages/main/src/forwards/behaviors/door-lock.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/ecosystem-information.ts b/packages/main/src/forwards/behaviors/ecosystem-information.ts new file mode 100644 index 0000000000..dea6e9a5ea --- /dev/null +++ b/packages/main/src/forwards/behaviors/ecosystem-information.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/ecosystem-information"; diff --git a/packages/main/src/forwards/behaviors/electrical-energy-measurement.ts b/packages/main/src/forwards/behaviors/electrical-energy-measurement.ts index 8cf04d2c2e..89c4b4dc70 100644 --- a/packages/main/src/forwards/behaviors/electrical-energy-measurement.ts +++ b/packages/main/src/forwards/behaviors/electrical-energy-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/electrical-power-measurement.ts b/packages/main/src/forwards/behaviors/electrical-power-measurement.ts index c85039043e..f9ad47315f 100644 --- a/packages/main/src/forwards/behaviors/electrical-power-measurement.ts +++ b/packages/main/src/forwards/behaviors/electrical-power-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/energy-evse-mode.ts b/packages/main/src/forwards/behaviors/energy-evse-mode.ts index d1358bf005..7c2a31dbc0 100644 --- a/packages/main/src/forwards/behaviors/energy-evse-mode.ts +++ b/packages/main/src/forwards/behaviors/energy-evse-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/energy-evse.ts b/packages/main/src/forwards/behaviors/energy-evse.ts index e811c87d82..0512855eef 100644 --- a/packages/main/src/forwards/behaviors/energy-evse.ts +++ b/packages/main/src/forwards/behaviors/energy-evse.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/energy-preference.ts b/packages/main/src/forwards/behaviors/energy-preference.ts index e5d0cc044a..cc394821bb 100644 --- a/packages/main/src/forwards/behaviors/energy-preference.ts +++ b/packages/main/src/forwards/behaviors/energy-preference.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/ethernet-network-diagnostics.ts b/packages/main/src/forwards/behaviors/ethernet-network-diagnostics.ts index f232f93d65..a6fcc2f6b2 100644 --- a/packages/main/src/forwards/behaviors/ethernet-network-diagnostics.ts +++ b/packages/main/src/forwards/behaviors/ethernet-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/fan-control.ts b/packages/main/src/forwards/behaviors/fan-control.ts index 604a005bea..c3b1740c4e 100644 --- a/packages/main/src/forwards/behaviors/fan-control.ts +++ b/packages/main/src/forwards/behaviors/fan-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/fixed-label.ts b/packages/main/src/forwards/behaviors/fixed-label.ts index 5ed781e05d..ec8be76590 100644 --- a/packages/main/src/forwards/behaviors/fixed-label.ts +++ b/packages/main/src/forwards/behaviors/fixed-label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/flow-measurement.ts b/packages/main/src/forwards/behaviors/flow-measurement.ts index 885512fb7c..c57d69b7e1 100644 --- a/packages/main/src/forwards/behaviors/flow-measurement.ts +++ b/packages/main/src/forwards/behaviors/flow-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/formaldehyde-concentration-measurement.ts b/packages/main/src/forwards/behaviors/formaldehyde-concentration-measurement.ts index afdeb68056..0ba9b9ed55 100644 --- a/packages/main/src/forwards/behaviors/formaldehyde-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/formaldehyde-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/general-commissioning.ts b/packages/main/src/forwards/behaviors/general-commissioning.ts index 947e4c3b0f..e2d7f99fd3 100644 --- a/packages/main/src/forwards/behaviors/general-commissioning.ts +++ b/packages/main/src/forwards/behaviors/general-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/general-diagnostics.ts b/packages/main/src/forwards/behaviors/general-diagnostics.ts index a5768ce9bb..88e82d4062 100644 --- a/packages/main/src/forwards/behaviors/general-diagnostics.ts +++ b/packages/main/src/forwards/behaviors/general-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/group-key-management.ts b/packages/main/src/forwards/behaviors/group-key-management.ts index 978eaf0a1e..e6d2877d02 100644 --- a/packages/main/src/forwards/behaviors/group-key-management.ts +++ b/packages/main/src/forwards/behaviors/group-key-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/groups.ts b/packages/main/src/forwards/behaviors/groups.ts index c02f55d22a..0afba0fc58 100644 --- a/packages/main/src/forwards/behaviors/groups.ts +++ b/packages/main/src/forwards/behaviors/groups.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/hepa-filter-monitoring.ts b/packages/main/src/forwards/behaviors/hepa-filter-monitoring.ts index f49d0a5795..bd9fd3bd90 100644 --- a/packages/main/src/forwards/behaviors/hepa-filter-monitoring.ts +++ b/packages/main/src/forwards/behaviors/hepa-filter-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/icd-management.ts b/packages/main/src/forwards/behaviors/icd-management.ts index 1ed4578ef2..2922e7df94 100644 --- a/packages/main/src/forwards/behaviors/icd-management.ts +++ b/packages/main/src/forwards/behaviors/icd-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/identify.ts b/packages/main/src/forwards/behaviors/identify.ts index 4041572ba2..9ac4b5f8dd 100644 --- a/packages/main/src/forwards/behaviors/identify.ts +++ b/packages/main/src/forwards/behaviors/identify.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/illuminance-measurement.ts b/packages/main/src/forwards/behaviors/illuminance-measurement.ts index 0fccaf11f0..549b5907a5 100644 --- a/packages/main/src/forwards/behaviors/illuminance-measurement.ts +++ b/packages/main/src/forwards/behaviors/illuminance-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/index.ts b/packages/main/src/forwards/behaviors/index.ts index 366b1eaba9..fa57e46ba4 100644 --- a/packages/main/src/forwards/behaviors/index.ts +++ b/packages/main/src/forwards/behaviors/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/joint-fabric-datastore-cluster.ts b/packages/main/src/forwards/behaviors/joint-fabric-datastore-cluster.ts new file mode 100644 index 0000000000..0e2bef24d2 --- /dev/null +++ b/packages/main/src/forwards/behaviors/joint-fabric-datastore-cluster.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/joint-fabric-datastore-cluster"; diff --git a/packages/main/src/forwards/behaviors/joint-fabric-pki.ts b/packages/main/src/forwards/behaviors/joint-fabric-pki.ts new file mode 100644 index 0000000000..dea2bb9a2f --- /dev/null +++ b/packages/main/src/forwards/behaviors/joint-fabric-pki.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/joint-fabric-pki"; diff --git a/packages/main/src/forwards/behaviors/keypad-input.ts b/packages/main/src/forwards/behaviors/keypad-input.ts index 361db54e46..6c11476609 100644 --- a/packages/main/src/forwards/behaviors/keypad-input.ts +++ b/packages/main/src/forwards/behaviors/keypad-input.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/label.ts b/packages/main/src/forwards/behaviors/label.ts index 3464b050a6..63de275948 100644 --- a/packages/main/src/forwards/behaviors/label.ts +++ b/packages/main/src/forwards/behaviors/label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/laundry-dryer-controls.ts b/packages/main/src/forwards/behaviors/laundry-dryer-controls.ts index d1803f6c49..88dd80f0b5 100644 --- a/packages/main/src/forwards/behaviors/laundry-dryer-controls.ts +++ b/packages/main/src/forwards/behaviors/laundry-dryer-controls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/laundry-washer-controls.ts b/packages/main/src/forwards/behaviors/laundry-washer-controls.ts index 131035eedc..3751e74ed6 100644 --- a/packages/main/src/forwards/behaviors/laundry-washer-controls.ts +++ b/packages/main/src/forwards/behaviors/laundry-washer-controls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/laundry-washer-mode.ts b/packages/main/src/forwards/behaviors/laundry-washer-mode.ts index 1544e5bef3..a301be0ea1 100644 --- a/packages/main/src/forwards/behaviors/laundry-washer-mode.ts +++ b/packages/main/src/forwards/behaviors/laundry-washer-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/level-control.ts b/packages/main/src/forwards/behaviors/level-control.ts index a60c389685..7aa36085e1 100644 --- a/packages/main/src/forwards/behaviors/level-control.ts +++ b/packages/main/src/forwards/behaviors/level-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/localization-configuration.ts b/packages/main/src/forwards/behaviors/localization-configuration.ts index 0e98d2c03f..981ab92f5f 100644 --- a/packages/main/src/forwards/behaviors/localization-configuration.ts +++ b/packages/main/src/forwards/behaviors/localization-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/low-power.ts b/packages/main/src/forwards/behaviors/low-power.ts index deef353344..c2ccc347f2 100644 --- a/packages/main/src/forwards/behaviors/low-power.ts +++ b/packages/main/src/forwards/behaviors/low-power.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/media-input.ts b/packages/main/src/forwards/behaviors/media-input.ts index 799eee5ea9..795e4614cb 100644 --- a/packages/main/src/forwards/behaviors/media-input.ts +++ b/packages/main/src/forwards/behaviors/media-input.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/media-playback.ts b/packages/main/src/forwards/behaviors/media-playback.ts index 1832cf78c2..0d28b1c708 100644 --- a/packages/main/src/forwards/behaviors/media-playback.ts +++ b/packages/main/src/forwards/behaviors/media-playback.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/messages.ts b/packages/main/src/forwards/behaviors/messages.ts index f1d02cbfcf..763b297e57 100644 --- a/packages/main/src/forwards/behaviors/messages.ts +++ b/packages/main/src/forwards/behaviors/messages.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/microwave-oven-control.ts b/packages/main/src/forwards/behaviors/microwave-oven-control.ts index 8123ac36d9..f282b05d0b 100644 --- a/packages/main/src/forwards/behaviors/microwave-oven-control.ts +++ b/packages/main/src/forwards/behaviors/microwave-oven-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/microwave-oven-mode.ts b/packages/main/src/forwards/behaviors/microwave-oven-mode.ts index 4519c9918b..214939639d 100644 --- a/packages/main/src/forwards/behaviors/microwave-oven-mode.ts +++ b/packages/main/src/forwards/behaviors/microwave-oven-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/mode-base.ts b/packages/main/src/forwards/behaviors/mode-base.ts index 977016a53e..fc9a47157b 100644 --- a/packages/main/src/forwards/behaviors/mode-base.ts +++ b/packages/main/src/forwards/behaviors/mode-base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/mode-select.ts b/packages/main/src/forwards/behaviors/mode-select.ts index de468e328f..9bf62bc291 100644 --- a/packages/main/src/forwards/behaviors/mode-select.ts +++ b/packages/main/src/forwards/behaviors/mode-select.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/network-commissioning.ts b/packages/main/src/forwards/behaviors/network-commissioning.ts index 9490a49686..36fabf69e2 100644 --- a/packages/main/src/forwards/behaviors/network-commissioning.ts +++ b/packages/main/src/forwards/behaviors/network-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/nitrogen-dioxide-concentration-measurement.ts b/packages/main/src/forwards/behaviors/nitrogen-dioxide-concentration-measurement.ts index 48ff9cfc1e..fc095dab2f 100644 --- a/packages/main/src/forwards/behaviors/nitrogen-dioxide-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/nitrogen-dioxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/occupancy-sensing.ts b/packages/main/src/forwards/behaviors/occupancy-sensing.ts index 13b58cdbb1..9ae9bee90a 100644 --- a/packages/main/src/forwards/behaviors/occupancy-sensing.ts +++ b/packages/main/src/forwards/behaviors/occupancy-sensing.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/on-off.ts b/packages/main/src/forwards/behaviors/on-off.ts index c346a4bf0a..67ab68b655 100644 --- a/packages/main/src/forwards/behaviors/on-off.ts +++ b/packages/main/src/forwards/behaviors/on-off.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/operational-credentials.ts b/packages/main/src/forwards/behaviors/operational-credentials.ts index 6f33564d66..e25526a4e5 100644 --- a/packages/main/src/forwards/behaviors/operational-credentials.ts +++ b/packages/main/src/forwards/behaviors/operational-credentials.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/operational-state.ts b/packages/main/src/forwards/behaviors/operational-state.ts index 2a3275df17..3968c09bba 100644 --- a/packages/main/src/forwards/behaviors/operational-state.ts +++ b/packages/main/src/forwards/behaviors/operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/ota-software-update-provider.ts b/packages/main/src/forwards/behaviors/ota-software-update-provider.ts index ec47452b2b..de4b0b9565 100644 --- a/packages/main/src/forwards/behaviors/ota-software-update-provider.ts +++ b/packages/main/src/forwards/behaviors/ota-software-update-provider.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/ota-software-update-requestor.ts b/packages/main/src/forwards/behaviors/ota-software-update-requestor.ts index c11157804f..ec8a69efa6 100644 --- a/packages/main/src/forwards/behaviors/ota-software-update-requestor.ts +++ b/packages/main/src/forwards/behaviors/ota-software-update-requestor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/oven-cavity-operational-state.ts b/packages/main/src/forwards/behaviors/oven-cavity-operational-state.ts index e79db3627e..523c76d588 100644 --- a/packages/main/src/forwards/behaviors/oven-cavity-operational-state.ts +++ b/packages/main/src/forwards/behaviors/oven-cavity-operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/oven-mode.ts b/packages/main/src/forwards/behaviors/oven-mode.ts index 669f728aeb..58446a854f 100644 --- a/packages/main/src/forwards/behaviors/oven-mode.ts +++ b/packages/main/src/forwards/behaviors/oven-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/ozone-concentration-measurement.ts b/packages/main/src/forwards/behaviors/ozone-concentration-measurement.ts index 4bf4a7947d..265a44085b 100644 --- a/packages/main/src/forwards/behaviors/ozone-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/ozone-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/pm1-concentration-measurement.ts b/packages/main/src/forwards/behaviors/pm1-concentration-measurement.ts index 360aa8dcd1..e35af7d642 100644 --- a/packages/main/src/forwards/behaviors/pm1-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/pm1-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/pm10-concentration-measurement.ts b/packages/main/src/forwards/behaviors/pm10-concentration-measurement.ts index 4f42b12af8..e6e5ecafa0 100644 --- a/packages/main/src/forwards/behaviors/pm10-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/pm10-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/pm25-concentration-measurement.ts b/packages/main/src/forwards/behaviors/pm25-concentration-measurement.ts index 25f1147e25..15e46cb170 100644 --- a/packages/main/src/forwards/behaviors/pm25-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/pm25-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/power-source-configuration.ts b/packages/main/src/forwards/behaviors/power-source-configuration.ts index 20a48520d2..eae2d4d748 100644 --- a/packages/main/src/forwards/behaviors/power-source-configuration.ts +++ b/packages/main/src/forwards/behaviors/power-source-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/power-source.ts b/packages/main/src/forwards/behaviors/power-source.ts index aecc5e7e1b..153af93010 100644 --- a/packages/main/src/forwards/behaviors/power-source.ts +++ b/packages/main/src/forwards/behaviors/power-source.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/power-topology.ts b/packages/main/src/forwards/behaviors/power-topology.ts index f93c04d3d3..272ed807f4 100644 --- a/packages/main/src/forwards/behaviors/power-topology.ts +++ b/packages/main/src/forwards/behaviors/power-topology.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/pressure-measurement.ts b/packages/main/src/forwards/behaviors/pressure-measurement.ts index 09219dcbae..7398c7a3ec 100644 --- a/packages/main/src/forwards/behaviors/pressure-measurement.ts +++ b/packages/main/src/forwards/behaviors/pressure-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/proxy-configuration.ts b/packages/main/src/forwards/behaviors/proxy-configuration.ts index 70e3492573..5756b2d2c4 100644 --- a/packages/main/src/forwards/behaviors/proxy-configuration.ts +++ b/packages/main/src/forwards/behaviors/proxy-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/proxy-discovery.ts b/packages/main/src/forwards/behaviors/proxy-discovery.ts index 2268c7c65a..3b06e70185 100644 --- a/packages/main/src/forwards/behaviors/proxy-discovery.ts +++ b/packages/main/src/forwards/behaviors/proxy-discovery.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/pump-configuration-and-control.ts b/packages/main/src/forwards/behaviors/pump-configuration-and-control.ts index 518c4a18ee..29042a65d0 100644 --- a/packages/main/src/forwards/behaviors/pump-configuration-and-control.ts +++ b/packages/main/src/forwards/behaviors/pump-configuration-and-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/radon-concentration-measurement.ts b/packages/main/src/forwards/behaviors/radon-concentration-measurement.ts index 6a4bd2f4e1..3550840654 100644 --- a/packages/main/src/forwards/behaviors/radon-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/radon-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/refrigerator-alarm.ts b/packages/main/src/forwards/behaviors/refrigerator-alarm.ts index 35fe6653ce..0fa8bea977 100644 --- a/packages/main/src/forwards/behaviors/refrigerator-alarm.ts +++ b/packages/main/src/forwards/behaviors/refrigerator-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/refrigerator-and-temperature-controlled-cabinet-mode.ts b/packages/main/src/forwards/behaviors/refrigerator-and-temperature-controlled-cabinet-mode.ts index e214965e34..862586b7ec 100644 --- a/packages/main/src/forwards/behaviors/refrigerator-and-temperature-controlled-cabinet-mode.ts +++ b/packages/main/src/forwards/behaviors/refrigerator-and-temperature-controlled-cabinet-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/relative-humidity-measurement.ts b/packages/main/src/forwards/behaviors/relative-humidity-measurement.ts index fe58ac86ae..ba60e809a5 100644 --- a/packages/main/src/forwards/behaviors/relative-humidity-measurement.ts +++ b/packages/main/src/forwards/behaviors/relative-humidity-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/resource-monitoring.ts b/packages/main/src/forwards/behaviors/resource-monitoring.ts index 02314bddb7..314040cbb3 100644 --- a/packages/main/src/forwards/behaviors/resource-monitoring.ts +++ b/packages/main/src/forwards/behaviors/resource-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/rvc-clean-mode.ts b/packages/main/src/forwards/behaviors/rvc-clean-mode.ts index 3a15f896ce..b06eb2c088 100644 --- a/packages/main/src/forwards/behaviors/rvc-clean-mode.ts +++ b/packages/main/src/forwards/behaviors/rvc-clean-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/rvc-operational-state.ts b/packages/main/src/forwards/behaviors/rvc-operational-state.ts index 7b5f8d9ba1..94b0b10218 100644 --- a/packages/main/src/forwards/behaviors/rvc-operational-state.ts +++ b/packages/main/src/forwards/behaviors/rvc-operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/rvc-run-mode.ts b/packages/main/src/forwards/behaviors/rvc-run-mode.ts index 1247caaeec..50d6e2281f 100644 --- a/packages/main/src/forwards/behaviors/rvc-run-mode.ts +++ b/packages/main/src/forwards/behaviors/rvc-run-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/scenes-management.ts b/packages/main/src/forwards/behaviors/scenes-management.ts index ddf81b20b7..2ea0c4a71a 100644 --- a/packages/main/src/forwards/behaviors/scenes-management.ts +++ b/packages/main/src/forwards/behaviors/scenes-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/service-area.ts b/packages/main/src/forwards/behaviors/service-area.ts new file mode 100644 index 0000000000..9e52a2c9f4 --- /dev/null +++ b/packages/main/src/forwards/behaviors/service-area.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/service-area"; diff --git a/packages/main/src/forwards/behaviors/smoke-co-alarm.ts b/packages/main/src/forwards/behaviors/smoke-co-alarm.ts index 8d69c6562c..ed2299f452 100644 --- a/packages/main/src/forwards/behaviors/smoke-co-alarm.ts +++ b/packages/main/src/forwards/behaviors/smoke-co-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/software-diagnostics.ts b/packages/main/src/forwards/behaviors/software-diagnostics.ts index 87a4405a88..10b1301393 100644 --- a/packages/main/src/forwards/behaviors/software-diagnostics.ts +++ b/packages/main/src/forwards/behaviors/software-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/switch.ts b/packages/main/src/forwards/behaviors/switch.ts index 8fa39d9a32..ab205ed759 100644 --- a/packages/main/src/forwards/behaviors/switch.ts +++ b/packages/main/src/forwards/behaviors/switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/target-navigator.ts b/packages/main/src/forwards/behaviors/target-navigator.ts index 67625055ae..6352bc0e7c 100644 --- a/packages/main/src/forwards/behaviors/target-navigator.ts +++ b/packages/main/src/forwards/behaviors/target-navigator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/temperature-control.ts b/packages/main/src/forwards/behaviors/temperature-control.ts index a004a4083f..944d303ec9 100644 --- a/packages/main/src/forwards/behaviors/temperature-control.ts +++ b/packages/main/src/forwards/behaviors/temperature-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/temperature-measurement.ts b/packages/main/src/forwards/behaviors/temperature-measurement.ts index 6394cde470..4c0fd5b18d 100644 --- a/packages/main/src/forwards/behaviors/temperature-measurement.ts +++ b/packages/main/src/forwards/behaviors/temperature-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/thermostat-user-interface-configuration.ts b/packages/main/src/forwards/behaviors/thermostat-user-interface-configuration.ts index ce46789576..4d37f962bf 100644 --- a/packages/main/src/forwards/behaviors/thermostat-user-interface-configuration.ts +++ b/packages/main/src/forwards/behaviors/thermostat-user-interface-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/thermostat.ts b/packages/main/src/forwards/behaviors/thermostat.ts index 06a045c454..be52b9be28 100644 --- a/packages/main/src/forwards/behaviors/thermostat.ts +++ b/packages/main/src/forwards/behaviors/thermostat.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/thread-border-router-management.ts b/packages/main/src/forwards/behaviors/thread-border-router-management.ts new file mode 100644 index 0000000000..bc441ba731 --- /dev/null +++ b/packages/main/src/forwards/behaviors/thread-border-router-management.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/thread-border-router-management"; diff --git a/packages/main/src/forwards/behaviors/thread-network-diagnostics.ts b/packages/main/src/forwards/behaviors/thread-network-diagnostics.ts index 385753539e..533db34a68 100644 --- a/packages/main/src/forwards/behaviors/thread-network-diagnostics.ts +++ b/packages/main/src/forwards/behaviors/thread-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/thread-network-directory.ts b/packages/main/src/forwards/behaviors/thread-network-directory.ts new file mode 100644 index 0000000000..d5c010e0bc --- /dev/null +++ b/packages/main/src/forwards/behaviors/thread-network-directory.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/thread-network-directory"; diff --git a/packages/main/src/forwards/behaviors/time-format-localization.ts b/packages/main/src/forwards/behaviors/time-format-localization.ts index 3056d647c6..b556220c67 100644 --- a/packages/main/src/forwards/behaviors/time-format-localization.ts +++ b/packages/main/src/forwards/behaviors/time-format-localization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/time-synchronization.ts b/packages/main/src/forwards/behaviors/time-synchronization.ts index 86047f4220..2071833f8e 100644 --- a/packages/main/src/forwards/behaviors/time-synchronization.ts +++ b/packages/main/src/forwards/behaviors/time-synchronization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/total-volatile-organic-compounds-concentration-measurement.ts b/packages/main/src/forwards/behaviors/total-volatile-organic-compounds-concentration-measurement.ts index 14268f5705..cc5761afe9 100644 --- a/packages/main/src/forwards/behaviors/total-volatile-organic-compounds-concentration-measurement.ts +++ b/packages/main/src/forwards/behaviors/total-volatile-organic-compounds-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/unit-localization.ts b/packages/main/src/forwards/behaviors/unit-localization.ts index 788c13aa98..ce97467d91 100644 --- a/packages/main/src/forwards/behaviors/unit-localization.ts +++ b/packages/main/src/forwards/behaviors/unit-localization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/user-label.ts b/packages/main/src/forwards/behaviors/user-label.ts index 2a339b5d3f..0d83d8c704 100644 --- a/packages/main/src/forwards/behaviors/user-label.ts +++ b/packages/main/src/forwards/behaviors/user-label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/valid-proxies.ts b/packages/main/src/forwards/behaviors/valid-proxies.ts index 589db706ed..99f96427a0 100644 --- a/packages/main/src/forwards/behaviors/valid-proxies.ts +++ b/packages/main/src/forwards/behaviors/valid-proxies.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/valve-configuration-and-control.ts b/packages/main/src/forwards/behaviors/valve-configuration-and-control.ts index 0707573ba2..dabb2a712d 100644 --- a/packages/main/src/forwards/behaviors/valve-configuration-and-control.ts +++ b/packages/main/src/forwards/behaviors/valve-configuration-and-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/wake-on-lan.ts b/packages/main/src/forwards/behaviors/wake-on-lan.ts index e9c49b1dc0..a34bf491d0 100644 --- a/packages/main/src/forwards/behaviors/wake-on-lan.ts +++ b/packages/main/src/forwards/behaviors/wake-on-lan.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/water-heater-management.ts b/packages/main/src/forwards/behaviors/water-heater-management.ts new file mode 100644 index 0000000000..e64155b946 --- /dev/null +++ b/packages/main/src/forwards/behaviors/water-heater-management.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/water-heater-management"; diff --git a/packages/main/src/forwards/behaviors/water-heater-mode.ts b/packages/main/src/forwards/behaviors/water-heater-mode.ts new file mode 100644 index 0000000000..d97c06671d --- /dev/null +++ b/packages/main/src/forwards/behaviors/water-heater-mode.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/water-heater-mode"; diff --git a/packages/main/src/forwards/behaviors/water-tank-level-monitoring.ts b/packages/main/src/forwards/behaviors/water-tank-level-monitoring.ts new file mode 100644 index 0000000000..b34cc52819 --- /dev/null +++ b/packages/main/src/forwards/behaviors/water-tank-level-monitoring.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/water-tank-level-monitoring"; diff --git a/packages/main/src/forwards/behaviors/wi-fi-network-diagnostics.ts b/packages/main/src/forwards/behaviors/wi-fi-network-diagnostics.ts index 2988d76a8b..0e0fd3a3bd 100644 --- a/packages/main/src/forwards/behaviors/wi-fi-network-diagnostics.ts +++ b/packages/main/src/forwards/behaviors/wi-fi-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/behaviors/wi-fi-network-management.ts b/packages/main/src/forwards/behaviors/wi-fi-network-management.ts new file mode 100644 index 0000000000..69ffc375da --- /dev/null +++ b/packages/main/src/forwards/behaviors/wi-fi-network-management.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#behaviors/wi-fi-network-management"; diff --git a/packages/main/src/forwards/behaviors/window-covering.ts b/packages/main/src/forwards/behaviors/window-covering.ts index da3f90ae0a..68e3832eac 100644 --- a/packages/main/src/forwards/behaviors/window-covering.ts +++ b/packages/main/src/forwards/behaviors/window-covering.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/access-control.ts b/packages/main/src/forwards/clusters/access-control.ts index f027619efa..0b1ffd03ca 100644 --- a/packages/main/src/forwards/clusters/access-control.ts +++ b/packages/main/src/forwards/clusters/access-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/account-login.ts b/packages/main/src/forwards/clusters/account-login.ts index ddd874e842..e01ef9e3d8 100644 --- a/packages/main/src/forwards/clusters/account-login.ts +++ b/packages/main/src/forwards/clusters/account-login.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/actions.ts b/packages/main/src/forwards/clusters/actions.ts index ca41a9c675..0842d435ee 100644 --- a/packages/main/src/forwards/clusters/actions.ts +++ b/packages/main/src/forwards/clusters/actions.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/activated-carbon-filter-monitoring.ts b/packages/main/src/forwards/clusters/activated-carbon-filter-monitoring.ts index fa624bcbf7..64f7e68bf6 100644 --- a/packages/main/src/forwards/clusters/activated-carbon-filter-monitoring.ts +++ b/packages/main/src/forwards/clusters/activated-carbon-filter-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/administrator-commissioning.ts b/packages/main/src/forwards/clusters/administrator-commissioning.ts index 8c273d5d8f..41dfd6d29f 100644 --- a/packages/main/src/forwards/clusters/administrator-commissioning.ts +++ b/packages/main/src/forwards/clusters/administrator-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/air-quality.ts b/packages/main/src/forwards/clusters/air-quality.ts index c94f92ffd9..f9c91a777c 100644 --- a/packages/main/src/forwards/clusters/air-quality.ts +++ b/packages/main/src/forwards/clusters/air-quality.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/alarm-base.ts b/packages/main/src/forwards/clusters/alarm-base.ts index 56be597e4d..75c4e37446 100644 --- a/packages/main/src/forwards/clusters/alarm-base.ts +++ b/packages/main/src/forwards/clusters/alarm-base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/application-basic.ts b/packages/main/src/forwards/clusters/application-basic.ts index 438f0961ff..d44182cdf7 100644 --- a/packages/main/src/forwards/clusters/application-basic.ts +++ b/packages/main/src/forwards/clusters/application-basic.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/application-launcher.ts b/packages/main/src/forwards/clusters/application-launcher.ts index 276d232b70..af8415f66a 100644 --- a/packages/main/src/forwards/clusters/application-launcher.ts +++ b/packages/main/src/forwards/clusters/application-launcher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/audio-output.ts b/packages/main/src/forwards/clusters/audio-output.ts index 3eeb5ac1d6..e29ce05c10 100644 --- a/packages/main/src/forwards/clusters/audio-output.ts +++ b/packages/main/src/forwards/clusters/audio-output.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/ballast-configuration.ts b/packages/main/src/forwards/clusters/ballast-configuration.ts index 1c300e5d51..475dda36c6 100644 --- a/packages/main/src/forwards/clusters/ballast-configuration.ts +++ b/packages/main/src/forwards/clusters/ballast-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/basic-information.ts b/packages/main/src/forwards/clusters/basic-information.ts index 40b4d5bf4c..5d4a3ebbe1 100644 --- a/packages/main/src/forwards/clusters/basic-information.ts +++ b/packages/main/src/forwards/clusters/basic-information.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/binding.ts b/packages/main/src/forwards/clusters/binding.ts index 5239d4def3..9a926e1c72 100644 --- a/packages/main/src/forwards/clusters/binding.ts +++ b/packages/main/src/forwards/clusters/binding.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/boolean-state-configuration.ts b/packages/main/src/forwards/clusters/boolean-state-configuration.ts index f471382e82..a524df818c 100644 --- a/packages/main/src/forwards/clusters/boolean-state-configuration.ts +++ b/packages/main/src/forwards/clusters/boolean-state-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/boolean-state.ts b/packages/main/src/forwards/clusters/boolean-state.ts index 3b62a53bfb..dac4d5c5a4 100644 --- a/packages/main/src/forwards/clusters/boolean-state.ts +++ b/packages/main/src/forwards/clusters/boolean-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/bridged-device-basic-information.ts b/packages/main/src/forwards/clusters/bridged-device-basic-information.ts index 0126f1cd25..af9d49fda4 100644 --- a/packages/main/src/forwards/clusters/bridged-device-basic-information.ts +++ b/packages/main/src/forwards/clusters/bridged-device-basic-information.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/carbon-dioxide-concentration-measurement.ts b/packages/main/src/forwards/clusters/carbon-dioxide-concentration-measurement.ts index ec8a6c207e..5703629bea 100644 --- a/packages/main/src/forwards/clusters/carbon-dioxide-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/carbon-dioxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/carbon-monoxide-concentration-measurement.ts b/packages/main/src/forwards/clusters/carbon-monoxide-concentration-measurement.ts index 8c8ac6bfc5..9c8d14602d 100644 --- a/packages/main/src/forwards/clusters/carbon-monoxide-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/carbon-monoxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/channel.ts b/packages/main/src/forwards/clusters/channel.ts index 4ab77c5b2e..b358f1b17d 100644 --- a/packages/main/src/forwards/clusters/channel.ts +++ b/packages/main/src/forwards/clusters/channel.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/color-control.ts b/packages/main/src/forwards/clusters/color-control.ts index b7418c2a17..a3c8264be2 100644 --- a/packages/main/src/forwards/clusters/color-control.ts +++ b/packages/main/src/forwards/clusters/color-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/commissioner-control.ts b/packages/main/src/forwards/clusters/commissioner-control.ts new file mode 100644 index 0000000000..5044429d57 --- /dev/null +++ b/packages/main/src/forwards/clusters/commissioner-control.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/commissioner-control"; diff --git a/packages/main/src/forwards/clusters/concentration-measurement.ts b/packages/main/src/forwards/clusters/concentration-measurement.ts index 0da65fdf98..8574faf24c 100644 --- a/packages/main/src/forwards/clusters/concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/content-app-observer.ts b/packages/main/src/forwards/clusters/content-app-observer.ts index be6321ed0e..109c41ce08 100644 --- a/packages/main/src/forwards/clusters/content-app-observer.ts +++ b/packages/main/src/forwards/clusters/content-app-observer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/content-control.ts b/packages/main/src/forwards/clusters/content-control.ts index 8bdb71ee05..3cfd1b8ecd 100644 --- a/packages/main/src/forwards/clusters/content-control.ts +++ b/packages/main/src/forwards/clusters/content-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/content-launcher.ts b/packages/main/src/forwards/clusters/content-launcher.ts index 436709023d..558f04e176 100644 --- a/packages/main/src/forwards/clusters/content-launcher.ts +++ b/packages/main/src/forwards/clusters/content-launcher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/descriptor.ts b/packages/main/src/forwards/clusters/descriptor.ts index 60359c59c7..bb97ba9836 100644 --- a/packages/main/src/forwards/clusters/descriptor.ts +++ b/packages/main/src/forwards/clusters/descriptor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/device-energy-management-mode.ts b/packages/main/src/forwards/clusters/device-energy-management-mode.ts index 33dd278f49..f65655c1c5 100644 --- a/packages/main/src/forwards/clusters/device-energy-management-mode.ts +++ b/packages/main/src/forwards/clusters/device-energy-management-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/device-energy-management.ts b/packages/main/src/forwards/clusters/device-energy-management.ts index 80e7052b86..0d8074508b 100644 --- a/packages/main/src/forwards/clusters/device-energy-management.ts +++ b/packages/main/src/forwards/clusters/device-energy-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/diagnostic-logs.ts b/packages/main/src/forwards/clusters/diagnostic-logs.ts index 493d6e1e78..9ec38a220c 100644 --- a/packages/main/src/forwards/clusters/diagnostic-logs.ts +++ b/packages/main/src/forwards/clusters/diagnostic-logs.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/dishwasher-alarm.ts b/packages/main/src/forwards/clusters/dishwasher-alarm.ts index a81acd9f0e..29c01be5b9 100644 --- a/packages/main/src/forwards/clusters/dishwasher-alarm.ts +++ b/packages/main/src/forwards/clusters/dishwasher-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/dishwasher-mode.ts b/packages/main/src/forwards/clusters/dishwasher-mode.ts index 5807575d57..8ead803c3d 100644 --- a/packages/main/src/forwards/clusters/dishwasher-mode.ts +++ b/packages/main/src/forwards/clusters/dishwasher-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/door-lock.ts b/packages/main/src/forwards/clusters/door-lock.ts index 0b794f69a6..f4bec32e1b 100644 --- a/packages/main/src/forwards/clusters/door-lock.ts +++ b/packages/main/src/forwards/clusters/door-lock.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/ecosystem-information.ts b/packages/main/src/forwards/clusters/ecosystem-information.ts new file mode 100644 index 0000000000..8fb15abb63 --- /dev/null +++ b/packages/main/src/forwards/clusters/ecosystem-information.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/ecosystem-information"; diff --git a/packages/main/src/forwards/clusters/electrical-energy-measurement.ts b/packages/main/src/forwards/clusters/electrical-energy-measurement.ts index c1d67acc04..939a4630b1 100644 --- a/packages/main/src/forwards/clusters/electrical-energy-measurement.ts +++ b/packages/main/src/forwards/clusters/electrical-energy-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/electrical-power-measurement.ts b/packages/main/src/forwards/clusters/electrical-power-measurement.ts index 2581231adf..26693c2c06 100644 --- a/packages/main/src/forwards/clusters/electrical-power-measurement.ts +++ b/packages/main/src/forwards/clusters/electrical-power-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/energy-evse-mode.ts b/packages/main/src/forwards/clusters/energy-evse-mode.ts index f2a4b92443..5d9c00f7e7 100644 --- a/packages/main/src/forwards/clusters/energy-evse-mode.ts +++ b/packages/main/src/forwards/clusters/energy-evse-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/energy-evse.ts b/packages/main/src/forwards/clusters/energy-evse.ts index a20265168b..c13d0f1891 100644 --- a/packages/main/src/forwards/clusters/energy-evse.ts +++ b/packages/main/src/forwards/clusters/energy-evse.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/energy-preference.ts b/packages/main/src/forwards/clusters/energy-preference.ts index 849ed144af..f6630be721 100644 --- a/packages/main/src/forwards/clusters/energy-preference.ts +++ b/packages/main/src/forwards/clusters/energy-preference.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/ethernet-network-diagnostics.ts b/packages/main/src/forwards/clusters/ethernet-network-diagnostics.ts index a39aca30f6..283e021755 100644 --- a/packages/main/src/forwards/clusters/ethernet-network-diagnostics.ts +++ b/packages/main/src/forwards/clusters/ethernet-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/fan-control.ts b/packages/main/src/forwards/clusters/fan-control.ts index c47e1ffbe7..f622aed726 100644 --- a/packages/main/src/forwards/clusters/fan-control.ts +++ b/packages/main/src/forwards/clusters/fan-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/fixed-label.ts b/packages/main/src/forwards/clusters/fixed-label.ts index 3759002f6e..33920b4a39 100644 --- a/packages/main/src/forwards/clusters/fixed-label.ts +++ b/packages/main/src/forwards/clusters/fixed-label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/flow-measurement.ts b/packages/main/src/forwards/clusters/flow-measurement.ts index f8c51ad89d..66dec39d1d 100644 --- a/packages/main/src/forwards/clusters/flow-measurement.ts +++ b/packages/main/src/forwards/clusters/flow-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/formaldehyde-concentration-measurement.ts b/packages/main/src/forwards/clusters/formaldehyde-concentration-measurement.ts index 613735520a..4a042a147d 100644 --- a/packages/main/src/forwards/clusters/formaldehyde-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/formaldehyde-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/general-commissioning.ts b/packages/main/src/forwards/clusters/general-commissioning.ts index 6997a439d5..5fe6a4f9bf 100644 --- a/packages/main/src/forwards/clusters/general-commissioning.ts +++ b/packages/main/src/forwards/clusters/general-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/general-diagnostics.ts b/packages/main/src/forwards/clusters/general-diagnostics.ts index 4dbcc178c9..fba3432121 100644 --- a/packages/main/src/forwards/clusters/general-diagnostics.ts +++ b/packages/main/src/forwards/clusters/general-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/group-key-management.ts b/packages/main/src/forwards/clusters/group-key-management.ts index 4f174eb250..165c66d376 100644 --- a/packages/main/src/forwards/clusters/group-key-management.ts +++ b/packages/main/src/forwards/clusters/group-key-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/groups.ts b/packages/main/src/forwards/clusters/groups.ts index 4439fc0f53..b56a544d3a 100644 --- a/packages/main/src/forwards/clusters/groups.ts +++ b/packages/main/src/forwards/clusters/groups.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/hepa-filter-monitoring.ts b/packages/main/src/forwards/clusters/hepa-filter-monitoring.ts index 77b223471c..501eb30e66 100644 --- a/packages/main/src/forwards/clusters/hepa-filter-monitoring.ts +++ b/packages/main/src/forwards/clusters/hepa-filter-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/icd-management.ts b/packages/main/src/forwards/clusters/icd-management.ts index 9709b9539c..6b22de263b 100644 --- a/packages/main/src/forwards/clusters/icd-management.ts +++ b/packages/main/src/forwards/clusters/icd-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/identify.ts b/packages/main/src/forwards/clusters/identify.ts index fb9627e927..2ce5039daa 100644 --- a/packages/main/src/forwards/clusters/identify.ts +++ b/packages/main/src/forwards/clusters/identify.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/illuminance-measurement.ts b/packages/main/src/forwards/clusters/illuminance-measurement.ts index 85ad948ba1..4b745fbf35 100644 --- a/packages/main/src/forwards/clusters/illuminance-measurement.ts +++ b/packages/main/src/forwards/clusters/illuminance-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/index.ts b/packages/main/src/forwards/clusters/index.ts index 366b1eaba9..fa57e46ba4 100644 --- a/packages/main/src/forwards/clusters/index.ts +++ b/packages/main/src/forwards/clusters/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/joint-fabric-datastore-cluster.ts b/packages/main/src/forwards/clusters/joint-fabric-datastore-cluster.ts new file mode 100644 index 0000000000..e06d5ef59e --- /dev/null +++ b/packages/main/src/forwards/clusters/joint-fabric-datastore-cluster.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/joint-fabric-datastore-cluster"; diff --git a/packages/main/src/forwards/clusters/joint-fabric-pki.ts b/packages/main/src/forwards/clusters/joint-fabric-pki.ts new file mode 100644 index 0000000000..8b0c33e890 --- /dev/null +++ b/packages/main/src/forwards/clusters/joint-fabric-pki.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/joint-fabric-pki"; diff --git a/packages/main/src/forwards/clusters/keypad-input.ts b/packages/main/src/forwards/clusters/keypad-input.ts index a0fec0fe79..b8480378b8 100644 --- a/packages/main/src/forwards/clusters/keypad-input.ts +++ b/packages/main/src/forwards/clusters/keypad-input.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/label.ts b/packages/main/src/forwards/clusters/label.ts index dc41adda2f..a805164e0b 100644 --- a/packages/main/src/forwards/clusters/label.ts +++ b/packages/main/src/forwards/clusters/label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/laundry-dryer-controls.ts b/packages/main/src/forwards/clusters/laundry-dryer-controls.ts index 436afd09c7..ba53bc22b3 100644 --- a/packages/main/src/forwards/clusters/laundry-dryer-controls.ts +++ b/packages/main/src/forwards/clusters/laundry-dryer-controls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/laundry-washer-controls.ts b/packages/main/src/forwards/clusters/laundry-washer-controls.ts index f6db46076e..07e6090b9a 100644 --- a/packages/main/src/forwards/clusters/laundry-washer-controls.ts +++ b/packages/main/src/forwards/clusters/laundry-washer-controls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/laundry-washer-mode.ts b/packages/main/src/forwards/clusters/laundry-washer-mode.ts index 98ca49246d..662efe6b5a 100644 --- a/packages/main/src/forwards/clusters/laundry-washer-mode.ts +++ b/packages/main/src/forwards/clusters/laundry-washer-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/level-control.ts b/packages/main/src/forwards/clusters/level-control.ts index b4f5700132..d6caf2d20c 100644 --- a/packages/main/src/forwards/clusters/level-control.ts +++ b/packages/main/src/forwards/clusters/level-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/localization-configuration.ts b/packages/main/src/forwards/clusters/localization-configuration.ts index 7555e9b7c8..5f0f826da1 100644 --- a/packages/main/src/forwards/clusters/localization-configuration.ts +++ b/packages/main/src/forwards/clusters/localization-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/low-power.ts b/packages/main/src/forwards/clusters/low-power.ts index 940771a412..b716882af0 100644 --- a/packages/main/src/forwards/clusters/low-power.ts +++ b/packages/main/src/forwards/clusters/low-power.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/media-input.ts b/packages/main/src/forwards/clusters/media-input.ts index 2996e4671a..0c99caa5f4 100644 --- a/packages/main/src/forwards/clusters/media-input.ts +++ b/packages/main/src/forwards/clusters/media-input.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/media-playback.ts b/packages/main/src/forwards/clusters/media-playback.ts index b724432b8d..3445ea50be 100644 --- a/packages/main/src/forwards/clusters/media-playback.ts +++ b/packages/main/src/forwards/clusters/media-playback.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/messages.ts b/packages/main/src/forwards/clusters/messages.ts index 9517070e66..4595c025ff 100644 --- a/packages/main/src/forwards/clusters/messages.ts +++ b/packages/main/src/forwards/clusters/messages.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/microwave-oven-control.ts b/packages/main/src/forwards/clusters/microwave-oven-control.ts index f3b8b5a3b5..f07edaf969 100644 --- a/packages/main/src/forwards/clusters/microwave-oven-control.ts +++ b/packages/main/src/forwards/clusters/microwave-oven-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/microwave-oven-mode.ts b/packages/main/src/forwards/clusters/microwave-oven-mode.ts index bff913391f..ba141225bd 100644 --- a/packages/main/src/forwards/clusters/microwave-oven-mode.ts +++ b/packages/main/src/forwards/clusters/microwave-oven-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/mode-base.ts b/packages/main/src/forwards/clusters/mode-base.ts index 639c548bb6..533d65e50a 100644 --- a/packages/main/src/forwards/clusters/mode-base.ts +++ b/packages/main/src/forwards/clusters/mode-base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/mode-select.ts b/packages/main/src/forwards/clusters/mode-select.ts index 4d085002d5..86582a5bed 100644 --- a/packages/main/src/forwards/clusters/mode-select.ts +++ b/packages/main/src/forwards/clusters/mode-select.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/network-commissioning.ts b/packages/main/src/forwards/clusters/network-commissioning.ts index e32dc49a15..101617e33a 100644 --- a/packages/main/src/forwards/clusters/network-commissioning.ts +++ b/packages/main/src/forwards/clusters/network-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/nitrogen-dioxide-concentration-measurement.ts b/packages/main/src/forwards/clusters/nitrogen-dioxide-concentration-measurement.ts index d2721685fc..4f6dac3e5f 100644 --- a/packages/main/src/forwards/clusters/nitrogen-dioxide-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/nitrogen-dioxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/occupancy-sensing.ts b/packages/main/src/forwards/clusters/occupancy-sensing.ts index 1835e08a97..4e64b2c462 100644 --- a/packages/main/src/forwards/clusters/occupancy-sensing.ts +++ b/packages/main/src/forwards/clusters/occupancy-sensing.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/on-off.ts b/packages/main/src/forwards/clusters/on-off.ts index 4d76daf990..49914c90b1 100644 --- a/packages/main/src/forwards/clusters/on-off.ts +++ b/packages/main/src/forwards/clusters/on-off.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/operational-credentials.ts b/packages/main/src/forwards/clusters/operational-credentials.ts index b7b7ec2a18..611de88fec 100644 --- a/packages/main/src/forwards/clusters/operational-credentials.ts +++ b/packages/main/src/forwards/clusters/operational-credentials.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/operational-state.ts b/packages/main/src/forwards/clusters/operational-state.ts index a5addf925a..608525c9f3 100644 --- a/packages/main/src/forwards/clusters/operational-state.ts +++ b/packages/main/src/forwards/clusters/operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/ota-software-update-provider.ts b/packages/main/src/forwards/clusters/ota-software-update-provider.ts index 94cd395d72..3a07272c6c 100644 --- a/packages/main/src/forwards/clusters/ota-software-update-provider.ts +++ b/packages/main/src/forwards/clusters/ota-software-update-provider.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/ota-software-update-requestor.ts b/packages/main/src/forwards/clusters/ota-software-update-requestor.ts index ca25af2809..eb35c2ce72 100644 --- a/packages/main/src/forwards/clusters/ota-software-update-requestor.ts +++ b/packages/main/src/forwards/clusters/ota-software-update-requestor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/oven-cavity-operational-state.ts b/packages/main/src/forwards/clusters/oven-cavity-operational-state.ts index 94a9d7b1b0..bebc8cf248 100644 --- a/packages/main/src/forwards/clusters/oven-cavity-operational-state.ts +++ b/packages/main/src/forwards/clusters/oven-cavity-operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/oven-mode.ts b/packages/main/src/forwards/clusters/oven-mode.ts index c8ae103b23..dcd8b6a9c4 100644 --- a/packages/main/src/forwards/clusters/oven-mode.ts +++ b/packages/main/src/forwards/clusters/oven-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/ozone-concentration-measurement.ts b/packages/main/src/forwards/clusters/ozone-concentration-measurement.ts index 656cc4444c..52388d4c88 100644 --- a/packages/main/src/forwards/clusters/ozone-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/ozone-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/pm1-concentration-measurement.ts b/packages/main/src/forwards/clusters/pm1-concentration-measurement.ts index 56f06f46de..fa85f41b00 100644 --- a/packages/main/src/forwards/clusters/pm1-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/pm1-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/pm10-concentration-measurement.ts b/packages/main/src/forwards/clusters/pm10-concentration-measurement.ts index c9acd92816..e12b93495f 100644 --- a/packages/main/src/forwards/clusters/pm10-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/pm10-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/pm25-concentration-measurement.ts b/packages/main/src/forwards/clusters/pm25-concentration-measurement.ts index 7be3d43a61..be6ac99fb2 100644 --- a/packages/main/src/forwards/clusters/pm25-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/pm25-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/power-source-configuration.ts b/packages/main/src/forwards/clusters/power-source-configuration.ts index fbe97e1546..b976fafdd1 100644 --- a/packages/main/src/forwards/clusters/power-source-configuration.ts +++ b/packages/main/src/forwards/clusters/power-source-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/power-source.ts b/packages/main/src/forwards/clusters/power-source.ts index 0559cf9c2b..44d7e7e950 100644 --- a/packages/main/src/forwards/clusters/power-source.ts +++ b/packages/main/src/forwards/clusters/power-source.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/power-topology.ts b/packages/main/src/forwards/clusters/power-topology.ts index 6e09d8a5cd..675d88aafd 100644 --- a/packages/main/src/forwards/clusters/power-topology.ts +++ b/packages/main/src/forwards/clusters/power-topology.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/pressure-measurement.ts b/packages/main/src/forwards/clusters/pressure-measurement.ts index 35a1253537..5ef94a0c9b 100644 --- a/packages/main/src/forwards/clusters/pressure-measurement.ts +++ b/packages/main/src/forwards/clusters/pressure-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/proxy-configuration.ts b/packages/main/src/forwards/clusters/proxy-configuration.ts index 5cc46ae4d1..ef25aa2fc8 100644 --- a/packages/main/src/forwards/clusters/proxy-configuration.ts +++ b/packages/main/src/forwards/clusters/proxy-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/proxy-discovery.ts b/packages/main/src/forwards/clusters/proxy-discovery.ts index 10d6c16f3c..4f15ddbfda 100644 --- a/packages/main/src/forwards/clusters/proxy-discovery.ts +++ b/packages/main/src/forwards/clusters/proxy-discovery.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/pump-configuration-and-control.ts b/packages/main/src/forwards/clusters/pump-configuration-and-control.ts index 0747777ee5..00f72fcd7a 100644 --- a/packages/main/src/forwards/clusters/pump-configuration-and-control.ts +++ b/packages/main/src/forwards/clusters/pump-configuration-and-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/radon-concentration-measurement.ts b/packages/main/src/forwards/clusters/radon-concentration-measurement.ts index eaf84eab55..3bcbb0cf51 100644 --- a/packages/main/src/forwards/clusters/radon-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/radon-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/refrigerator-alarm.ts b/packages/main/src/forwards/clusters/refrigerator-alarm.ts index fb0a288669..ddd68458b7 100644 --- a/packages/main/src/forwards/clusters/refrigerator-alarm.ts +++ b/packages/main/src/forwards/clusters/refrigerator-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/refrigerator-and-temperature-controlled-cabinet-mode.ts b/packages/main/src/forwards/clusters/refrigerator-and-temperature-controlled-cabinet-mode.ts index ebd317e4cd..da73d85386 100644 --- a/packages/main/src/forwards/clusters/refrigerator-and-temperature-controlled-cabinet-mode.ts +++ b/packages/main/src/forwards/clusters/refrigerator-and-temperature-controlled-cabinet-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/relative-humidity-measurement.ts b/packages/main/src/forwards/clusters/relative-humidity-measurement.ts index 86b4198b05..d1628b41a4 100644 --- a/packages/main/src/forwards/clusters/relative-humidity-measurement.ts +++ b/packages/main/src/forwards/clusters/relative-humidity-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/resource-monitoring.ts b/packages/main/src/forwards/clusters/resource-monitoring.ts index 92fbfed200..2ad12ba805 100644 --- a/packages/main/src/forwards/clusters/resource-monitoring.ts +++ b/packages/main/src/forwards/clusters/resource-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/rvc-clean-mode.ts b/packages/main/src/forwards/clusters/rvc-clean-mode.ts index f1c5a04f67..7eb5604c64 100644 --- a/packages/main/src/forwards/clusters/rvc-clean-mode.ts +++ b/packages/main/src/forwards/clusters/rvc-clean-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/rvc-operational-state.ts b/packages/main/src/forwards/clusters/rvc-operational-state.ts index 0b2214bc18..5c11e56cb1 100644 --- a/packages/main/src/forwards/clusters/rvc-operational-state.ts +++ b/packages/main/src/forwards/clusters/rvc-operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/rvc-run-mode.ts b/packages/main/src/forwards/clusters/rvc-run-mode.ts index c05eae4ec3..6eb7d1fd82 100644 --- a/packages/main/src/forwards/clusters/rvc-run-mode.ts +++ b/packages/main/src/forwards/clusters/rvc-run-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/scenes-management.ts b/packages/main/src/forwards/clusters/scenes-management.ts index 60155a76eb..d54b2951ba 100644 --- a/packages/main/src/forwards/clusters/scenes-management.ts +++ b/packages/main/src/forwards/clusters/scenes-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/service-area.ts b/packages/main/src/forwards/clusters/service-area.ts new file mode 100644 index 0000000000..9a1c76d843 --- /dev/null +++ b/packages/main/src/forwards/clusters/service-area.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/service-area"; diff --git a/packages/main/src/forwards/clusters/smoke-co-alarm.ts b/packages/main/src/forwards/clusters/smoke-co-alarm.ts index 8c57ae1a90..d6cd9df997 100644 --- a/packages/main/src/forwards/clusters/smoke-co-alarm.ts +++ b/packages/main/src/forwards/clusters/smoke-co-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/software-diagnostics.ts b/packages/main/src/forwards/clusters/software-diagnostics.ts index d8aecc5fd2..678feb041f 100644 --- a/packages/main/src/forwards/clusters/software-diagnostics.ts +++ b/packages/main/src/forwards/clusters/software-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/switch.ts b/packages/main/src/forwards/clusters/switch.ts index 86d8869398..bd21eaa1c1 100644 --- a/packages/main/src/forwards/clusters/switch.ts +++ b/packages/main/src/forwards/clusters/switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/target-navigator.ts b/packages/main/src/forwards/clusters/target-navigator.ts index f9a9bf9da3..382f43146e 100644 --- a/packages/main/src/forwards/clusters/target-navigator.ts +++ b/packages/main/src/forwards/clusters/target-navigator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/temperature-control.ts b/packages/main/src/forwards/clusters/temperature-control.ts index 0e389226cf..1de08f0e5d 100644 --- a/packages/main/src/forwards/clusters/temperature-control.ts +++ b/packages/main/src/forwards/clusters/temperature-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/temperature-measurement.ts b/packages/main/src/forwards/clusters/temperature-measurement.ts index 53bb1c0615..690ee5fb6f 100644 --- a/packages/main/src/forwards/clusters/temperature-measurement.ts +++ b/packages/main/src/forwards/clusters/temperature-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/thermostat-user-interface-configuration.ts b/packages/main/src/forwards/clusters/thermostat-user-interface-configuration.ts index 912c940a52..193448cb3a 100644 --- a/packages/main/src/forwards/clusters/thermostat-user-interface-configuration.ts +++ b/packages/main/src/forwards/clusters/thermostat-user-interface-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/thermostat.ts b/packages/main/src/forwards/clusters/thermostat.ts index 267dbe6c84..48cdecd8c7 100644 --- a/packages/main/src/forwards/clusters/thermostat.ts +++ b/packages/main/src/forwards/clusters/thermostat.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/thread-border-router-management.ts b/packages/main/src/forwards/clusters/thread-border-router-management.ts new file mode 100644 index 0000000000..f79b0ac9fa --- /dev/null +++ b/packages/main/src/forwards/clusters/thread-border-router-management.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/thread-border-router-management"; diff --git a/packages/main/src/forwards/clusters/thread-network-diagnostics.ts b/packages/main/src/forwards/clusters/thread-network-diagnostics.ts index 240647ed0d..f71f241a76 100644 --- a/packages/main/src/forwards/clusters/thread-network-diagnostics.ts +++ b/packages/main/src/forwards/clusters/thread-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/thread-network-directory.ts b/packages/main/src/forwards/clusters/thread-network-directory.ts new file mode 100644 index 0000000000..e892521111 --- /dev/null +++ b/packages/main/src/forwards/clusters/thread-network-directory.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/thread-network-directory"; diff --git a/packages/main/src/forwards/clusters/time-format-localization.ts b/packages/main/src/forwards/clusters/time-format-localization.ts index c3761b3a26..9f4f268f94 100644 --- a/packages/main/src/forwards/clusters/time-format-localization.ts +++ b/packages/main/src/forwards/clusters/time-format-localization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/time-synchronization.ts b/packages/main/src/forwards/clusters/time-synchronization.ts index c8e56b8bf4..a9a9ca6a56 100644 --- a/packages/main/src/forwards/clusters/time-synchronization.ts +++ b/packages/main/src/forwards/clusters/time-synchronization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/total-volatile-organic-compounds-concentration-measurement.ts b/packages/main/src/forwards/clusters/total-volatile-organic-compounds-concentration-measurement.ts index 23e451b40d..5166174eff 100644 --- a/packages/main/src/forwards/clusters/total-volatile-organic-compounds-concentration-measurement.ts +++ b/packages/main/src/forwards/clusters/total-volatile-organic-compounds-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/unit-localization.ts b/packages/main/src/forwards/clusters/unit-localization.ts index 2e4c44b4e7..cccc9f3ca4 100644 --- a/packages/main/src/forwards/clusters/unit-localization.ts +++ b/packages/main/src/forwards/clusters/unit-localization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/user-label.ts b/packages/main/src/forwards/clusters/user-label.ts index 8e77b0d0de..15c3a05efb 100644 --- a/packages/main/src/forwards/clusters/user-label.ts +++ b/packages/main/src/forwards/clusters/user-label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/valid-proxies.ts b/packages/main/src/forwards/clusters/valid-proxies.ts index 26de57a026..b90998f978 100644 --- a/packages/main/src/forwards/clusters/valid-proxies.ts +++ b/packages/main/src/forwards/clusters/valid-proxies.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/valve-configuration-and-control.ts b/packages/main/src/forwards/clusters/valve-configuration-and-control.ts index d88c8263f9..b3be7bff74 100644 --- a/packages/main/src/forwards/clusters/valve-configuration-and-control.ts +++ b/packages/main/src/forwards/clusters/valve-configuration-and-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/wake-on-lan.ts b/packages/main/src/forwards/clusters/wake-on-lan.ts index 335f6071ed..8773e2f59c 100644 --- a/packages/main/src/forwards/clusters/wake-on-lan.ts +++ b/packages/main/src/forwards/clusters/wake-on-lan.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/water-heater-management.ts b/packages/main/src/forwards/clusters/water-heater-management.ts new file mode 100644 index 0000000000..3292f862d9 --- /dev/null +++ b/packages/main/src/forwards/clusters/water-heater-management.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/water-heater-management"; diff --git a/packages/main/src/forwards/clusters/water-heater-mode.ts b/packages/main/src/forwards/clusters/water-heater-mode.ts new file mode 100644 index 0000000000..b855983641 --- /dev/null +++ b/packages/main/src/forwards/clusters/water-heater-mode.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/water-heater-mode"; diff --git a/packages/main/src/forwards/clusters/water-tank-level-monitoring.ts b/packages/main/src/forwards/clusters/water-tank-level-monitoring.ts new file mode 100644 index 0000000000..2d44347d6b --- /dev/null +++ b/packages/main/src/forwards/clusters/water-tank-level-monitoring.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/water-tank-level-monitoring"; diff --git a/packages/main/src/forwards/clusters/wi-fi-network-diagnostics.ts b/packages/main/src/forwards/clusters/wi-fi-network-diagnostics.ts index 2c1ef698ab..11afb78b0d 100644 --- a/packages/main/src/forwards/clusters/wi-fi-network-diagnostics.ts +++ b/packages/main/src/forwards/clusters/wi-fi-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/clusters/wi-fi-network-management.ts b/packages/main/src/forwards/clusters/wi-fi-network-management.ts new file mode 100644 index 0000000000..7bb9abc71a --- /dev/null +++ b/packages/main/src/forwards/clusters/wi-fi-network-management.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#clusters/wi-fi-network-management"; diff --git a/packages/main/src/forwards/clusters/window-covering.ts b/packages/main/src/forwards/clusters/window-covering.ts index cd59dabcee..8645b48529 100644 --- a/packages/main/src/forwards/clusters/window-covering.ts +++ b/packages/main/src/forwards/clusters/window-covering.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/air-purifier.ts b/packages/main/src/forwards/devices/air-purifier.ts index 705f89436f..b7c0c0d3bb 100644 --- a/packages/main/src/forwards/devices/air-purifier.ts +++ b/packages/main/src/forwards/devices/air-purifier.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/air-quality-sensor.ts b/packages/main/src/forwards/devices/air-quality-sensor.ts index 329f8583fd..d2cbfd6825 100644 --- a/packages/main/src/forwards/devices/air-quality-sensor.ts +++ b/packages/main/src/forwards/devices/air-quality-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/basic-video-player.ts b/packages/main/src/forwards/devices/basic-video-player.ts index 147697ce43..185917c105 100644 --- a/packages/main/src/forwards/devices/basic-video-player.ts +++ b/packages/main/src/forwards/devices/basic-video-player.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/battery-storage.ts b/packages/main/src/forwards/devices/battery-storage.ts new file mode 100644 index 0000000000..e3b42d6064 --- /dev/null +++ b/packages/main/src/forwards/devices/battery-storage.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#devices/battery-storage"; diff --git a/packages/main/src/forwards/devices/casting-video-client.ts b/packages/main/src/forwards/devices/casting-video-client.ts index 43f9015b48..6475f52f85 100644 --- a/packages/main/src/forwards/devices/casting-video-client.ts +++ b/packages/main/src/forwards/devices/casting-video-client.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/casting-video-player.ts b/packages/main/src/forwards/devices/casting-video-player.ts index 8641319a24..dfd2bd2809 100644 --- a/packages/main/src/forwards/devices/casting-video-player.ts +++ b/packages/main/src/forwards/devices/casting-video-player.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/color-dimmer-switch.ts b/packages/main/src/forwards/devices/color-dimmer-switch.ts index 119ca4b59b..0cde03218c 100644 --- a/packages/main/src/forwards/devices/color-dimmer-switch.ts +++ b/packages/main/src/forwards/devices/color-dimmer-switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/color-temperature-light.ts b/packages/main/src/forwards/devices/color-temperature-light.ts index bd0dbb5a91..d36047cbc2 100644 --- a/packages/main/src/forwards/devices/color-temperature-light.ts +++ b/packages/main/src/forwards/devices/color-temperature-light.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/contact-sensor.ts b/packages/main/src/forwards/devices/contact-sensor.ts index 6376023e90..54a3734b2e 100644 --- a/packages/main/src/forwards/devices/contact-sensor.ts +++ b/packages/main/src/forwards/devices/contact-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/content-app.ts b/packages/main/src/forwards/devices/content-app.ts index 974120a8fc..c7fd004ad9 100644 --- a/packages/main/src/forwards/devices/content-app.ts +++ b/packages/main/src/forwards/devices/content-app.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/control-bridge.ts b/packages/main/src/forwards/devices/control-bridge.ts index ea8e5b39c3..5d70951792 100644 --- a/packages/main/src/forwards/devices/control-bridge.ts +++ b/packages/main/src/forwards/devices/control-bridge.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/cook-surface.ts b/packages/main/src/forwards/devices/cook-surface.ts index afbad852df..cc5da48276 100644 --- a/packages/main/src/forwards/devices/cook-surface.ts +++ b/packages/main/src/forwards/devices/cook-surface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/cooktop.ts b/packages/main/src/forwards/devices/cooktop.ts index 05a724c40f..b4f7961496 100644 --- a/packages/main/src/forwards/devices/cooktop.ts +++ b/packages/main/src/forwards/devices/cooktop.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/dimmable-light.ts b/packages/main/src/forwards/devices/dimmable-light.ts index 1046b0232b..e99b75681d 100644 --- a/packages/main/src/forwards/devices/dimmable-light.ts +++ b/packages/main/src/forwards/devices/dimmable-light.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/dimmable-plug-in-unit.ts b/packages/main/src/forwards/devices/dimmable-plug-in-unit.ts index 9c123e74d3..cbeab219d8 100644 --- a/packages/main/src/forwards/devices/dimmable-plug-in-unit.ts +++ b/packages/main/src/forwards/devices/dimmable-plug-in-unit.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/dimmer-switch.ts b/packages/main/src/forwards/devices/dimmer-switch.ts index 52620ea4df..92ea035c02 100644 --- a/packages/main/src/forwards/devices/dimmer-switch.ts +++ b/packages/main/src/forwards/devices/dimmer-switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/dishwasher.ts b/packages/main/src/forwards/devices/dishwasher.ts index a02874429e..b8b22f159b 100644 --- a/packages/main/src/forwards/devices/dishwasher.ts +++ b/packages/main/src/forwards/devices/dishwasher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/door-lock-controller.ts b/packages/main/src/forwards/devices/door-lock-controller.ts index ef1ad918dd..89b109dc1d 100644 --- a/packages/main/src/forwards/devices/door-lock-controller.ts +++ b/packages/main/src/forwards/devices/door-lock-controller.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/door-lock.ts b/packages/main/src/forwards/devices/door-lock.ts index d2a6606fe6..9daebc3651 100644 --- a/packages/main/src/forwards/devices/door-lock.ts +++ b/packages/main/src/forwards/devices/door-lock.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/energy-evse.ts b/packages/main/src/forwards/devices/energy-evse.ts new file mode 100644 index 0000000000..8af4086f2a --- /dev/null +++ b/packages/main/src/forwards/devices/energy-evse.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#devices/energy-evse"; diff --git a/packages/main/src/forwards/devices/extended-color-light.ts b/packages/main/src/forwards/devices/extended-color-light.ts index 2cdf0dd22b..831bef093a 100644 --- a/packages/main/src/forwards/devices/extended-color-light.ts +++ b/packages/main/src/forwards/devices/extended-color-light.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/extractor-hood.ts b/packages/main/src/forwards/devices/extractor-hood.ts index aa52bf4b73..3db4d96a91 100644 --- a/packages/main/src/forwards/devices/extractor-hood.ts +++ b/packages/main/src/forwards/devices/extractor-hood.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/fan.ts b/packages/main/src/forwards/devices/fan.ts index 1139c73c3d..d0670ce37c 100644 --- a/packages/main/src/forwards/devices/fan.ts +++ b/packages/main/src/forwards/devices/fan.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/flow-sensor.ts b/packages/main/src/forwards/devices/flow-sensor.ts index bc7a249fc5..8f815a436f 100644 --- a/packages/main/src/forwards/devices/flow-sensor.ts +++ b/packages/main/src/forwards/devices/flow-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/generic-switch.ts b/packages/main/src/forwards/devices/generic-switch.ts index 0a9f5b2f99..0c46f63434 100644 --- a/packages/main/src/forwards/devices/generic-switch.ts +++ b/packages/main/src/forwards/devices/generic-switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/heat-pump.ts b/packages/main/src/forwards/devices/heat-pump.ts new file mode 100644 index 0000000000..07c90eff7f --- /dev/null +++ b/packages/main/src/forwards/devices/heat-pump.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#devices/heat-pump"; diff --git a/packages/main/src/forwards/devices/humidity-sensor.ts b/packages/main/src/forwards/devices/humidity-sensor.ts index c6d2c83fe9..74cd0acf78 100644 --- a/packages/main/src/forwards/devices/humidity-sensor.ts +++ b/packages/main/src/forwards/devices/humidity-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/index.ts b/packages/main/src/forwards/devices/index.ts index 366b1eaba9..fa57e46ba4 100644 --- a/packages/main/src/forwards/devices/index.ts +++ b/packages/main/src/forwards/devices/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/laundry-dryer.ts b/packages/main/src/forwards/devices/laundry-dryer.ts index 279865196f..552ebce4f6 100644 --- a/packages/main/src/forwards/devices/laundry-dryer.ts +++ b/packages/main/src/forwards/devices/laundry-dryer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/laundry-washer.ts b/packages/main/src/forwards/devices/laundry-washer.ts index 9d27d08414..dc972847b6 100644 --- a/packages/main/src/forwards/devices/laundry-washer.ts +++ b/packages/main/src/forwards/devices/laundry-washer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/light-sensor.ts b/packages/main/src/forwards/devices/light-sensor.ts index 2280aa6937..7eb047a27d 100644 --- a/packages/main/src/forwards/devices/light-sensor.ts +++ b/packages/main/src/forwards/devices/light-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/microwave-oven.ts b/packages/main/src/forwards/devices/microwave-oven.ts index 34b1f7804e..aca9665c70 100644 --- a/packages/main/src/forwards/devices/microwave-oven.ts +++ b/packages/main/src/forwards/devices/microwave-oven.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/mode-select.ts b/packages/main/src/forwards/devices/mode-select.ts index 77d21f8a92..873d12b56e 100644 --- a/packages/main/src/forwards/devices/mode-select.ts +++ b/packages/main/src/forwards/devices/mode-select.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/mounted-dimmable-load-control.ts b/packages/main/src/forwards/devices/mounted-dimmable-load-control.ts new file mode 100644 index 0000000000..a1ce7e1945 --- /dev/null +++ b/packages/main/src/forwards/devices/mounted-dimmable-load-control.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#devices/mounted-dimmable-load-control"; diff --git a/packages/main/src/forwards/devices/mounted-on-off-control.ts b/packages/main/src/forwards/devices/mounted-on-off-control.ts new file mode 100644 index 0000000000..7c88c4d70a --- /dev/null +++ b/packages/main/src/forwards/devices/mounted-on-off-control.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#devices/mounted-on-off-control"; diff --git a/packages/main/src/forwards/devices/network-infrastructure-manager.ts b/packages/main/src/forwards/devices/network-infrastructure-manager.ts new file mode 100644 index 0000000000..ea8c10d5e3 --- /dev/null +++ b/packages/main/src/forwards/devices/network-infrastructure-manager.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#devices/network-infrastructure-manager"; diff --git a/packages/main/src/forwards/devices/occupancy-sensor.ts b/packages/main/src/forwards/devices/occupancy-sensor.ts index 9b45464e53..6b035a4b5c 100644 --- a/packages/main/src/forwards/devices/occupancy-sensor.ts +++ b/packages/main/src/forwards/devices/occupancy-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/on-off-light-switch.ts b/packages/main/src/forwards/devices/on-off-light-switch.ts index b466cfca4d..0b3450568c 100644 --- a/packages/main/src/forwards/devices/on-off-light-switch.ts +++ b/packages/main/src/forwards/devices/on-off-light-switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/on-off-light.ts b/packages/main/src/forwards/devices/on-off-light.ts index eb55fb0159..b3028c76cd 100644 --- a/packages/main/src/forwards/devices/on-off-light.ts +++ b/packages/main/src/forwards/devices/on-off-light.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/on-off-plug-in-unit.ts b/packages/main/src/forwards/devices/on-off-plug-in-unit.ts index b662e337b5..4798f0b3dc 100644 --- a/packages/main/src/forwards/devices/on-off-plug-in-unit.ts +++ b/packages/main/src/forwards/devices/on-off-plug-in-unit.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/on-off-sensor.ts b/packages/main/src/forwards/devices/on-off-sensor.ts index 09f76b5b63..83d14b9d29 100644 --- a/packages/main/src/forwards/devices/on-off-sensor.ts +++ b/packages/main/src/forwards/devices/on-off-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/oven.ts b/packages/main/src/forwards/devices/oven.ts index a46c20c108..bafb115e45 100644 --- a/packages/main/src/forwards/devices/oven.ts +++ b/packages/main/src/forwards/devices/oven.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/pressure-sensor.ts b/packages/main/src/forwards/devices/pressure-sensor.ts index 8542695351..377f4f29c6 100644 --- a/packages/main/src/forwards/devices/pressure-sensor.ts +++ b/packages/main/src/forwards/devices/pressure-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/pump-controller.ts b/packages/main/src/forwards/devices/pump-controller.ts index 2d7932b3a5..6f11564774 100644 --- a/packages/main/src/forwards/devices/pump-controller.ts +++ b/packages/main/src/forwards/devices/pump-controller.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/pump.ts b/packages/main/src/forwards/devices/pump.ts index ef53f2f40b..d78e74ce43 100644 --- a/packages/main/src/forwards/devices/pump.ts +++ b/packages/main/src/forwards/devices/pump.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/rain-sensor.ts b/packages/main/src/forwards/devices/rain-sensor.ts index fb1ef08873..5f2a3197a1 100644 --- a/packages/main/src/forwards/devices/rain-sensor.ts +++ b/packages/main/src/forwards/devices/rain-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/refrigerator.ts b/packages/main/src/forwards/devices/refrigerator.ts index 3cf8d3b442..6a45ce24fb 100644 --- a/packages/main/src/forwards/devices/refrigerator.ts +++ b/packages/main/src/forwards/devices/refrigerator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/robotic-vacuum-cleaner.ts b/packages/main/src/forwards/devices/robotic-vacuum-cleaner.ts index d4ceee1e13..5bf5b40de8 100644 --- a/packages/main/src/forwards/devices/robotic-vacuum-cleaner.ts +++ b/packages/main/src/forwards/devices/robotic-vacuum-cleaner.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/room-air-conditioner.ts b/packages/main/src/forwards/devices/room-air-conditioner.ts index 0af2e25164..ef4c2aac28 100644 --- a/packages/main/src/forwards/devices/room-air-conditioner.ts +++ b/packages/main/src/forwards/devices/room-air-conditioner.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/smoke-co-alarm.ts b/packages/main/src/forwards/devices/smoke-co-alarm.ts index 7408623b65..7016751762 100644 --- a/packages/main/src/forwards/devices/smoke-co-alarm.ts +++ b/packages/main/src/forwards/devices/smoke-co-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/solar-power.ts b/packages/main/src/forwards/devices/solar-power.ts new file mode 100644 index 0000000000..086d4072df --- /dev/null +++ b/packages/main/src/forwards/devices/solar-power.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#devices/solar-power"; diff --git a/packages/main/src/forwards/devices/speaker.ts b/packages/main/src/forwards/devices/speaker.ts index a65b150a94..54d59376f9 100644 --- a/packages/main/src/forwards/devices/speaker.ts +++ b/packages/main/src/forwards/devices/speaker.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/temperature-controlled-cabinet.ts b/packages/main/src/forwards/devices/temperature-controlled-cabinet.ts index aaf60a16a6..ff87ed96fc 100644 --- a/packages/main/src/forwards/devices/temperature-controlled-cabinet.ts +++ b/packages/main/src/forwards/devices/temperature-controlled-cabinet.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/temperature-sensor.ts b/packages/main/src/forwards/devices/temperature-sensor.ts index 8d1a4347f0..b1c54bd20c 100644 --- a/packages/main/src/forwards/devices/temperature-sensor.ts +++ b/packages/main/src/forwards/devices/temperature-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/thermostat.ts b/packages/main/src/forwards/devices/thermostat.ts index 562c83a1b6..1682bd48f7 100644 --- a/packages/main/src/forwards/devices/thermostat.ts +++ b/packages/main/src/forwards/devices/thermostat.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/video-remote-control.ts b/packages/main/src/forwards/devices/video-remote-control.ts index 05d6c4d025..3fbea1215e 100644 --- a/packages/main/src/forwards/devices/video-remote-control.ts +++ b/packages/main/src/forwards/devices/video-remote-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/water-freeze-detector.ts b/packages/main/src/forwards/devices/water-freeze-detector.ts index 137d824e1c..e252fc23e8 100644 --- a/packages/main/src/forwards/devices/water-freeze-detector.ts +++ b/packages/main/src/forwards/devices/water-freeze-detector.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/water-heater.ts b/packages/main/src/forwards/devices/water-heater.ts new file mode 100644 index 0000000000..8c01af0815 --- /dev/null +++ b/packages/main/src/forwards/devices/water-heater.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#devices/water-heater"; diff --git a/packages/main/src/forwards/devices/water-leak-detector.ts b/packages/main/src/forwards/devices/water-leak-detector.ts index 080b274c09..b2a61436a1 100644 --- a/packages/main/src/forwards/devices/water-leak-detector.ts +++ b/packages/main/src/forwards/devices/water-leak-detector.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/water-valve.ts b/packages/main/src/forwards/devices/water-valve.ts index 058589556b..841eff1087 100644 --- a/packages/main/src/forwards/devices/water-valve.ts +++ b/packages/main/src/forwards/devices/water-valve.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/window-covering-controller.ts b/packages/main/src/forwards/devices/window-covering-controller.ts index 976d0dd3bb..77e7a04e6e 100644 --- a/packages/main/src/forwards/devices/window-covering-controller.ts +++ b/packages/main/src/forwards/devices/window-covering-controller.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/devices/window-covering.ts b/packages/main/src/forwards/devices/window-covering.ts index 1704d00b23..12572959ec 100644 --- a/packages/main/src/forwards/devices/window-covering.ts +++ b/packages/main/src/forwards/devices/window-covering.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/aggregator.ts b/packages/main/src/forwards/endpoints/aggregator.ts index b08d7c1a58..38d4d82ef6 100644 --- a/packages/main/src/forwards/endpoints/aggregator.ts +++ b/packages/main/src/forwards/endpoints/aggregator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/base.ts b/packages/main/src/forwards/endpoints/base.ts index 7c6fdbaf35..a187b3c380 100644 --- a/packages/main/src/forwards/endpoints/base.ts +++ b/packages/main/src/forwards/endpoints/base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/bridged-node.ts b/packages/main/src/forwards/endpoints/bridged-node.ts index 1e3644f81b..6754419105 100644 --- a/packages/main/src/forwards/endpoints/bridged-node.ts +++ b/packages/main/src/forwards/endpoints/bridged-node.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/device-energy-management.ts b/packages/main/src/forwards/endpoints/device-energy-management.ts index df17ce001d..6a17b1bafd 100644 --- a/packages/main/src/forwards/endpoints/device-energy-management.ts +++ b/packages/main/src/forwards/endpoints/device-energy-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/electrical-sensor.ts b/packages/main/src/forwards/endpoints/electrical-sensor.ts index 48a3511490..a3eceaa223 100644 --- a/packages/main/src/forwards/endpoints/electrical-sensor.ts +++ b/packages/main/src/forwards/endpoints/electrical-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/index.ts b/packages/main/src/forwards/endpoints/index.ts index 366b1eaba9..fa57e46ba4 100644 --- a/packages/main/src/forwards/endpoints/index.ts +++ b/packages/main/src/forwards/endpoints/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/joint-fabric-administrator.ts b/packages/main/src/forwards/endpoints/joint-fabric-administrator.ts new file mode 100644 index 0000000000..2acd29c90e --- /dev/null +++ b/packages/main/src/forwards/endpoints/joint-fabric-administrator.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#endpoints/joint-fabric-administrator"; diff --git a/packages/main/src/forwards/endpoints/ota-provider.ts b/packages/main/src/forwards/endpoints/ota-provider.ts index b25b9e849a..a99ba1336f 100644 --- a/packages/main/src/forwards/endpoints/ota-provider.ts +++ b/packages/main/src/forwards/endpoints/ota-provider.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/ota-requestor.ts b/packages/main/src/forwards/endpoints/ota-requestor.ts index 1362b59b3d..cc835f38ec 100644 --- a/packages/main/src/forwards/endpoints/ota-requestor.ts +++ b/packages/main/src/forwards/endpoints/ota-requestor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/power-source.ts b/packages/main/src/forwards/endpoints/power-source.ts index 7c45ec3d69..fa63eb5c15 100644 --- a/packages/main/src/forwards/endpoints/power-source.ts +++ b/packages/main/src/forwards/endpoints/power-source.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/root.ts b/packages/main/src/forwards/endpoints/root.ts index 40363d864d..33ce458b51 100644 --- a/packages/main/src/forwards/endpoints/root.ts +++ b/packages/main/src/forwards/endpoints/root.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/main/src/forwards/endpoints/secondary-network-interface.ts b/packages/main/src/forwards/endpoints/secondary-network-interface.ts new file mode 100644 index 0000000000..5b1722f722 --- /dev/null +++ b/packages/main/src/forwards/endpoints/secondary-network-interface.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import "#platform"; + +export * from "#endpoints/secondary-network-interface"; diff --git a/packages/main/src/tsconfig.json b/packages/main/src/tsconfig.json index 22195d9306..8b87cc96e9 100644 --- a/packages/main/src/tsconfig.json +++ b/packages/main/src/tsconfig.json @@ -22,6 +22,9 @@ { "path": "../../protocol/src" }, + { + "path": "../../tools/src" + }, { "path": "../../types/src" } diff --git a/packages/matter.js/src/CommissioningServer.ts b/packages/matter.js/src/CommissioningServer.ts index 3006cd4c1c..fcc1dd4c27 100644 --- a/packages/matter.js/src/CommissioningServer.ts +++ b/packages/matter.js/src/CommissioningServer.ts @@ -16,6 +16,7 @@ import { GroupKeyManagementCluster, OperationalCredentialsCluster, } from "#clusters"; +import { BasicInformationServer } from "#forwards/behaviors/basic-information.js"; import { Bytes, Crypto, @@ -275,6 +276,7 @@ export class CommissioningServer extends MatterNode { const basicInformationAttributes: AttributeInitialValues = { dataModelRevision: Specification.DATA_MODEL_REVISION, nodeLabel: "", + uniqueId: BasicInformationServer.createUniqueId(), hardwareVersion: 0, hardwareVersionString: "0", location: "XX", diff --git a/packages/matter.js/src/cluster/server/AccessControlServer.ts b/packages/matter.js/src/cluster/server/AccessControlServer.ts index b96df0fd35..5f51e7da8f 100644 --- a/packages/matter.js/src/cluster/server/AccessControlServer.ts +++ b/packages/matter.js/src/cluster/server/AccessControlServer.ts @@ -33,7 +33,9 @@ import { ClusterServerHandlers } from "./ClusterServerTypes.js"; const logger = Logger.get("AccessControlClusterServer"); -export const AccessControlClusterHandler: () => ClusterServerHandlers = () => { +const Cluster = AccessControlCluster.with("Extension"); + +export const AccessControlClusterHandler: () => ClusterServerHandlers = () => { let accessControlEntryChangedEvent: | FabricSensitiveEventServer | undefined = undefined; @@ -326,7 +328,7 @@ export const AccessControlClusterHandler: () => ClusterServerHandlers ClusterServer( - AccessControlCluster, + Cluster, { acl: [], extension: [], diff --git a/packages/matter.js/src/device/DeviceInformation.ts b/packages/matter.js/src/device/DeviceInformation.ts index 06246ed3e1..5595969d34 100644 --- a/packages/matter.js/src/device/DeviceInformation.ts +++ b/packages/matter.js/src/device/DeviceInformation.ts @@ -155,7 +155,7 @@ export class DeviceInformation { } } - const powerSourceCluster = endpoint.getClusterClient(PowerSource.Cluster); + const powerSourceCluster = endpoint.getClusterClient(PowerSource.Complete); if (powerSourceCluster !== undefined) { if ((await powerSourceCluster.getStatusAttribute()) === PowerSource.PowerSourceStatus.Active) { const features = await powerSourceCluster.getFeatureMapAttribute(); @@ -192,11 +192,11 @@ export class DeviceInformation { }, { clusterId: PowerSource.Cluster.id, - attributeId: PowerSource.Cluster.attributes.featureMap.id, + attributeId: PowerSource.Complete.attributes.featureMap.id, }, { clusterId: PowerSource.Cluster.id, - attributeId: PowerSource.Cluster.attributes.status.id, + attributeId: PowerSource.Complete.attributes.status.id, }, { endpointId: EndpointNumber(0), @@ -261,9 +261,9 @@ export class DeviceInformation { break; case PowerSource.Cluster.id: const powerSourceEntry = powerSourceData.get(endpointId) ?? {}; - if (attributeId === PowerSource.Cluster.attributes.featureMap.id) { + if (attributeId === PowerSource.Complete.attributes.featureMap.id) { powerSourceEntry.features = value; - } else if (attributeId === PowerSource.Cluster.attributes.status.id) { + } else if (attributeId === PowerSource.Complete.attributes.status.id) { powerSourceEntry.status = value; } powerSourceData.set(endpointId, powerSourceEntry); diff --git a/packages/matter.js/src/forwards/behaviors/access-control.ts b/packages/matter.js/src/forwards/behaviors/access-control.ts index 64d30a2f1f..6cee94650c 100644 --- a/packages/matter.js/src/forwards/behaviors/access-control.ts +++ b/packages/matter.js/src/forwards/behaviors/access-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/account-login.ts b/packages/matter.js/src/forwards/behaviors/account-login.ts index 819b622e44..14ed3dcf8b 100644 --- a/packages/matter.js/src/forwards/behaviors/account-login.ts +++ b/packages/matter.js/src/forwards/behaviors/account-login.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/actions.ts b/packages/matter.js/src/forwards/behaviors/actions.ts index 9c8e652f35..9a5a837cf4 100644 --- a/packages/matter.js/src/forwards/behaviors/actions.ts +++ b/packages/matter.js/src/forwards/behaviors/actions.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/activated-carbon-filter-monitoring.ts b/packages/matter.js/src/forwards/behaviors/activated-carbon-filter-monitoring.ts index 3dd8627bfd..e8974b5f8b 100644 --- a/packages/matter.js/src/forwards/behaviors/activated-carbon-filter-monitoring.ts +++ b/packages/matter.js/src/forwards/behaviors/activated-carbon-filter-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/administrator-commissioning.ts b/packages/matter.js/src/forwards/behaviors/administrator-commissioning.ts index aa65774e07..7e835080fd 100644 --- a/packages/matter.js/src/forwards/behaviors/administrator-commissioning.ts +++ b/packages/matter.js/src/forwards/behaviors/administrator-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/air-quality.ts b/packages/matter.js/src/forwards/behaviors/air-quality.ts index 01a39bf431..c590669553 100644 --- a/packages/matter.js/src/forwards/behaviors/air-quality.ts +++ b/packages/matter.js/src/forwards/behaviors/air-quality.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/alarm-base.ts b/packages/matter.js/src/forwards/behaviors/alarm-base.ts index ab0b232d27..4d8c294dd5 100644 --- a/packages/matter.js/src/forwards/behaviors/alarm-base.ts +++ b/packages/matter.js/src/forwards/behaviors/alarm-base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/application-basic.ts b/packages/matter.js/src/forwards/behaviors/application-basic.ts index da6a62d4ed..daf8805bbf 100644 --- a/packages/matter.js/src/forwards/behaviors/application-basic.ts +++ b/packages/matter.js/src/forwards/behaviors/application-basic.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/application-launcher.ts b/packages/matter.js/src/forwards/behaviors/application-launcher.ts index 00f35e854a..4c32b67087 100644 --- a/packages/matter.js/src/forwards/behaviors/application-launcher.ts +++ b/packages/matter.js/src/forwards/behaviors/application-launcher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/audio-output.ts b/packages/matter.js/src/forwards/behaviors/audio-output.ts index 8e77fa9e50..7016c4a4a2 100644 --- a/packages/matter.js/src/forwards/behaviors/audio-output.ts +++ b/packages/matter.js/src/forwards/behaviors/audio-output.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/ballast-configuration.ts b/packages/matter.js/src/forwards/behaviors/ballast-configuration.ts index 4dd9a06d08..e7e1d0fd3d 100644 --- a/packages/matter.js/src/forwards/behaviors/ballast-configuration.ts +++ b/packages/matter.js/src/forwards/behaviors/ballast-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/basic-information.ts b/packages/matter.js/src/forwards/behaviors/basic-information.ts index c5f819db60..de869c2228 100644 --- a/packages/matter.js/src/forwards/behaviors/basic-information.ts +++ b/packages/matter.js/src/forwards/behaviors/basic-information.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/binding.ts b/packages/matter.js/src/forwards/behaviors/binding.ts index 23c07a68a6..88d553c69c 100644 --- a/packages/matter.js/src/forwards/behaviors/binding.ts +++ b/packages/matter.js/src/forwards/behaviors/binding.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/boolean-state-configuration.ts b/packages/matter.js/src/forwards/behaviors/boolean-state-configuration.ts index 33fb50e99f..98a7173c12 100644 --- a/packages/matter.js/src/forwards/behaviors/boolean-state-configuration.ts +++ b/packages/matter.js/src/forwards/behaviors/boolean-state-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/boolean-state.ts b/packages/matter.js/src/forwards/behaviors/boolean-state.ts index bfc968b71c..dab9804b9d 100644 --- a/packages/matter.js/src/forwards/behaviors/boolean-state.ts +++ b/packages/matter.js/src/forwards/behaviors/boolean-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/bridged-device-basic-information.ts b/packages/matter.js/src/forwards/behaviors/bridged-device-basic-information.ts index e5a41f2a80..7160df362b 100644 --- a/packages/matter.js/src/forwards/behaviors/bridged-device-basic-information.ts +++ b/packages/matter.js/src/forwards/behaviors/bridged-device-basic-information.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/carbon-dioxide-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/carbon-dioxide-concentration-measurement.ts index 79163b398a..fa455e73ce 100644 --- a/packages/matter.js/src/forwards/behaviors/carbon-dioxide-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/carbon-dioxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/carbon-monoxide-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/carbon-monoxide-concentration-measurement.ts index 5e40557216..3e6a484f10 100644 --- a/packages/matter.js/src/forwards/behaviors/carbon-monoxide-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/carbon-monoxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/channel.ts b/packages/matter.js/src/forwards/behaviors/channel.ts index 875d54ae02..8e71532940 100644 --- a/packages/matter.js/src/forwards/behaviors/channel.ts +++ b/packages/matter.js/src/forwards/behaviors/channel.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/color-control.ts b/packages/matter.js/src/forwards/behaviors/color-control.ts index 5a84648086..48545e0c95 100644 --- a/packages/matter.js/src/forwards/behaviors/color-control.ts +++ b/packages/matter.js/src/forwards/behaviors/color-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/commissioner-control.ts b/packages/matter.js/src/forwards/behaviors/commissioner-control.ts new file mode 100644 index 0000000000..7a50e4c7c2 --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/commissioner-control.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/commissioner-control"; diff --git a/packages/matter.js/src/forwards/behaviors/concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/concentration-measurement.ts index 68b937a358..028fd3da71 100644 --- a/packages/matter.js/src/forwards/behaviors/concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/content-app-observer.ts b/packages/matter.js/src/forwards/behaviors/content-app-observer.ts index 7ed8011dd4..ad1dcc5b7a 100644 --- a/packages/matter.js/src/forwards/behaviors/content-app-observer.ts +++ b/packages/matter.js/src/forwards/behaviors/content-app-observer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/content-control.ts b/packages/matter.js/src/forwards/behaviors/content-control.ts index de485eda4b..b64bc2261d 100644 --- a/packages/matter.js/src/forwards/behaviors/content-control.ts +++ b/packages/matter.js/src/forwards/behaviors/content-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/content-launcher.ts b/packages/matter.js/src/forwards/behaviors/content-launcher.ts index f201826858..20e5ad1521 100644 --- a/packages/matter.js/src/forwards/behaviors/content-launcher.ts +++ b/packages/matter.js/src/forwards/behaviors/content-launcher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/descriptor.ts b/packages/matter.js/src/forwards/behaviors/descriptor.ts index 4db3edb45c..434258bf00 100644 --- a/packages/matter.js/src/forwards/behaviors/descriptor.ts +++ b/packages/matter.js/src/forwards/behaviors/descriptor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/device-energy-management-mode.ts b/packages/matter.js/src/forwards/behaviors/device-energy-management-mode.ts index 89a7f9b980..b21782325e 100644 --- a/packages/matter.js/src/forwards/behaviors/device-energy-management-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/device-energy-management-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/device-energy-management.ts b/packages/matter.js/src/forwards/behaviors/device-energy-management.ts index d73208842d..b8c30cce7c 100644 --- a/packages/matter.js/src/forwards/behaviors/device-energy-management.ts +++ b/packages/matter.js/src/forwards/behaviors/device-energy-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/diagnostic-logs.ts b/packages/matter.js/src/forwards/behaviors/diagnostic-logs.ts index dd4c68d1c8..bcfa3fcd6b 100644 --- a/packages/matter.js/src/forwards/behaviors/diagnostic-logs.ts +++ b/packages/matter.js/src/forwards/behaviors/diagnostic-logs.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/dishwasher-alarm.ts b/packages/matter.js/src/forwards/behaviors/dishwasher-alarm.ts index 3a325959b4..92c46e517c 100644 --- a/packages/matter.js/src/forwards/behaviors/dishwasher-alarm.ts +++ b/packages/matter.js/src/forwards/behaviors/dishwasher-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/dishwasher-mode.ts b/packages/matter.js/src/forwards/behaviors/dishwasher-mode.ts index 1c0bb9c02d..b90dff4d8a 100644 --- a/packages/matter.js/src/forwards/behaviors/dishwasher-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/dishwasher-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/door-lock.ts b/packages/matter.js/src/forwards/behaviors/door-lock.ts index 5c95b50369..021796c510 100644 --- a/packages/matter.js/src/forwards/behaviors/door-lock.ts +++ b/packages/matter.js/src/forwards/behaviors/door-lock.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/ecosystem-information.ts b/packages/matter.js/src/forwards/behaviors/ecosystem-information.ts new file mode 100644 index 0000000000..8bf7d0f80c --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/ecosystem-information.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/ecosystem-information"; diff --git a/packages/matter.js/src/forwards/behaviors/electrical-energy-measurement.ts b/packages/matter.js/src/forwards/behaviors/electrical-energy-measurement.ts index 1ac8e86350..ab4895c4ee 100644 --- a/packages/matter.js/src/forwards/behaviors/electrical-energy-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/electrical-energy-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/electrical-power-measurement.ts b/packages/matter.js/src/forwards/behaviors/electrical-power-measurement.ts index 27d96d78e3..dc15164d85 100644 --- a/packages/matter.js/src/forwards/behaviors/electrical-power-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/electrical-power-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/energy-evse-mode.ts b/packages/matter.js/src/forwards/behaviors/energy-evse-mode.ts index fb26bdcd05..3f3e795fda 100644 --- a/packages/matter.js/src/forwards/behaviors/energy-evse-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/energy-evse-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/energy-evse.ts b/packages/matter.js/src/forwards/behaviors/energy-evse.ts index b55bda9ed2..d83525bdc2 100644 --- a/packages/matter.js/src/forwards/behaviors/energy-evse.ts +++ b/packages/matter.js/src/forwards/behaviors/energy-evse.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/energy-preference.ts b/packages/matter.js/src/forwards/behaviors/energy-preference.ts index 103ede3993..ba55539627 100644 --- a/packages/matter.js/src/forwards/behaviors/energy-preference.ts +++ b/packages/matter.js/src/forwards/behaviors/energy-preference.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/ethernet-network-diagnostics.ts b/packages/matter.js/src/forwards/behaviors/ethernet-network-diagnostics.ts index 3e90e29a17..65b05803cf 100644 --- a/packages/matter.js/src/forwards/behaviors/ethernet-network-diagnostics.ts +++ b/packages/matter.js/src/forwards/behaviors/ethernet-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/fan-control.ts b/packages/matter.js/src/forwards/behaviors/fan-control.ts index adce674e4e..3f9263d56e 100644 --- a/packages/matter.js/src/forwards/behaviors/fan-control.ts +++ b/packages/matter.js/src/forwards/behaviors/fan-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/fixed-label.ts b/packages/matter.js/src/forwards/behaviors/fixed-label.ts index 59e0505776..5107e3d251 100644 --- a/packages/matter.js/src/forwards/behaviors/fixed-label.ts +++ b/packages/matter.js/src/forwards/behaviors/fixed-label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/flow-measurement.ts b/packages/matter.js/src/forwards/behaviors/flow-measurement.ts index c71c41a8bc..55830d1906 100644 --- a/packages/matter.js/src/forwards/behaviors/flow-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/flow-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/formaldehyde-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/formaldehyde-concentration-measurement.ts index c45786a4aa..459d6c67f8 100644 --- a/packages/matter.js/src/forwards/behaviors/formaldehyde-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/formaldehyde-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/general-commissioning.ts b/packages/matter.js/src/forwards/behaviors/general-commissioning.ts index c55d95c805..9ff4bf9e51 100644 --- a/packages/matter.js/src/forwards/behaviors/general-commissioning.ts +++ b/packages/matter.js/src/forwards/behaviors/general-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/general-diagnostics.ts b/packages/matter.js/src/forwards/behaviors/general-diagnostics.ts index 0ee85f34ef..483e956d45 100644 --- a/packages/matter.js/src/forwards/behaviors/general-diagnostics.ts +++ b/packages/matter.js/src/forwards/behaviors/general-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/group-key-management.ts b/packages/matter.js/src/forwards/behaviors/group-key-management.ts index 8fdec4c916..64371114c7 100644 --- a/packages/matter.js/src/forwards/behaviors/group-key-management.ts +++ b/packages/matter.js/src/forwards/behaviors/group-key-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/groups.ts b/packages/matter.js/src/forwards/behaviors/groups.ts index d83127b1d3..f9868c375b 100644 --- a/packages/matter.js/src/forwards/behaviors/groups.ts +++ b/packages/matter.js/src/forwards/behaviors/groups.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/hepa-filter-monitoring.ts b/packages/matter.js/src/forwards/behaviors/hepa-filter-monitoring.ts index 04c0a07ff7..ebafc7e69b 100644 --- a/packages/matter.js/src/forwards/behaviors/hepa-filter-monitoring.ts +++ b/packages/matter.js/src/forwards/behaviors/hepa-filter-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/icd-management.ts b/packages/matter.js/src/forwards/behaviors/icd-management.ts index b8384990f5..da81eb48b6 100644 --- a/packages/matter.js/src/forwards/behaviors/icd-management.ts +++ b/packages/matter.js/src/forwards/behaviors/icd-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/identify.ts b/packages/matter.js/src/forwards/behaviors/identify.ts index 9d0407c38e..15d09a48dc 100644 --- a/packages/matter.js/src/forwards/behaviors/identify.ts +++ b/packages/matter.js/src/forwards/behaviors/identify.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/illuminance-measurement.ts b/packages/matter.js/src/forwards/behaviors/illuminance-measurement.ts index 07c6762b4d..9cc5248e47 100644 --- a/packages/matter.js/src/forwards/behaviors/illuminance-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/illuminance-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/index.ts b/packages/matter.js/src/forwards/behaviors/index.ts index 366b1eaba9..fa57e46ba4 100644 --- a/packages/matter.js/src/forwards/behaviors/index.ts +++ b/packages/matter.js/src/forwards/behaviors/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/joint-fabric-datastore-cluster.ts b/packages/matter.js/src/forwards/behaviors/joint-fabric-datastore-cluster.ts new file mode 100644 index 0000000000..9ed79ae3ab --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/joint-fabric-datastore-cluster.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/joint-fabric-datastore-cluster"; diff --git a/packages/matter.js/src/forwards/behaviors/joint-fabric-pki.ts b/packages/matter.js/src/forwards/behaviors/joint-fabric-pki.ts new file mode 100644 index 0000000000..1273d32aa7 --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/joint-fabric-pki.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/joint-fabric-pki"; diff --git a/packages/matter.js/src/forwards/behaviors/keypad-input.ts b/packages/matter.js/src/forwards/behaviors/keypad-input.ts index 1051f12a29..71aa6725ac 100644 --- a/packages/matter.js/src/forwards/behaviors/keypad-input.ts +++ b/packages/matter.js/src/forwards/behaviors/keypad-input.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/label.ts b/packages/matter.js/src/forwards/behaviors/label.ts index 480cd55fed..2ad972994a 100644 --- a/packages/matter.js/src/forwards/behaviors/label.ts +++ b/packages/matter.js/src/forwards/behaviors/label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/laundry-dryer-controls.ts b/packages/matter.js/src/forwards/behaviors/laundry-dryer-controls.ts index 2d2e1e2e4d..b9b59061e1 100644 --- a/packages/matter.js/src/forwards/behaviors/laundry-dryer-controls.ts +++ b/packages/matter.js/src/forwards/behaviors/laundry-dryer-controls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/laundry-washer-controls.ts b/packages/matter.js/src/forwards/behaviors/laundry-washer-controls.ts index 3928ce9703..504949adc4 100644 --- a/packages/matter.js/src/forwards/behaviors/laundry-washer-controls.ts +++ b/packages/matter.js/src/forwards/behaviors/laundry-washer-controls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/laundry-washer-mode.ts b/packages/matter.js/src/forwards/behaviors/laundry-washer-mode.ts index 1bd6d7c380..da9e4ab430 100644 --- a/packages/matter.js/src/forwards/behaviors/laundry-washer-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/laundry-washer-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/level-control.ts b/packages/matter.js/src/forwards/behaviors/level-control.ts index a1bab6d351..0b0e635e51 100644 --- a/packages/matter.js/src/forwards/behaviors/level-control.ts +++ b/packages/matter.js/src/forwards/behaviors/level-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/localization-configuration.ts b/packages/matter.js/src/forwards/behaviors/localization-configuration.ts index 3affaabb99..bbb78bec7c 100644 --- a/packages/matter.js/src/forwards/behaviors/localization-configuration.ts +++ b/packages/matter.js/src/forwards/behaviors/localization-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/low-power.ts b/packages/matter.js/src/forwards/behaviors/low-power.ts index 4ec098a878..1b8bea3236 100644 --- a/packages/matter.js/src/forwards/behaviors/low-power.ts +++ b/packages/matter.js/src/forwards/behaviors/low-power.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/media-input.ts b/packages/matter.js/src/forwards/behaviors/media-input.ts index 66fd0ace02..62905eb700 100644 --- a/packages/matter.js/src/forwards/behaviors/media-input.ts +++ b/packages/matter.js/src/forwards/behaviors/media-input.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/media-playback.ts b/packages/matter.js/src/forwards/behaviors/media-playback.ts index 547b9245b2..907a6a3144 100644 --- a/packages/matter.js/src/forwards/behaviors/media-playback.ts +++ b/packages/matter.js/src/forwards/behaviors/media-playback.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/messages.ts b/packages/matter.js/src/forwards/behaviors/messages.ts index fa8f7b02fe..b390c44d06 100644 --- a/packages/matter.js/src/forwards/behaviors/messages.ts +++ b/packages/matter.js/src/forwards/behaviors/messages.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/microwave-oven-control.ts b/packages/matter.js/src/forwards/behaviors/microwave-oven-control.ts index 705dbeac72..490ac5eb63 100644 --- a/packages/matter.js/src/forwards/behaviors/microwave-oven-control.ts +++ b/packages/matter.js/src/forwards/behaviors/microwave-oven-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/microwave-oven-mode.ts b/packages/matter.js/src/forwards/behaviors/microwave-oven-mode.ts index 0a05568fa8..67415f7f3d 100644 --- a/packages/matter.js/src/forwards/behaviors/microwave-oven-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/microwave-oven-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/mode-base.ts b/packages/matter.js/src/forwards/behaviors/mode-base.ts index 5716c98b00..0b5978af8b 100644 --- a/packages/matter.js/src/forwards/behaviors/mode-base.ts +++ b/packages/matter.js/src/forwards/behaviors/mode-base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/mode-select.ts b/packages/matter.js/src/forwards/behaviors/mode-select.ts index 2cb80d4230..62a866b1f7 100644 --- a/packages/matter.js/src/forwards/behaviors/mode-select.ts +++ b/packages/matter.js/src/forwards/behaviors/mode-select.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/network-commissioning.ts b/packages/matter.js/src/forwards/behaviors/network-commissioning.ts index d7ba6c324c..dddaf8c2ab 100644 --- a/packages/matter.js/src/forwards/behaviors/network-commissioning.ts +++ b/packages/matter.js/src/forwards/behaviors/network-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/nitrogen-dioxide-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/nitrogen-dioxide-concentration-measurement.ts index 7a6b36cc5f..9eb149d8e4 100644 --- a/packages/matter.js/src/forwards/behaviors/nitrogen-dioxide-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/nitrogen-dioxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/occupancy-sensing.ts b/packages/matter.js/src/forwards/behaviors/occupancy-sensing.ts index 951727bdaf..1d81d0f568 100644 --- a/packages/matter.js/src/forwards/behaviors/occupancy-sensing.ts +++ b/packages/matter.js/src/forwards/behaviors/occupancy-sensing.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/on-off.ts b/packages/matter.js/src/forwards/behaviors/on-off.ts index 44d14433fd..b24bf83d66 100644 --- a/packages/matter.js/src/forwards/behaviors/on-off.ts +++ b/packages/matter.js/src/forwards/behaviors/on-off.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/operational-credentials.ts b/packages/matter.js/src/forwards/behaviors/operational-credentials.ts index f429c3c735..fda413d194 100644 --- a/packages/matter.js/src/forwards/behaviors/operational-credentials.ts +++ b/packages/matter.js/src/forwards/behaviors/operational-credentials.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/operational-state.ts b/packages/matter.js/src/forwards/behaviors/operational-state.ts index 194a86a592..ddef6c2af7 100644 --- a/packages/matter.js/src/forwards/behaviors/operational-state.ts +++ b/packages/matter.js/src/forwards/behaviors/operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/ota-software-update-provider.ts b/packages/matter.js/src/forwards/behaviors/ota-software-update-provider.ts index c38e4e00b8..ff449effe8 100644 --- a/packages/matter.js/src/forwards/behaviors/ota-software-update-provider.ts +++ b/packages/matter.js/src/forwards/behaviors/ota-software-update-provider.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/ota-software-update-requestor.ts b/packages/matter.js/src/forwards/behaviors/ota-software-update-requestor.ts index 40511dcaea..ed6e1e775f 100644 --- a/packages/matter.js/src/forwards/behaviors/ota-software-update-requestor.ts +++ b/packages/matter.js/src/forwards/behaviors/ota-software-update-requestor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/oven-cavity-operational-state.ts b/packages/matter.js/src/forwards/behaviors/oven-cavity-operational-state.ts index 29842a0d16..575c2ac3cd 100644 --- a/packages/matter.js/src/forwards/behaviors/oven-cavity-operational-state.ts +++ b/packages/matter.js/src/forwards/behaviors/oven-cavity-operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/oven-mode.ts b/packages/matter.js/src/forwards/behaviors/oven-mode.ts index 41c22b17e2..098087233f 100644 --- a/packages/matter.js/src/forwards/behaviors/oven-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/oven-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/ozone-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/ozone-concentration-measurement.ts index 09184c2d60..39bf09573b 100644 --- a/packages/matter.js/src/forwards/behaviors/ozone-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/ozone-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/pm1-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/pm1-concentration-measurement.ts index 3f0d69bec1..0cda7a9299 100644 --- a/packages/matter.js/src/forwards/behaviors/pm1-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/pm1-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/pm10-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/pm10-concentration-measurement.ts index c03904375a..d2aa15b1f6 100644 --- a/packages/matter.js/src/forwards/behaviors/pm10-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/pm10-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/pm25-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/pm25-concentration-measurement.ts index 17476b9316..2d13b91954 100644 --- a/packages/matter.js/src/forwards/behaviors/pm25-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/pm25-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/power-source-configuration.ts b/packages/matter.js/src/forwards/behaviors/power-source-configuration.ts index 9284bb6d41..de36344afc 100644 --- a/packages/matter.js/src/forwards/behaviors/power-source-configuration.ts +++ b/packages/matter.js/src/forwards/behaviors/power-source-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/power-source.ts b/packages/matter.js/src/forwards/behaviors/power-source.ts index 22426de21d..74e466f205 100644 --- a/packages/matter.js/src/forwards/behaviors/power-source.ts +++ b/packages/matter.js/src/forwards/behaviors/power-source.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/power-topology.ts b/packages/matter.js/src/forwards/behaviors/power-topology.ts index ce10490fe1..3dd3cc6a53 100644 --- a/packages/matter.js/src/forwards/behaviors/power-topology.ts +++ b/packages/matter.js/src/forwards/behaviors/power-topology.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/pressure-measurement.ts b/packages/matter.js/src/forwards/behaviors/pressure-measurement.ts index 90d995e986..6568c1daa9 100644 --- a/packages/matter.js/src/forwards/behaviors/pressure-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/pressure-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/proxy-configuration.ts b/packages/matter.js/src/forwards/behaviors/proxy-configuration.ts index aec858bdee..29d2c1f819 100644 --- a/packages/matter.js/src/forwards/behaviors/proxy-configuration.ts +++ b/packages/matter.js/src/forwards/behaviors/proxy-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/proxy-discovery.ts b/packages/matter.js/src/forwards/behaviors/proxy-discovery.ts index 0d92f4765f..26cb43bcd4 100644 --- a/packages/matter.js/src/forwards/behaviors/proxy-discovery.ts +++ b/packages/matter.js/src/forwards/behaviors/proxy-discovery.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/pump-configuration-and-control.ts b/packages/matter.js/src/forwards/behaviors/pump-configuration-and-control.ts index 5e5f3a1e4d..6d7e218b3d 100644 --- a/packages/matter.js/src/forwards/behaviors/pump-configuration-and-control.ts +++ b/packages/matter.js/src/forwards/behaviors/pump-configuration-and-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/radon-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/radon-concentration-measurement.ts index 8b5c052ec6..b3f5039f67 100644 --- a/packages/matter.js/src/forwards/behaviors/radon-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/radon-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/refrigerator-alarm.ts b/packages/matter.js/src/forwards/behaviors/refrigerator-alarm.ts index aac8cc893c..aa07358e17 100644 --- a/packages/matter.js/src/forwards/behaviors/refrigerator-alarm.ts +++ b/packages/matter.js/src/forwards/behaviors/refrigerator-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/refrigerator-and-temperature-controlled-cabinet-mode.ts b/packages/matter.js/src/forwards/behaviors/refrigerator-and-temperature-controlled-cabinet-mode.ts index 865e3aaaa6..b293739bcb 100644 --- a/packages/matter.js/src/forwards/behaviors/refrigerator-and-temperature-controlled-cabinet-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/refrigerator-and-temperature-controlled-cabinet-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/relative-humidity-measurement.ts b/packages/matter.js/src/forwards/behaviors/relative-humidity-measurement.ts index 70d89c04a3..a231277a1a 100644 --- a/packages/matter.js/src/forwards/behaviors/relative-humidity-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/relative-humidity-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/resource-monitoring.ts b/packages/matter.js/src/forwards/behaviors/resource-monitoring.ts index b916feee45..2d6cdd30cc 100644 --- a/packages/matter.js/src/forwards/behaviors/resource-monitoring.ts +++ b/packages/matter.js/src/forwards/behaviors/resource-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/rvc-clean-mode.ts b/packages/matter.js/src/forwards/behaviors/rvc-clean-mode.ts index 3e6efff342..386ad9df25 100644 --- a/packages/matter.js/src/forwards/behaviors/rvc-clean-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/rvc-clean-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/rvc-operational-state.ts b/packages/matter.js/src/forwards/behaviors/rvc-operational-state.ts index 8fe4b2c5ee..2233af32c5 100644 --- a/packages/matter.js/src/forwards/behaviors/rvc-operational-state.ts +++ b/packages/matter.js/src/forwards/behaviors/rvc-operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/rvc-run-mode.ts b/packages/matter.js/src/forwards/behaviors/rvc-run-mode.ts index fe746bcb84..b9e91c4de5 100644 --- a/packages/matter.js/src/forwards/behaviors/rvc-run-mode.ts +++ b/packages/matter.js/src/forwards/behaviors/rvc-run-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/scenes-management.ts b/packages/matter.js/src/forwards/behaviors/scenes-management.ts index 51a42ba73a..c054e685ed 100644 --- a/packages/matter.js/src/forwards/behaviors/scenes-management.ts +++ b/packages/matter.js/src/forwards/behaviors/scenes-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/service-area.ts b/packages/matter.js/src/forwards/behaviors/service-area.ts new file mode 100644 index 0000000000..6afd8dbcc5 --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/service-area.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/service-area"; diff --git a/packages/matter.js/src/forwards/behaviors/smoke-co-alarm.ts b/packages/matter.js/src/forwards/behaviors/smoke-co-alarm.ts index 30d869886a..41e3b43b05 100644 --- a/packages/matter.js/src/forwards/behaviors/smoke-co-alarm.ts +++ b/packages/matter.js/src/forwards/behaviors/smoke-co-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/software-diagnostics.ts b/packages/matter.js/src/forwards/behaviors/software-diagnostics.ts index e0afe52b24..c18cb4589a 100644 --- a/packages/matter.js/src/forwards/behaviors/software-diagnostics.ts +++ b/packages/matter.js/src/forwards/behaviors/software-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/switch.ts b/packages/matter.js/src/forwards/behaviors/switch.ts index c823902051..7e22b3df3b 100644 --- a/packages/matter.js/src/forwards/behaviors/switch.ts +++ b/packages/matter.js/src/forwards/behaviors/switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/target-navigator.ts b/packages/matter.js/src/forwards/behaviors/target-navigator.ts index 990e7b1d17..d5f58bc14f 100644 --- a/packages/matter.js/src/forwards/behaviors/target-navigator.ts +++ b/packages/matter.js/src/forwards/behaviors/target-navigator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/temperature-control.ts b/packages/matter.js/src/forwards/behaviors/temperature-control.ts index 7efdcace5c..eccab7b7de 100644 --- a/packages/matter.js/src/forwards/behaviors/temperature-control.ts +++ b/packages/matter.js/src/forwards/behaviors/temperature-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/temperature-measurement.ts b/packages/matter.js/src/forwards/behaviors/temperature-measurement.ts index 15f2ba7940..d3e4a0edc0 100644 --- a/packages/matter.js/src/forwards/behaviors/temperature-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/temperature-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/thermostat-user-interface-configuration.ts b/packages/matter.js/src/forwards/behaviors/thermostat-user-interface-configuration.ts index d66c9a421f..1ae1c2c7fc 100644 --- a/packages/matter.js/src/forwards/behaviors/thermostat-user-interface-configuration.ts +++ b/packages/matter.js/src/forwards/behaviors/thermostat-user-interface-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/thermostat.ts b/packages/matter.js/src/forwards/behaviors/thermostat.ts index 96d67a8551..de91c299e0 100644 --- a/packages/matter.js/src/forwards/behaviors/thermostat.ts +++ b/packages/matter.js/src/forwards/behaviors/thermostat.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/thread-border-router-management.ts b/packages/matter.js/src/forwards/behaviors/thread-border-router-management.ts new file mode 100644 index 0000000000..e536ec1a72 --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/thread-border-router-management.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/thread-border-router-management"; diff --git a/packages/matter.js/src/forwards/behaviors/thread-network-diagnostics.ts b/packages/matter.js/src/forwards/behaviors/thread-network-diagnostics.ts index 3b1dc24e22..8f367d9286 100644 --- a/packages/matter.js/src/forwards/behaviors/thread-network-diagnostics.ts +++ b/packages/matter.js/src/forwards/behaviors/thread-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/thread-network-directory.ts b/packages/matter.js/src/forwards/behaviors/thread-network-directory.ts new file mode 100644 index 0000000000..580f7048e4 --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/thread-network-directory.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/thread-network-directory"; diff --git a/packages/matter.js/src/forwards/behaviors/time-format-localization.ts b/packages/matter.js/src/forwards/behaviors/time-format-localization.ts index b8e5456de5..7a64ef27ac 100644 --- a/packages/matter.js/src/forwards/behaviors/time-format-localization.ts +++ b/packages/matter.js/src/forwards/behaviors/time-format-localization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/time-synchronization.ts b/packages/matter.js/src/forwards/behaviors/time-synchronization.ts index e00c9ca20b..7e5b9350db 100644 --- a/packages/matter.js/src/forwards/behaviors/time-synchronization.ts +++ b/packages/matter.js/src/forwards/behaviors/time-synchronization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/total-volatile-organic-compounds-concentration-measurement.ts b/packages/matter.js/src/forwards/behaviors/total-volatile-organic-compounds-concentration-measurement.ts index 237db8f85c..1da827dba8 100644 --- a/packages/matter.js/src/forwards/behaviors/total-volatile-organic-compounds-concentration-measurement.ts +++ b/packages/matter.js/src/forwards/behaviors/total-volatile-organic-compounds-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/unit-localization.ts b/packages/matter.js/src/forwards/behaviors/unit-localization.ts index 24d5616caf..52893da359 100644 --- a/packages/matter.js/src/forwards/behaviors/unit-localization.ts +++ b/packages/matter.js/src/forwards/behaviors/unit-localization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/user-label.ts b/packages/matter.js/src/forwards/behaviors/user-label.ts index b25ceed733..980fd828d0 100644 --- a/packages/matter.js/src/forwards/behaviors/user-label.ts +++ b/packages/matter.js/src/forwards/behaviors/user-label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/valid-proxies.ts b/packages/matter.js/src/forwards/behaviors/valid-proxies.ts index ede118e73f..3c6ff8d797 100644 --- a/packages/matter.js/src/forwards/behaviors/valid-proxies.ts +++ b/packages/matter.js/src/forwards/behaviors/valid-proxies.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/valve-configuration-and-control.ts b/packages/matter.js/src/forwards/behaviors/valve-configuration-and-control.ts index 6fbbe6650c..8498dd6514 100644 --- a/packages/matter.js/src/forwards/behaviors/valve-configuration-and-control.ts +++ b/packages/matter.js/src/forwards/behaviors/valve-configuration-and-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/wake-on-lan.ts b/packages/matter.js/src/forwards/behaviors/wake-on-lan.ts index 0c0d68b221..5bd84b5c48 100644 --- a/packages/matter.js/src/forwards/behaviors/wake-on-lan.ts +++ b/packages/matter.js/src/forwards/behaviors/wake-on-lan.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/water-heater-management.ts b/packages/matter.js/src/forwards/behaviors/water-heater-management.ts new file mode 100644 index 0000000000..5bd5fbd6ee --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/water-heater-management.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/water-heater-management"; diff --git a/packages/matter.js/src/forwards/behaviors/water-heater-mode.ts b/packages/matter.js/src/forwards/behaviors/water-heater-mode.ts new file mode 100644 index 0000000000..1181c05278 --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/water-heater-mode.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/water-heater-mode"; diff --git a/packages/matter.js/src/forwards/behaviors/water-tank-level-monitoring.ts b/packages/matter.js/src/forwards/behaviors/water-tank-level-monitoring.ts new file mode 100644 index 0000000000..c243519afd --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/water-tank-level-monitoring.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/water-tank-level-monitoring"; diff --git a/packages/matter.js/src/forwards/behaviors/wi-fi-network-diagnostics.ts b/packages/matter.js/src/forwards/behaviors/wi-fi-network-diagnostics.ts index 7a8f938d4f..49a394cf87 100644 --- a/packages/matter.js/src/forwards/behaviors/wi-fi-network-diagnostics.ts +++ b/packages/matter.js/src/forwards/behaviors/wi-fi-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/behaviors/wi-fi-network-management.ts b/packages/matter.js/src/forwards/behaviors/wi-fi-network-management.ts new file mode 100644 index 0000000000..6797214384 --- /dev/null +++ b/packages/matter.js/src/forwards/behaviors/wi-fi-network-management.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#behaviors/wi-fi-network-management"; diff --git a/packages/matter.js/src/forwards/behaviors/window-covering.ts b/packages/matter.js/src/forwards/behaviors/window-covering.ts index ec37a6c875..148e880a13 100644 --- a/packages/matter.js/src/forwards/behaviors/window-covering.ts +++ b/packages/matter.js/src/forwards/behaviors/window-covering.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/AirPurifierDevice.ts b/packages/matter.js/src/forwards/devices/AirPurifierDevice.ts index c997f21b18..2bd6f04bd4 100644 --- a/packages/matter.js/src/forwards/devices/AirPurifierDevice.ts +++ b/packages/matter.js/src/forwards/devices/AirPurifierDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/AirQualitySensorDevice.ts b/packages/matter.js/src/forwards/devices/AirQualitySensorDevice.ts index 8663804934..d161ecd5df 100644 --- a/packages/matter.js/src/forwards/devices/AirQualitySensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/AirQualitySensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/BasicVideoPlayerDevice.ts b/packages/matter.js/src/forwards/devices/BasicVideoPlayerDevice.ts index 9676c019bd..d76d5f2665 100644 --- a/packages/matter.js/src/forwards/devices/BasicVideoPlayerDevice.ts +++ b/packages/matter.js/src/forwards/devices/BasicVideoPlayerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/BatteryStorageDevice.ts b/packages/matter.js/src/forwards/devices/BatteryStorageDevice.ts new file mode 100644 index 0000000000..4f493e0f3b --- /dev/null +++ b/packages/matter.js/src/forwards/devices/BatteryStorageDevice.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#devices/battery-storage"; diff --git a/packages/matter.js/src/forwards/devices/CastingVideoClientDevice.ts b/packages/matter.js/src/forwards/devices/CastingVideoClientDevice.ts index fe3d38ebb6..68e7fec8a1 100644 --- a/packages/matter.js/src/forwards/devices/CastingVideoClientDevice.ts +++ b/packages/matter.js/src/forwards/devices/CastingVideoClientDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/CastingVideoPlayerDevice.ts b/packages/matter.js/src/forwards/devices/CastingVideoPlayerDevice.ts index 9547d040d6..f725141515 100644 --- a/packages/matter.js/src/forwards/devices/CastingVideoPlayerDevice.ts +++ b/packages/matter.js/src/forwards/devices/CastingVideoPlayerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/ColorDimmerSwitchDevice.ts b/packages/matter.js/src/forwards/devices/ColorDimmerSwitchDevice.ts index 1d467f473f..c503b6a7df 100644 --- a/packages/matter.js/src/forwards/devices/ColorDimmerSwitchDevice.ts +++ b/packages/matter.js/src/forwards/devices/ColorDimmerSwitchDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/ColorTemperatureLightDevice.ts b/packages/matter.js/src/forwards/devices/ColorTemperatureLightDevice.ts index b1f88a92ef..04e1345c66 100644 --- a/packages/matter.js/src/forwards/devices/ColorTemperatureLightDevice.ts +++ b/packages/matter.js/src/forwards/devices/ColorTemperatureLightDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/ContactSensorDevice.ts b/packages/matter.js/src/forwards/devices/ContactSensorDevice.ts index 1e274004bd..d5ac8f08eb 100644 --- a/packages/matter.js/src/forwards/devices/ContactSensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/ContactSensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/ContentAppDevice.ts b/packages/matter.js/src/forwards/devices/ContentAppDevice.ts index e8b004f59d..f56de3650a 100644 --- a/packages/matter.js/src/forwards/devices/ContentAppDevice.ts +++ b/packages/matter.js/src/forwards/devices/ContentAppDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/ControlBridgeDevice.ts b/packages/matter.js/src/forwards/devices/ControlBridgeDevice.ts index 8d919c6a8c..bc0df05038 100644 --- a/packages/matter.js/src/forwards/devices/ControlBridgeDevice.ts +++ b/packages/matter.js/src/forwards/devices/ControlBridgeDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/CookSurfaceDevice.ts b/packages/matter.js/src/forwards/devices/CookSurfaceDevice.ts index 20ff310c7b..1b4259b03b 100644 --- a/packages/matter.js/src/forwards/devices/CookSurfaceDevice.ts +++ b/packages/matter.js/src/forwards/devices/CookSurfaceDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/CooktopDevice.ts b/packages/matter.js/src/forwards/devices/CooktopDevice.ts index f00d7f1609..b62404b5e4 100644 --- a/packages/matter.js/src/forwards/devices/CooktopDevice.ts +++ b/packages/matter.js/src/forwards/devices/CooktopDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/DimmableLightDevice.ts b/packages/matter.js/src/forwards/devices/DimmableLightDevice.ts index f1d332a42d..b2b9da721f 100644 --- a/packages/matter.js/src/forwards/devices/DimmableLightDevice.ts +++ b/packages/matter.js/src/forwards/devices/DimmableLightDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/DimmablePlugInUnitDevice.ts b/packages/matter.js/src/forwards/devices/DimmablePlugInUnitDevice.ts index 80c09225da..d81c2f7268 100644 --- a/packages/matter.js/src/forwards/devices/DimmablePlugInUnitDevice.ts +++ b/packages/matter.js/src/forwards/devices/DimmablePlugInUnitDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/DimmerSwitchDevice.ts b/packages/matter.js/src/forwards/devices/DimmerSwitchDevice.ts index a4716bacd3..8cd21c3a28 100644 --- a/packages/matter.js/src/forwards/devices/DimmerSwitchDevice.ts +++ b/packages/matter.js/src/forwards/devices/DimmerSwitchDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/DishwasherDevice.ts b/packages/matter.js/src/forwards/devices/DishwasherDevice.ts index f954f7681a..bb9077bc2d 100644 --- a/packages/matter.js/src/forwards/devices/DishwasherDevice.ts +++ b/packages/matter.js/src/forwards/devices/DishwasherDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/DoorLockControllerDevice.ts b/packages/matter.js/src/forwards/devices/DoorLockControllerDevice.ts index 3a3dd854d0..b7a9cf40db 100644 --- a/packages/matter.js/src/forwards/devices/DoorLockControllerDevice.ts +++ b/packages/matter.js/src/forwards/devices/DoorLockControllerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/DoorLockDevice.ts b/packages/matter.js/src/forwards/devices/DoorLockDevice.ts index 5eb582a52c..cb0f3c031d 100644 --- a/packages/matter.js/src/forwards/devices/DoorLockDevice.ts +++ b/packages/matter.js/src/forwards/devices/DoorLockDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/EnergyEvseDevice.ts b/packages/matter.js/src/forwards/devices/EnergyEvseDevice.ts new file mode 100644 index 0000000000..e605a8f645 --- /dev/null +++ b/packages/matter.js/src/forwards/devices/EnergyEvseDevice.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#devices/energy-evse"; diff --git a/packages/matter.js/src/forwards/devices/ExtendedColorLightDevice.ts b/packages/matter.js/src/forwards/devices/ExtendedColorLightDevice.ts index 1cb142c4e2..cdef0c290b 100644 --- a/packages/matter.js/src/forwards/devices/ExtendedColorLightDevice.ts +++ b/packages/matter.js/src/forwards/devices/ExtendedColorLightDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/ExtractorHoodDevice.ts b/packages/matter.js/src/forwards/devices/ExtractorHoodDevice.ts index 5ca6095b7d..9e11708092 100644 --- a/packages/matter.js/src/forwards/devices/ExtractorHoodDevice.ts +++ b/packages/matter.js/src/forwards/devices/ExtractorHoodDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/FanDevice.ts b/packages/matter.js/src/forwards/devices/FanDevice.ts index e416f4799d..5470b75e57 100644 --- a/packages/matter.js/src/forwards/devices/FanDevice.ts +++ b/packages/matter.js/src/forwards/devices/FanDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/FlowSensorDevice.ts b/packages/matter.js/src/forwards/devices/FlowSensorDevice.ts index d7d4d74d81..f6b1fcc02b 100644 --- a/packages/matter.js/src/forwards/devices/FlowSensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/FlowSensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/GenericSwitchDevice.ts b/packages/matter.js/src/forwards/devices/GenericSwitchDevice.ts index 6e30c772bb..62cb74ee5d 100644 --- a/packages/matter.js/src/forwards/devices/GenericSwitchDevice.ts +++ b/packages/matter.js/src/forwards/devices/GenericSwitchDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/HeatPumpDevice.ts b/packages/matter.js/src/forwards/devices/HeatPumpDevice.ts new file mode 100644 index 0000000000..d3f0c72d42 --- /dev/null +++ b/packages/matter.js/src/forwards/devices/HeatPumpDevice.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#devices/heat-pump"; diff --git a/packages/matter.js/src/forwards/devices/HumiditySensorDevice.ts b/packages/matter.js/src/forwards/devices/HumiditySensorDevice.ts index 20c3428006..f669c0722f 100644 --- a/packages/matter.js/src/forwards/devices/HumiditySensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/HumiditySensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/IndexDevice.ts b/packages/matter.js/src/forwards/devices/IndexDevice.ts index c88289d331..70f7eb7107 100644 --- a/packages/matter.js/src/forwards/devices/IndexDevice.ts +++ b/packages/matter.js/src/forwards/devices/IndexDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/LaundryDryerDevice.ts b/packages/matter.js/src/forwards/devices/LaundryDryerDevice.ts index 7b980c3c00..14c7f65906 100644 --- a/packages/matter.js/src/forwards/devices/LaundryDryerDevice.ts +++ b/packages/matter.js/src/forwards/devices/LaundryDryerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/LaundryWasherDevice.ts b/packages/matter.js/src/forwards/devices/LaundryWasherDevice.ts index 1738bd3b17..34af5543d9 100644 --- a/packages/matter.js/src/forwards/devices/LaundryWasherDevice.ts +++ b/packages/matter.js/src/forwards/devices/LaundryWasherDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/LightSensorDevice.ts b/packages/matter.js/src/forwards/devices/LightSensorDevice.ts index 36e3dc7d96..d8afdec700 100644 --- a/packages/matter.js/src/forwards/devices/LightSensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/LightSensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/MicrowaveOvenDevice.ts b/packages/matter.js/src/forwards/devices/MicrowaveOvenDevice.ts index 5f64b9d4dd..a38c9b3323 100644 --- a/packages/matter.js/src/forwards/devices/MicrowaveOvenDevice.ts +++ b/packages/matter.js/src/forwards/devices/MicrowaveOvenDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/ModeSelectDevice.ts b/packages/matter.js/src/forwards/devices/ModeSelectDevice.ts index edcb84b662..97c629351b 100644 --- a/packages/matter.js/src/forwards/devices/ModeSelectDevice.ts +++ b/packages/matter.js/src/forwards/devices/ModeSelectDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/MountedDimmableLoadControlDevice.ts b/packages/matter.js/src/forwards/devices/MountedDimmableLoadControlDevice.ts new file mode 100644 index 0000000000..b176f4a1b0 --- /dev/null +++ b/packages/matter.js/src/forwards/devices/MountedDimmableLoadControlDevice.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#devices/mounted-dimmable-load-control"; diff --git a/packages/matter.js/src/forwards/devices/MountedOnOffControlDevice.ts b/packages/matter.js/src/forwards/devices/MountedOnOffControlDevice.ts new file mode 100644 index 0000000000..3c83687398 --- /dev/null +++ b/packages/matter.js/src/forwards/devices/MountedOnOffControlDevice.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#devices/mounted-on-off-control"; diff --git a/packages/matter.js/src/forwards/devices/NetworkInfrastructureManagerDevice.ts b/packages/matter.js/src/forwards/devices/NetworkInfrastructureManagerDevice.ts new file mode 100644 index 0000000000..849833a7c8 --- /dev/null +++ b/packages/matter.js/src/forwards/devices/NetworkInfrastructureManagerDevice.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#devices/network-infrastructure-manager"; diff --git a/packages/matter.js/src/forwards/devices/OccupancySensorDevice.ts b/packages/matter.js/src/forwards/devices/OccupancySensorDevice.ts index 234dbf4c64..1f732db3a7 100644 --- a/packages/matter.js/src/forwards/devices/OccupancySensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/OccupancySensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/OnOffLightDevice.ts b/packages/matter.js/src/forwards/devices/OnOffLightDevice.ts index 34b9d9a903..4ffe9c7b5b 100644 --- a/packages/matter.js/src/forwards/devices/OnOffLightDevice.ts +++ b/packages/matter.js/src/forwards/devices/OnOffLightDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/OnOffLightSwitchDevice.ts b/packages/matter.js/src/forwards/devices/OnOffLightSwitchDevice.ts index c1d2020e39..0a93fe64a8 100644 --- a/packages/matter.js/src/forwards/devices/OnOffLightSwitchDevice.ts +++ b/packages/matter.js/src/forwards/devices/OnOffLightSwitchDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/OnOffPlugInUnitDevice.ts b/packages/matter.js/src/forwards/devices/OnOffPlugInUnitDevice.ts index f2b5c2aa26..3f17fd09c8 100644 --- a/packages/matter.js/src/forwards/devices/OnOffPlugInUnitDevice.ts +++ b/packages/matter.js/src/forwards/devices/OnOffPlugInUnitDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/OnOffSensorDevice.ts b/packages/matter.js/src/forwards/devices/OnOffSensorDevice.ts index c1325b4f2c..03c9d81295 100644 --- a/packages/matter.js/src/forwards/devices/OnOffSensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/OnOffSensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/OvenDevice.ts b/packages/matter.js/src/forwards/devices/OvenDevice.ts index 48d49e3324..365387aa1c 100644 --- a/packages/matter.js/src/forwards/devices/OvenDevice.ts +++ b/packages/matter.js/src/forwards/devices/OvenDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/PressureSensorDevice.ts b/packages/matter.js/src/forwards/devices/PressureSensorDevice.ts index 1b9d08f3ac..4d2e689534 100644 --- a/packages/matter.js/src/forwards/devices/PressureSensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/PressureSensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/PumpControllerDevice.ts b/packages/matter.js/src/forwards/devices/PumpControllerDevice.ts index b250e4bdd9..58eb21250b 100644 --- a/packages/matter.js/src/forwards/devices/PumpControllerDevice.ts +++ b/packages/matter.js/src/forwards/devices/PumpControllerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/PumpDevice.ts b/packages/matter.js/src/forwards/devices/PumpDevice.ts index 39850e452c..00d84cf146 100644 --- a/packages/matter.js/src/forwards/devices/PumpDevice.ts +++ b/packages/matter.js/src/forwards/devices/PumpDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/RainSensorDevice.ts b/packages/matter.js/src/forwards/devices/RainSensorDevice.ts index 2e7efbe8b9..af104c926e 100644 --- a/packages/matter.js/src/forwards/devices/RainSensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/RainSensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/RefrigeratorDevice.ts b/packages/matter.js/src/forwards/devices/RefrigeratorDevice.ts index 162459657d..7863b86868 100644 --- a/packages/matter.js/src/forwards/devices/RefrigeratorDevice.ts +++ b/packages/matter.js/src/forwards/devices/RefrigeratorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/RoboticVacuumCleanerDevice.ts b/packages/matter.js/src/forwards/devices/RoboticVacuumCleanerDevice.ts index cf0e91730e..ea1686b692 100644 --- a/packages/matter.js/src/forwards/devices/RoboticVacuumCleanerDevice.ts +++ b/packages/matter.js/src/forwards/devices/RoboticVacuumCleanerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/RoomAirConditionerDevice.ts b/packages/matter.js/src/forwards/devices/RoomAirConditionerDevice.ts index a973c68e96..4122ef0835 100644 --- a/packages/matter.js/src/forwards/devices/RoomAirConditionerDevice.ts +++ b/packages/matter.js/src/forwards/devices/RoomAirConditionerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/SmokeCoAlarmDevice.ts b/packages/matter.js/src/forwards/devices/SmokeCoAlarmDevice.ts index aae7723d17..6d35697ed2 100644 --- a/packages/matter.js/src/forwards/devices/SmokeCoAlarmDevice.ts +++ b/packages/matter.js/src/forwards/devices/SmokeCoAlarmDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/SolarPowerDevice.ts b/packages/matter.js/src/forwards/devices/SolarPowerDevice.ts new file mode 100644 index 0000000000..19a0f79a4a --- /dev/null +++ b/packages/matter.js/src/forwards/devices/SolarPowerDevice.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#devices/solar-power"; diff --git a/packages/matter.js/src/forwards/devices/SpeakerDevice.ts b/packages/matter.js/src/forwards/devices/SpeakerDevice.ts index aeb60d4cfb..953eb91488 100644 --- a/packages/matter.js/src/forwards/devices/SpeakerDevice.ts +++ b/packages/matter.js/src/forwards/devices/SpeakerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/TemperatureControlledCabinetDevice.ts b/packages/matter.js/src/forwards/devices/TemperatureControlledCabinetDevice.ts index 7fb39053bf..5844ea7f91 100644 --- a/packages/matter.js/src/forwards/devices/TemperatureControlledCabinetDevice.ts +++ b/packages/matter.js/src/forwards/devices/TemperatureControlledCabinetDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/TemperatureSensorDevice.ts b/packages/matter.js/src/forwards/devices/TemperatureSensorDevice.ts index b5574c2dc0..688a8cefe4 100644 --- a/packages/matter.js/src/forwards/devices/TemperatureSensorDevice.ts +++ b/packages/matter.js/src/forwards/devices/TemperatureSensorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/ThermostatDevice.ts b/packages/matter.js/src/forwards/devices/ThermostatDevice.ts index 31e3c30233..03ecc55d1e 100644 --- a/packages/matter.js/src/forwards/devices/ThermostatDevice.ts +++ b/packages/matter.js/src/forwards/devices/ThermostatDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/VideoRemoteControlDevice.ts b/packages/matter.js/src/forwards/devices/VideoRemoteControlDevice.ts index 41ee3899ff..8eba226b68 100644 --- a/packages/matter.js/src/forwards/devices/VideoRemoteControlDevice.ts +++ b/packages/matter.js/src/forwards/devices/VideoRemoteControlDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/WaterFreezeDetectorDevice.ts b/packages/matter.js/src/forwards/devices/WaterFreezeDetectorDevice.ts index 3983f3b1fa..6940c7aebe 100644 --- a/packages/matter.js/src/forwards/devices/WaterFreezeDetectorDevice.ts +++ b/packages/matter.js/src/forwards/devices/WaterFreezeDetectorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/WaterHeaterDevice.ts b/packages/matter.js/src/forwards/devices/WaterHeaterDevice.ts new file mode 100644 index 0000000000..ca2f870b71 --- /dev/null +++ b/packages/matter.js/src/forwards/devices/WaterHeaterDevice.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#devices/water-heater"; diff --git a/packages/matter.js/src/forwards/devices/WaterLeakDetectorDevice.ts b/packages/matter.js/src/forwards/devices/WaterLeakDetectorDevice.ts index 9d78c61a79..c9ac805847 100644 --- a/packages/matter.js/src/forwards/devices/WaterLeakDetectorDevice.ts +++ b/packages/matter.js/src/forwards/devices/WaterLeakDetectorDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/WaterValveDevice.ts b/packages/matter.js/src/forwards/devices/WaterValveDevice.ts index 4b072313a0..d19943af6f 100644 --- a/packages/matter.js/src/forwards/devices/WaterValveDevice.ts +++ b/packages/matter.js/src/forwards/devices/WaterValveDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/WindowCoveringControllerDevice.ts b/packages/matter.js/src/forwards/devices/WindowCoveringControllerDevice.ts index 4d88561cf7..5aa84c69f0 100644 --- a/packages/matter.js/src/forwards/devices/WindowCoveringControllerDevice.ts +++ b/packages/matter.js/src/forwards/devices/WindowCoveringControllerDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/WindowCoveringDevice.ts b/packages/matter.js/src/forwards/devices/WindowCoveringDevice.ts index 7d095d4553..0d5db34288 100644 --- a/packages/matter.js/src/forwards/devices/WindowCoveringDevice.ts +++ b/packages/matter.js/src/forwards/devices/WindowCoveringDevice.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/devices/index.ts b/packages/matter.js/src/forwards/devices/index.ts index 366b1eaba9..fa57e46ba4 100644 --- a/packages/matter.js/src/forwards/devices/index.ts +++ b/packages/matter.js/src/forwards/devices/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/AggregatorEndpoint.ts b/packages/matter.js/src/forwards/endpoints/AggregatorEndpoint.ts index 5a978e04e4..489e98c942 100644 --- a/packages/matter.js/src/forwards/endpoints/AggregatorEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/AggregatorEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/BaseEndpoint.ts b/packages/matter.js/src/forwards/endpoints/BaseEndpoint.ts index d9e1b2619f..a588eba6e6 100644 --- a/packages/matter.js/src/forwards/endpoints/BaseEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/BaseEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/BridgedNodeEndpoint.ts b/packages/matter.js/src/forwards/endpoints/BridgedNodeEndpoint.ts index c7e2b4f9d5..ef8bd82eb8 100644 --- a/packages/matter.js/src/forwards/endpoints/BridgedNodeEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/BridgedNodeEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/DeviceEnergyManagementEndpoint.ts b/packages/matter.js/src/forwards/endpoints/DeviceEnergyManagementEndpoint.ts index d7e0984bde..ad9e7c24db 100644 --- a/packages/matter.js/src/forwards/endpoints/DeviceEnergyManagementEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/DeviceEnergyManagementEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/ElectricalSensorEndpoint.ts b/packages/matter.js/src/forwards/endpoints/ElectricalSensorEndpoint.ts index 88a5a2f374..9ed3f15957 100644 --- a/packages/matter.js/src/forwards/endpoints/ElectricalSensorEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/ElectricalSensorEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/IndexEndpoint.ts b/packages/matter.js/src/forwards/endpoints/IndexEndpoint.ts index b4e2686f8e..3ab652c514 100644 --- a/packages/matter.js/src/forwards/endpoints/IndexEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/IndexEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/JointFabricAdministratorEndpoint.ts b/packages/matter.js/src/forwards/endpoints/JointFabricAdministratorEndpoint.ts new file mode 100644 index 0000000000..81e125dabe --- /dev/null +++ b/packages/matter.js/src/forwards/endpoints/JointFabricAdministratorEndpoint.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#endpoints/joint-fabric-administrator"; diff --git a/packages/matter.js/src/forwards/endpoints/OtaProviderEndpoint.ts b/packages/matter.js/src/forwards/endpoints/OtaProviderEndpoint.ts index 6019ded4cf..43fa0ff3c0 100644 --- a/packages/matter.js/src/forwards/endpoints/OtaProviderEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/OtaProviderEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/OtaRequestorEndpoint.ts b/packages/matter.js/src/forwards/endpoints/OtaRequestorEndpoint.ts index 03b4f72d68..1ed530bdd6 100644 --- a/packages/matter.js/src/forwards/endpoints/OtaRequestorEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/OtaRequestorEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/PowerSourceEndpoint.ts b/packages/matter.js/src/forwards/endpoints/PowerSourceEndpoint.ts index b1e1132711..b827ab730b 100644 --- a/packages/matter.js/src/forwards/endpoints/PowerSourceEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/PowerSourceEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/RootEndpoint.ts b/packages/matter.js/src/forwards/endpoints/RootEndpoint.ts index f3f3b1963f..522369dfc9 100644 --- a/packages/matter.js/src/forwards/endpoints/RootEndpoint.ts +++ b/packages/matter.js/src/forwards/endpoints/RootEndpoint.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/endpoints/SecondaryNetworkInterfaceEndpoint.ts b/packages/matter.js/src/forwards/endpoints/SecondaryNetworkInterfaceEndpoint.ts new file mode 100644 index 0000000000..ef7490e1c7 --- /dev/null +++ b/packages/matter.js/src/forwards/endpoints/SecondaryNetworkInterfaceEndpoint.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export * from "#endpoints/secondary-network-interface"; diff --git a/packages/matter.js/src/forwards/endpoints/index.ts b/packages/matter.js/src/forwards/endpoints/index.ts index 366b1eaba9..fa57e46ba4 100644 --- a/packages/matter.js/src/forwards/endpoints/index.ts +++ b/packages/matter.js/src/forwards/endpoints/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/AreaNamespaceTag.ts b/packages/matter.js/src/forwards/tags/AreaNamespaceTag.ts new file mode 100644 index 0000000000..1e03a0020e --- /dev/null +++ b/packages/matter.js/src/forwards/tags/AreaNamespaceTag.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export { AreaNamespaceTag } from "@matter/node"; diff --git a/packages/matter.js/src/forwards/tags/ClosureTag.ts b/packages/matter.js/src/forwards/tags/ClosureTag.ts index 0c001e2a53..ac49297789 100644 --- a/packages/matter.js/src/forwards/tags/ClosureTag.ts +++ b/packages/matter.js/src/forwards/tags/ClosureTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/CompassDirectionTag.ts b/packages/matter.js/src/forwards/tags/CompassDirectionTag.ts index 20376f6486..1892bbd4bd 100644 --- a/packages/matter.js/src/forwards/tags/CompassDirectionTag.ts +++ b/packages/matter.js/src/forwards/tags/CompassDirectionTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/CompassLocationTag.ts b/packages/matter.js/src/forwards/tags/CompassLocationTag.ts index 7ca270dd7c..a6d5cfaf3c 100644 --- a/packages/matter.js/src/forwards/tags/CompassLocationTag.ts +++ b/packages/matter.js/src/forwards/tags/CompassLocationTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/DirectionTag.ts b/packages/matter.js/src/forwards/tags/DirectionTag.ts index 66ead5d1e9..c2ed236381 100644 --- a/packages/matter.js/src/forwards/tags/DirectionTag.ts +++ b/packages/matter.js/src/forwards/tags/DirectionTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/ElectricalMeasurementTag.ts b/packages/matter.js/src/forwards/tags/ElectricalMeasurementTag.ts index a40a5775ca..df2366e9f9 100644 --- a/packages/matter.js/src/forwards/tags/ElectricalMeasurementTag.ts +++ b/packages/matter.js/src/forwards/tags/ElectricalMeasurementTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/LandmarkNamespaceTag.ts b/packages/matter.js/src/forwards/tags/LandmarkNamespaceTag.ts new file mode 100644 index 0000000000..3694de1f5c --- /dev/null +++ b/packages/matter.js/src/forwards/tags/LandmarkNamespaceTag.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export { LandmarkNamespaceTag } from "@matter/node"; diff --git a/packages/matter.js/src/forwards/tags/LaundryTag.ts b/packages/matter.js/src/forwards/tags/LaundryTag.ts index 19ad4f1e8b..4f21c16b80 100644 --- a/packages/matter.js/src/forwards/tags/LaundryTag.ts +++ b/packages/matter.js/src/forwards/tags/LaundryTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/LevelTag.ts b/packages/matter.js/src/forwards/tags/LevelTag.ts index e53d53ae2b..f96617afa8 100644 --- a/packages/matter.js/src/forwards/tags/LevelTag.ts +++ b/packages/matter.js/src/forwards/tags/LevelTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/LocationTag.ts b/packages/matter.js/src/forwards/tags/LocationTag.ts index e267cb4ad4..536481406d 100644 --- a/packages/matter.js/src/forwards/tags/LocationTag.ts +++ b/packages/matter.js/src/forwards/tags/LocationTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/NumberTag.ts b/packages/matter.js/src/forwards/tags/NumberTag.ts index 4d792337c1..26070e9ba3 100644 --- a/packages/matter.js/src/forwards/tags/NumberTag.ts +++ b/packages/matter.js/src/forwards/tags/NumberTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/PositionTag.ts b/packages/matter.js/src/forwards/tags/PositionTag.ts index 599903f239..c4e6b4798a 100644 --- a/packages/matter.js/src/forwards/tags/PositionTag.ts +++ b/packages/matter.js/src/forwards/tags/PositionTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/PowerSourceTag.ts b/packages/matter.js/src/forwards/tags/PowerSourceTag.ts index 96520d7277..2cdd43e2db 100644 --- a/packages/matter.js/src/forwards/tags/PowerSourceTag.ts +++ b/packages/matter.js/src/forwards/tags/PowerSourceTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/RefrigeratorTag.ts b/packages/matter.js/src/forwards/tags/RefrigeratorTag.ts index 12eef92748..18d8801fa3 100644 --- a/packages/matter.js/src/forwards/tags/RefrigeratorTag.ts +++ b/packages/matter.js/src/forwards/tags/RefrigeratorTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/RelativePositionTag.ts b/packages/matter.js/src/forwards/tags/RelativePositionTag.ts new file mode 100644 index 0000000000..a84592299d --- /dev/null +++ b/packages/matter.js/src/forwards/tags/RelativePositionTag.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export { RelativePositionTag } from "@matter/node"; diff --git a/packages/matter.js/src/forwards/tags/RoomAirConditionerTag.ts b/packages/matter.js/src/forwards/tags/RoomAirConditionerTag.ts index 2af944bc92..1df97e6fb5 100644 --- a/packages/matter.js/src/forwards/tags/RoomAirConditionerTag.ts +++ b/packages/matter.js/src/forwards/tags/RoomAirConditionerTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/SwitchesTag.ts b/packages/matter.js/src/forwards/tags/SwitchesTag.ts index 80f8036120..a38126465f 100644 --- a/packages/matter.js/src/forwards/tags/SwitchesTag.ts +++ b/packages/matter.js/src/forwards/tags/SwitchesTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/forwards/tags/index.ts b/packages/matter.js/src/forwards/tags/index.ts index 366b1eaba9..fa57e46ba4 100644 --- a/packages/matter.js/src/forwards/tags/index.ts +++ b/packages/matter.js/src/forwards/tags/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/matter.js/src/tsconfig.json b/packages/matter.js/src/tsconfig.json index d7f69ec2cd..b649878535 100644 --- a/packages/matter.js/src/tsconfig.json +++ b/packages/matter.js/src/tsconfig.json @@ -22,6 +22,9 @@ { "path": "../../testing/src" }, + { + "path": "../../tools/src" + }, { "path": "../../types/src" } diff --git a/packages/matter.js/test/cluster/ClusterServerTest.ts b/packages/matter.js/test/cluster/ClusterServerTest.ts index 65cafcafed..0616550b7b 100644 --- a/packages/matter.js/test/cluster/ClusterServerTest.ts +++ b/packages/matter.js/test/cluster/ClusterServerTest.ts @@ -34,6 +34,7 @@ describe("ClusterServer structure", () => { productName: "test", productId: 1, nodeLabel: "", + uniqueId: "", location: "DE", hardwareVersion: 1, hardwareVersionString: "1", @@ -98,6 +99,7 @@ describe("ClusterServer structure", () => { productName: "test", productId: 1, nodeLabel: "", + uniqueId: "", location: "DE", hardwareVersion: 1, hardwareVersionString: "1", @@ -150,6 +152,7 @@ describe("ClusterServer structure", () => { productName: "test", productId: 1, nodeLabel: "", + uniqueId: "", location: "DE", hardwareVersion: 1, hardwareVersionString: "1", @@ -225,6 +228,7 @@ describe("ClusterServer structure", () => { productName: "test", productId: 1, nodeLabel: "", + uniqueId: "", location: "DE", hardwareVersion: 1, hardwareVersionString: "1", @@ -280,6 +284,7 @@ describe("ClusterServer structure", () => { productName: "test", productId: 1, nodeLabel: "", + uniqueId: "", location: "DE", hardwareVersion: 1, hardwareVersionString: "1", @@ -338,6 +343,7 @@ describe("ClusterServer structure", () => { productName: "test", productId: 1, nodeLabel: "", + uniqueId: "", location: "DE", hardwareVersion: 1, hardwareVersionString: "1", @@ -770,6 +776,7 @@ describe("ClusterServer structure", () => { productName: "test", productId: 1, nodeLabel: "", + uniqueId: "", location: "DE", hardwareVersion: 1, hardwareVersionString: "1", diff --git a/packages/matter.js/test/device/MatterNodeStructureTest.ts b/packages/matter.js/test/device/MatterNodeStructureTest.ts index 0ec214afc7..b7fdcfda18 100644 --- a/packages/matter.js/test/device/MatterNodeStructureTest.ts +++ b/packages/matter.js/test/device/MatterNodeStructureTest.ts @@ -56,6 +56,7 @@ function addRequiredRootClusters( productName: "product", productId: 2, nodeLabel: "", + uniqueId: "", hardwareVersion: 0, hardwareVersionString: "0", location: "US", @@ -139,7 +140,7 @@ function addRequiredRootClusters( rootEndpoint.addClusterServer( ClusterServer( - AccessControlCluster, + AccessControlCluster.with("Extension"), { acl: [], extension: [], @@ -313,7 +314,7 @@ async function commissioningServer({ storage, values }: { storage?: boolean; val rootEndpoint = node.getRootEndpoint(); - addRequiredRootClusters(rootEndpoint); + addRequiredRootClusters(rootEndpoint, true, false); return node; } @@ -371,7 +372,7 @@ describe("Endpoint Structures", () => { expectPaths(endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, AccessControl: { attribute: 10 }, @@ -383,7 +384,7 @@ describe("Endpoint Structures", () => { const basicInformationCluster = rootEndpoint.getClusterServer(BasicInformationCluster); expect(basicInformationCluster).exist; - expect((basicInformationCluster?.attributes as any).attributeList.get().length).equal(21); + expect((basicInformationCluster?.attributes as any).attributeList.get().length).equal(22); expect((basicInformationCluster?.attributes as any).generatedCommandList.get().length).equal(0); expect((basicInformationCluster?.attributes as any).acceptedCommandList.get().length).equal(0); @@ -394,7 +395,7 @@ describe("Endpoint Structures", () => { expect((generalCommissioningCluster?.attributes as any).acceptedCommandList.get().length).equal(3); }); - it("One device with one Light endpoint - no unique id, use index", async () => { + it("One device with one Light endpoint - automatic unique id, use index", async () => { const node = await commissioningServer(); const onoffDevice = new OnOffPluginUnitDevice(); @@ -410,7 +411,7 @@ describe("Endpoint Structures", () => { endpointStructure.initializeFromEndpoint(rootEndpoint); const { endpoints, attributes } = endpointStructure; - expect(endpointStorage.get("serial_node-matter-0000-index_0")).equal(1); + expect(endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_0")).equal(1); expect(endpoints.size).equal(2); expect(endpoints.get(EndpointNumber(0))?.getAllClusterServers().length).equal(9); @@ -444,7 +445,7 @@ describe("Endpoint Structures", () => { endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, AccessControl: { attribute: 10 }, @@ -463,7 +464,7 @@ describe("Endpoint Structures", () => { ); }); - it("One device with one Light endpoints - with uniqueid", async () => { + it("One device with one Light endpoints - manual unique id", async () => { const node = await commissioningServer(); const onoffDevice = new OnOffPluginUnitDevice(undefined, { uniqueStorageKey: "test-unique-id" }); @@ -479,7 +480,7 @@ describe("Endpoint Structures", () => { endpointStructure.initializeFromEndpoint(rootEndpoint); const { endpoints, attributes } = endpointStructure; - expect(endpointStorage.get("serial_node-matter-0000-custom_test-unique-id")).equal(1); + expect(endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-custom_test-unique-id")).equal(1); expect(endpoints.size).equal(2); expect(endpoints.get(EndpointNumber(0))?.getAllClusterServers().length).equal(9); @@ -513,7 +514,7 @@ describe("Endpoint Structures", () => { endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, AccessControl: { attribute: 10 }, @@ -534,7 +535,7 @@ describe("Endpoint Structures", () => { it("One device with one Light endpoints - no uniqueid, use index, from storage", async () => { const node = await commissioningServer({ - values: { "serial_node-matter-0000-index_0": 10 }, + values: { "unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_0": 10 }, }); const onoffDevice = new OnOffPluginUnitDevice(); @@ -550,7 +551,7 @@ describe("Endpoint Structures", () => { endpointStructure.initializeFromEndpoint(rootEndpoint); const { endpoints, attributes } = endpointStructure; - expect(endpointStorage.get("serial_node-matter-0000-index_0")).equal(10); + expect(endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_0")).equal(10); expect(endpoints.size).equal(2); expect(endpoints.get(EndpointNumber(0))?.getAllClusterServers().length).equal(9); @@ -584,7 +585,7 @@ describe("Endpoint Structures", () => { endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, AccessControl: { attribute: 10 }, @@ -605,7 +606,7 @@ describe("Endpoint Structures", () => { it("One device with one Light endpoints - with uniqueid, from storage", async () => { const node = await commissioningServer({ - values: { "serial_node-matter-0000-custom_test-unique-id": 10 }, + values: { "unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-custom_test-unique-id": 10 }, }); const onoffDevice = new OnOffPluginUnitDevice(undefined, { uniqueStorageKey: "test-unique-id" }); @@ -621,7 +622,7 @@ describe("Endpoint Structures", () => { endpointStructure.initializeFromEndpoint(rootEndpoint); const { endpoints, attributes } = endpointStructure; - expect(endpointStorage.get("serial_node-matter-0000-custom_test-unique-id")).equal(10); + expect(endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-custom_test-unique-id")).equal(10); expect(endpoints.size).equal(2); expect(endpoints.get(EndpointNumber(0))?.getAllClusterServers().length).equal(9); @@ -655,7 +656,7 @@ describe("Endpoint Structures", () => { endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, AccessControl: { attribute: 10 }, @@ -687,6 +688,7 @@ describe("Endpoint Structures", () => { ClusterServer( BridgedDeviceBasicInformationCluster, { + uniqueId: "", nodeLabel: "Socket 1", reachable: true, }, @@ -714,6 +716,7 @@ describe("Endpoint Structures", () => { ClusterServer( BridgedDeviceBasicInformationCluster, { + uniqueId: "", nodeLabel: "Socket 1", reachable: true, }, @@ -818,7 +821,7 @@ describe("Endpoint Structures", () => { endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, NetworkCommissioning: { attribute: 11 }, @@ -834,7 +837,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, ); }); @@ -849,10 +852,12 @@ describe("Endpoint Structures", () => { const onoffDevice12 = new OnOffPluginUnitDevice(undefined, { endpointId: EndpointNumber(12) }); aggregator.addBridgedDevice(onoffDevice11, { + uniqueId: "", nodeLabel: "Socket 1", reachable: true, }); aggregator.addBridgedDevice(onoffDevice12, { + uniqueId: "", nodeLabel: "Socket 2", reachable: true, }); @@ -961,7 +966,7 @@ describe("Endpoint Structures", () => { endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, NetworkCommissioning: { attribute: 11 }, @@ -977,7 +982,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, @@ -985,7 +990,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, ); }); @@ -1009,10 +1014,12 @@ describe("Endpoint Structures", () => { const onoffDevice12 = new OnOffPluginUnitDevice(undefined, { endpointId: EndpointNumber(12) }); aggregator1.addBridgedDevice(onoffDevice11, { + uniqueId: "", nodeLabel: "Socket 1-1", reachable: true, }); aggregator1.addBridgedDevice(onoffDevice12, { + uniqueId: "", nodeLabel: "Socket 1-2", reachable: true, }); @@ -1033,10 +1040,12 @@ describe("Endpoint Structures", () => { const onoffDevice22 = new OnOffPluginUnitDevice(undefined, { endpointId: EndpointNumber(22) }); aggregator2.addBridgedDevice(onoffDevice21, { + uniqueId: "", nodeLabel: "Socket 2-1", reachable: true, }); aggregator2.addBridgedDevice(onoffDevice22, { + uniqueId: "", nodeLabel: "Socket 2-2", reachable: true, }); @@ -1137,7 +1146,7 @@ describe("Endpoint Structures", () => { endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, NetworkCommissioning: { attribute: 11 }, @@ -1154,7 +1163,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, @@ -1162,7 +1171,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, @@ -1170,7 +1179,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, @@ -1178,7 +1187,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, ); }); @@ -1201,10 +1210,12 @@ describe("Endpoint Structures", () => { const onoffDevice12 = new OnOffPluginUnitDevice(); aggregator1.addBridgedDevice(onoffDevice11, { + uniqueId: "", nodeLabel: "Socket 1-1", reachable: true, }); aggregator1.addBridgedDevice(onoffDevice12, { + uniqueId: "", nodeLabel: "Socket 1-2", reachable: true, }); @@ -1225,10 +1236,12 @@ describe("Endpoint Structures", () => { const onoffDevice22 = new OnOffPluginUnitDevice(); aggregator2.addBridgedDevice(onoffDevice21, { + uniqueId: "", nodeLabel: "Socket 2-1", reachable: true, }); aggregator2.addBridgedDevice(onoffDevice22, { + uniqueId: "", nodeLabel: "Socket 2-2", reachable: true, }); @@ -1333,7 +1346,7 @@ describe("Endpoint Structures", () => { endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, AccessControl: { attribute: 10 }, @@ -1349,7 +1362,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, @@ -1357,7 +1370,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, FixedLabel: { attribute: 6 } }, { @@ -1366,7 +1379,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, @@ -1374,7 +1387,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, ); }); @@ -1397,10 +1410,12 @@ describe("Endpoint Structures", () => { const onoffDevice12 = new OnOffPluginUnitDevice(); aggregator1.addBridgedDevice(onoffDevice11, { + uniqueId: "SOCKET-1-1", nodeLabel: "Socket 1-1", reachable: true, }); aggregator1.addBridgedDevice(onoffDevice12, { + uniqueId: "SOCKET-1-2", nodeLabel: "Socket 1-2", reachable: true, }); @@ -1421,11 +1436,13 @@ describe("Endpoint Structures", () => { const onoffDevice22 = new OnOffPluginUnitDevice(undefined, { endpointId: EndpointNumber(18) }); aggregator2.addBridgedDevice(onoffDevice21, { + uniqueId: "SOCKET-2-1", nodeLabel: "Socket 2-1", serialNumber: "12345678", reachable: true, }); aggregator2.addBridgedDevice(onoffDevice22, { + uniqueId: "SOCKET-2-2", nodeLabel: "Socket 2-2", reachable: true, }); @@ -1573,17 +1590,21 @@ describe("Endpoint Structures", () => { EndpointNumber(43), ]); - expect(endpointStorage.get("serial_node-matter-0000-index_0-index_1")).equal(38); - expect(endpointStorage.get("serial_node-matter-0000-index_1-unique_COMPOSED2-custom_COMPOSED.SUB1")).equal( - 42, - ); - expect(endpointStorage.get("serial_node-matter-0000-index_1-unique_COMPOSED2-index_1")).equal(43); + expect(endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_0-unique_SOCKET-1-2")).equal(38); + expect( + endpointStorage.get( + "unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_1-unique_COMPOSED2-custom_COMPOSED.SUB1", + ), + ).equal(42); + expect( + endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_1-unique_COMPOSED2-index_1"), + ).equal(43); expectPaths( endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, AccessControl: { attribute: 10 }, @@ -1598,7 +1619,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, @@ -1606,7 +1627,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, FixedLabel: { attribute: 6 } }, { @@ -1615,7 +1636,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, FixedLabel: { attribute: 6 } }, { @@ -1624,7 +1645,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 8 }, + BridgedDeviceBasicInformation: { attribute: 9 }, }, { Descriptor: { attribute: 9 }, BridgedDeviceBasicInformation: { attribute: 8 } }, { @@ -1646,7 +1667,7 @@ describe("Endpoint Structures", () => { it("Device Structure with two aggregators and three Light/Composed endpoints and all partly auto-assigned endpoint IDs and removing adding devices", async () => { const node = await commissioningServer({ - values: { "serial_node-matter-0000-index_0-custom_3333": 3 }, + values: { "unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_0-custom_3333": 3 }, }); const aggregator1 = new Aggregator([], { endpointId: EndpointNumber(37) }); @@ -1664,10 +1685,12 @@ describe("Endpoint Structures", () => { const onoffDevice12 = new OnOffPluginUnitDevice(); aggregator1.addBridgedDevice(onoffDevice11, { + uniqueId: "SOCKET-1-1", nodeLabel: "Socket 1-1", reachable: true, }); aggregator1.addBridgedDevice(onoffDevice12, { + uniqueId: "SOCKET-1-2", nodeLabel: "Socket 1-2", reachable: true, }); @@ -1688,11 +1711,13 @@ describe("Endpoint Structures", () => { const onoffDevice22 = new OnOffPluginUnitDevice(undefined, { endpointId: EndpointNumber(18) }); aggregator2.addBridgedDevice(onoffDevice21, { + uniqueId: "SOCKET-2-1", nodeLabel: "Socket 2-1", serialNumber: "12345678", reachable: true, }); aggregator2.addBridgedDevice(onoffDevice22, { + uniqueId: "SOCKET-2-2", nodeLabel: "Socket 2-2", reachable: true, }); @@ -1840,17 +1865,21 @@ describe("Endpoint Structures", () => { EndpointNumber(43), ]); - expect(endpointStorage.get("serial_node-matter-0000-index_0-index_1")).equal(38); - expect(endpointStorage.get("serial_node-matter-0000-index_1-unique_COMPOSED2-custom_COMPOSED.SUB1")).equal( - 42, - ); - expect(endpointStorage.get("serial_node-matter-0000-index_1-unique_COMPOSED2-index_1")).equal(43); + expect(endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_0-unique_SOCKET-1-2")).equal(38); + expect( + endpointStorage.get( + "unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_1-unique_COMPOSED2-custom_COMPOSED.SUB1", + ), + ).equal(42); + expect( + endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_1-unique_COMPOSED2-index_1"), + ).equal(43); expectPaths( endpointStructure, { Descriptor: { attribute: 9 }, - BasicInformation: { attribute: 21 }, + BasicInformation: { attribute: 22 }, OperationalCredentials: { attribute: 11, command: 8 }, GeneralCommissioning: { attribute: 10, command: 3 }, AccessControl: { attribute: 10 }, @@ -1865,7 +1894,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, @@ -1873,7 +1902,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, FixedLabel: { attribute: 6 } }, { @@ -1882,7 +1911,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 7 }, + BridgedDeviceBasicInformation: { attribute: 8 }, }, { Descriptor: { attribute: 9 }, FixedLabel: { attribute: 6 } }, { @@ -1891,7 +1920,7 @@ describe("Endpoint Structures", () => { Identify: { attribute: 7, command: 1 }, Groups: { attribute: 6, command: 6 }, OnOff: { attribute: 6, command: 3 }, - BridgedDeviceBasicInformation: { attribute: 8 }, + BridgedDeviceBasicInformation: { attribute: 9 }, }, { Descriptor: { attribute: 9 }, BridgedDeviceBasicInformation: { attribute: 8 } }, { @@ -1921,11 +1950,12 @@ describe("Endpoint Structures", () => { // Add another device const onoffDevice13 = new OnOffPluginUnitDevice(); aggregator1.addBridgedDevice(onoffDevice13, { + uniqueId: "SOCKET-1-1", nodeLabel: "Socket 1-1", reachable: true, }); expect(structureChangeCounter).equal(1); - expect(endpointStorage.get("serial_node-matter-0000-index_0-index_2")).equal(44); + expect(endpointStorage.get("unique_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-index_0-unique_SOCKET-1-1")).equal(44); // And remove one aggregator1.removeBridgedDevice(onoffDevice11); @@ -1951,6 +1981,7 @@ describe("Endpoint Structures", () => { // Add the removed back and verify it gets same endpointID as before const onoffDevice11New = new OnOffPluginUnitDevice(undefined, { uniqueStorageKey: "3333" }); aggregator1.addBridgedDevice(onoffDevice11New, { + uniqueId: "", nodeLabel: "Socket 1-1 NEW", reachable: true, }); @@ -2077,6 +2108,7 @@ describe("Endpoint Structures", () => { expect(destroyCalled).false; aggregator.addBridgedDevice(onoffDevice, { + uniqueId: "", nodeLabel: "Socket 1-1", reachable: true, }); diff --git a/packages/model/src/aspects/Conformance.ts b/packages/model/src/aspects/Conformance.ts index 6bb5db3c12..06caf78360 100644 --- a/packages/model/src/aspects/Conformance.ts +++ b/packages/model/src/aspects/Conformance.ts @@ -4,7 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { FieldValue } from "../common/index.js"; +import { type Model } from "#models/Model.js"; +import { type ValueModel } from "#models/ValueModel.js"; +import { FieldValue, Metatype } from "../common/index.js"; import { BasicToken, Lexer, TokenStream } from "../parser/index.js"; import { Aspect } from "./Aspect.js"; @@ -58,7 +60,7 @@ export class Conformance extends Aspect { this.freeze(); } - validateReferences(errorTarget: Conformance.ErrorTarget, lookup: Conformance.ReferenceResolver) { + validateReferences(errorTarget: Conformance.ErrorTarget, lookup: Conformance.ReferenceResolver) { return Conformance.validateReferences(this, this.ast, errorTarget, lookup); } @@ -178,6 +180,7 @@ export namespace Conformance { name: ChoiceName; num: number; orMore?: boolean; + orLess?: boolean; expr: Ast; }; } @@ -262,7 +265,7 @@ export namespace Conformance { | "y" | "z"; - export type ReferenceResolver = (name: string) => T; + export type ReferenceResolver = (name: string) => Model | undefined; export type ErrorTarget = { error(code: string, message: string): void }; /** @@ -286,7 +289,7 @@ export namespace Conformance { conformance: Conformance, ast: Ast, errorTarget: ErrorTarget, - resolver: ReferenceResolver, + resolver: ReferenceResolver, ) { switch (ast.type) { case Operator.OR: @@ -299,7 +302,24 @@ export namespace Conformance { case Operator.GTE: case Operator.LTE: validateReferences(conformance, ast.param.lhs, errorTarget, resolver); - validateReferences(conformance, ast.param.rhs, errorTarget, resolver); + + // Special case for binary operators -- if LHS references an enum, RHS may reference enum values using + // unqualified names + let operatorResolver = resolver; + if (ast.param.lhs.type === "name") { + const referenced = resolver(ast.param.lhs.param); + if ((referenced as ValueModel)?.effectiveMetatype === Metatype.enum) { + operatorResolver = (name: string) => { + const enumValue = (referenced as ValueModel).member(name); + if (enumValue) { + return enumValue as ValueModel; + } + return resolver(name); + }; + } + } + + validateReferences(conformance, ast.param.rhs, errorTarget, operatorResolver); break; case Operator.NOT: @@ -353,7 +373,11 @@ export namespace Conformance { result = `${result}${ast.param.num}`; } if (ast.param.orMore) { - result = `${result}+`; + if (!ast.param.orLess) { + result = `${result}+`; + } + } else if (ast.param.orLess) { + result = `${result}-`; } return result; @@ -541,6 +565,10 @@ function ParsedAst(conformance: Conformance, definition: string) { choice.orMore = true; tokens.next(); } + if (atOperator("-")) { + choice.orLess = true; + tokens.next(); + } return { type: Conformance.Special.Choice, diff --git a/packages/model/src/aspects/Quality.ts b/packages/model/src/aspects/Quality.ts index 43496430c7..3a91f07dc2 100644 --- a/packages/model/src/aspects/Quality.ts +++ b/packages/model/src/aspects/Quality.ts @@ -25,6 +25,7 @@ export class Quality extends Aspect implements Quality.Ast { declare quieter?: boolean; declare largeMessage?: boolean; declare diagnostics?: boolean; + declare atomic?: boolean; /** * Initialize from a Quality.All definition or a string conforming to the @@ -119,6 +120,7 @@ export namespace Quality { quieter = "Q", largeMessage = "L", diagnostics = "K", + atomic = "T", } /** @@ -135,6 +137,7 @@ export namespace Quality { Q = "quieter", L = "largeMessage", K = "diagnostics", + T = "atomic", } /** @@ -145,7 +148,7 @@ export namespace Quality { /** * Runtime version of QualityFlag. */ - export const FlagNames: FlagName[] = ["X", "N", "F", "S", "P", "C", "I", "Q", "L", "K"]; + export const FlagNames: FlagName[] = ["X", "N", "F", "S", "P", "C", "I", "Q", "L", "K", "T"]; /** * Quality values that apply to data fields. @@ -184,6 +187,11 @@ export namespace Quality { * to report. */ quieter?: boolean; + + /** + * Designates attribute as mutable only via atomic write. + */ + atomic?: boolean; }; /** diff --git a/packages/model/src/common/Specification.ts b/packages/model/src/common/Specification.ts index a3b54a161e..9c65191b35 100644 --- a/packages/model/src/common/Specification.ts +++ b/packages/model/src/common/Specification.ts @@ -49,19 +49,19 @@ export namespace Specification { /** * The default specification revision for Matter.js. */ - export const REVISION = "1.3.0.1"; + export const REVISION = "1.4"; /** * Binary version of specification revision defined by Basic Information Cluster. * * Currently spec says least significant octet is "reserved", so we don't stick the .1 into it. */ - export const SPECIFICATION_VERSION = 0x01030000; + export const SPECIFICATION_VERSION = 0x01040000; /** * Data model revision associated with the default revision of Matter. */ - export const DATA_MODEL_REVISION = 17; + export const DATA_MODEL_REVISION = 18; /** * Interaction model revision associated with the default revision of Matter. diff --git a/packages/model/src/logic/cluster-variance/IllegalFeatureCombinations.ts b/packages/model/src/logic/cluster-variance/IllegalFeatureCombinations.ts index aa637c98a9..b05b38b689 100644 --- a/packages/model/src/logic/cluster-variance/IllegalFeatureCombinations.ts +++ b/packages/model/src/logic/cluster-variance/IllegalFeatureCombinations.ts @@ -73,7 +73,95 @@ function addFeatureNode( illegal: IllegalFeatureCombinations, choices: Choices, ) { - function unsupported() { + switch (node.type) { + case Conformance.Special.Desc: + case Conformance.Special.Empty: + case Conformance.Flag.Optional: + case Conformance.Flag.Provisional: + break; + + case Conformance.Flag.Mandatory: + illegal.push({ [feature.name]: false }); + break; + + case Conformance.Flag.Deprecated: + case Conformance.Flag.Disallowed: + illegal.push({ [feature.name]: true }); + break; + + case Conformance.Special.Group: + node.param.forEach(ast => addFeatureNode(feature, ast, illegal, choices)); + break; + + case Conformance.Special.Choice: + if (node.param.num > 1) { + unsupported(); + } + let choice = choices[node.param.name]; + if (choice) { + choice.features.push(feature.name); + } else { + choice = choices[node.param.name] = { + exclusive: !node.param.orMore, + features: [feature.name], + }; + } + break; + + case Conformance.Special.Name: + illegal.push({ [node.param]: true, [feature.name]: false }); + break; + + case Conformance.Special.OptionalIf: + switch (node.param.type) { + case Conformance.AND: + case Conformance.Special.Name: + addDependencyRequirement(feature.name, node.param); + break; + + case Conformance.OR: { + const flags = FeatureBitmap({ [feature.name]: true }); + addExclusivityRequirement(flags, node.param); + illegal.push(flags); + break; + } + + case Conformance.Operator.NOT: { + illegal.push({ [feature.name]: true, [extractName(node.param.param)]: true }); + break; + } + + default: + unsupported(); + } + break; + + case Conformance.Operator.AND: { + // Handles simple conjunctions like "FOO & BAR" and "(STA|PAU|FA|CON) & !SFR" + const lhsFeatures = extractDisjunctFeatures(node.param.lhs); + const rhsFeature = extractFeatureFlag(node.param.rhs); + + for (const lhsFeature in lhsFeatures) { + illegal.push({ + feature: false, + [lhsFeature]: lhsFeatures[lhsFeature], + ...rhsFeature, + }); + } + break; + } + + case Conformance.Operator.OR: { + const features = extractDisjunctFeatures(node); + illegal.push(Object.fromEntries(Object.entries(features).map((k, v) => [k, !v]))); + break; + } + + default: + unsupported(); + } + + function unsupported(): never { throw new InternalError(`New rule required to support ${feature.path} conformance "${feature.conformance}"`); } @@ -85,7 +173,6 @@ function addFeatureNode( return node.param; } unsupported(); - return ""; // Unreachable } /** @@ -134,6 +221,21 @@ function addFeatureNode( addDependencyRequirement(feature, node.param.rhs); break; + case Conformance.OR: + if ( + node.param.lhs.type === Conformance.Special.Name && + node.param.rhs.type === Conformance.Special.Name + ) { + illegal.push({ [feature]: true, [node.param.lhs.param]: false, [node.param.rhs.param]: false }); + } + break; + + case Conformance.Operator.NOT: + if (node.param.type === Conformance.Special.Name) { + illegal.push({ [feature]: true, [node.param.param]: true }); + } + break; + default: unsupported(); } @@ -169,83 +271,4 @@ function addFeatureNode( return result; } - - switch (node.type) { - case Conformance.Special.Desc: - case Conformance.Special.Empty: - case Conformance.Flag.Optional: - case Conformance.Flag.Provisional: - break; - - case Conformance.Flag.Deprecated: - case Conformance.Flag.Disallowed: - illegal.push({ [feature.name]: true }); - break; - - case Conformance.Special.Group: - node.param.forEach(ast => addFeatureNode(feature, ast, illegal, choices)); - break; - - case Conformance.Special.Choice: - if (node.param.num > 1) { - unsupported(); - } - let choice = choices[node.param.name]; - if (choice) { - choice.features.push(feature.name); - } else { - choice = choices[node.param.name] = { - exclusive: !node.param.orMore, - features: [feature.name], - }; - } - break; - - case Conformance.Special.Name: - illegal.push({ [node.param]: true, [feature.name]: false }); - break; - - case Conformance.Special.OptionalIf: - switch (node.param.type) { - case Conformance.AND: - case Conformance.Special.Name: - addDependencyRequirement(feature.name, node.param); - break; - - case Conformance.OR: { - const flags = FeatureBitmap({ [feature.name]: true }); - addExclusivityRequirement(flags, node.param); - illegal.push(flags); - break; - } - - case Conformance.Operator.NOT: { - illegal.push({ [feature.name]: true, [extractName(node.param.param)]: true }); - break; - } - - default: - unsupported(); - } - break; - - case Conformance.Operator.AND: { - // Handles simple conjunctions like "FOO & BAR" and "(STA|PAU|FA|CON) & !SFR" - const lhsFeatures = extractDisjunctFeatures(node.param.lhs); - const rhsFeature = extractFeatureFlag(node.param.rhs); - - for (const lhsFeature in lhsFeatures) { - illegal.push({ - feature: false, - [lhsFeature]: lhsFeatures[lhsFeature], - ...rhsFeature, - }); - } - break; - } - - default: - unsupported(); - break; - } } diff --git a/packages/model/src/logic/cluster-variance/InferredComponents.ts b/packages/model/src/logic/cluster-variance/InferredComponents.ts index aa7c6c6e88..c3bb7c5d85 100644 --- a/packages/model/src/logic/cluster-variance/InferredComponents.ts +++ b/packages/model/src/logic/cluster-variance/InferredComponents.ts @@ -105,6 +105,14 @@ const VarianceMatchers: VarianceMatcher[] = [ }, }, + // [fieldName] (optional, unconditional). Ignores field reference which can only be enforced at runtime + { + pattern: pattern("[", FIELD, "]"), + processor(add) { + add(false); + }, + }, + // fieldName > num (optional, unconditional). Ignores field expression { pattern: pattern(FIELD, " > ", "\\d+"), @@ -179,6 +187,14 @@ const VarianceMatchers: VarianceMatcher[] = [ }, }, + // FOO & !BAR + { + pattern: pattern(FEATURE, AND, NOT, FEATURE), + processor(add, match) { + add(false, { allOf: [match[0]], not: match[1] }); + }, + }, + // !FOO & BAR { pattern: pattern(NOT, FEATURE, AND, FEATURE), @@ -244,6 +260,16 @@ const VarianceMatchers: VarianceMatcher[] = [ add(true); }, }, + + // Handles a bunch of super ugly conformances in deprecated occupancy sensing attributes. They all effectively + // become optional if certain features are enabled. We use the presence of the "HoldTime" field to reliably detect + // these and ensure these rules aren't too greedy + { + pattern: pattern(".*HoldTime", AND, "\\(?", FEATURE, ".*"), + processor(add, match) { + add(true, { allOf: [match[0]] }); + }, + }, ]; function addElement(components: InferredComponents, element: ValueModel) { @@ -267,7 +293,7 @@ function addElement(components: InferredComponents, element: ValueModel) { if (text === "D") { text = "O"; - } else if (text === "P") { + } else if (text === "M, D" || text === "P") { text = "M"; } diff --git a/packages/model/src/logic/definition-validation/ValueValidator.ts b/packages/model/src/logic/definition-validation/ValueValidator.ts index ed943f261c..b0b125bdee 100644 --- a/packages/model/src/logic/definition-validation/ValueValidator.ts +++ b/packages/model/src/logic/definition-validation/ValueValidator.ts @@ -29,16 +29,16 @@ export class ValueValidator extends ModelValidator { if (name.match(/^[A-Z0-9_$]+$/)) { // Feature lookup const cluster = this.model.owner(ClusterModel); - return !!cluster?.features.find(f => f.name === name); + return cluster?.features.find(f => f.name === name); } // Field lookup for (let model = this.model.parent; model; model = model.parent) { - if (model.member(name) !== undefined) { - return true; + const member = model.member(name); + if (member) { + return member; } } - return false; }); this.validateAspect("constraint"); @@ -259,9 +259,19 @@ export class ValueValidator extends ModelValidator { // Special "reference" object referencing another field by name if (typeof def === "object" && FieldValue.is(def, FieldValue.reference)) { const reference = (def as FieldValue.Reference).name; - const other = this.model.parent?.member(reference); + + // See if the referenced name is a sibling + const parent = this.model.parent; + let other = parent?.member(reference); + if (!other) { - this.error("MEMBER_UNKNOWN", `Default value references unknown property ${reference}`); + // We also allow names to reference cluster attributes + const cluster = parent?.owner(ClusterModel); + other = cluster?.member(reference); + + if (other === undefined) { + this.error("MEMBER_UNKNOWN", `Default value references unknown property ${reference}`); + } } return true; } diff --git a/packages/model/src/models/AttributeModel.ts b/packages/model/src/models/AttributeModel.ts index b8f2b13812..9891991516 100644 --- a/packages/model/src/models/AttributeModel.ts +++ b/packages/model/src/models/AttributeModel.ts @@ -44,10 +44,6 @@ export class AttributeModel extends PropertyModel implements A super(definition); } - static { - Model.types[AttributeElement.Tag] = this; - } - static isGlobal(model: Model) { return model instanceof AttributeModel && GLOBAL_IDS.has(model.id); } @@ -58,3 +54,5 @@ export class AttributeModel extends PropertyModel implements A static Tag = AttributeElement.Tag; } + +AttributeModel.register(); diff --git a/packages/model/src/models/ClusterModel.ts b/packages/model/src/models/ClusterModel.ts index 58facce939..0fc2fb0dd6 100644 --- a/packages/model/src/models/ClusterModel.ts +++ b/packages/model/src/models/ClusterModel.ts @@ -171,12 +171,10 @@ export class ClusterModel extends ScopeModel implements ClusterE } static Tag = ClusterElement.Tag; - - static { - Model.types[this.Tag] = this; - } } +ClusterModel.register(); + export namespace ClusterModel { export type Definition = ClusterElement.Properties & { supportedFeatures?: FeatureSet.Definition }; diff --git a/packages/model/src/models/CommandModel.ts b/packages/model/src/models/CommandModel.ts index 333103af5e..92af7ff2b1 100644 --- a/packages/model/src/models/CommandModel.ts +++ b/packages/model/src/models/CommandModel.ts @@ -7,7 +7,6 @@ import { Mei } from "../common/Mei.js"; import { CommandElement } from "../elements/index.js"; import { ModelTraversal } from "../logic/ModelTraversal.js"; -import { Model } from "./Model.js"; import { ValueModel } from "./ValueModel.js"; export class CommandModel extends ValueModel implements CommandElement { @@ -57,9 +56,7 @@ export class CommandModel extends ValueModel implements CommandE return this.direction; } - static { - Model.types[CommandElement.Tag] = this; - } - static Tag = CommandElement.Tag; } + +CommandModel.register(); diff --git a/packages/model/src/models/DatatypeModel.ts b/packages/model/src/models/DatatypeModel.ts index ed18d1a92f..e1b3de27ea 100644 --- a/packages/model/src/models/DatatypeModel.ts +++ b/packages/model/src/models/DatatypeModel.ts @@ -6,7 +6,6 @@ import { Metatype } from "../common/index.js"; import { DatatypeElement } from "../elements/DatatypeElement.js"; -import { Model } from "./Model.js"; import { ValueModel } from "./ValueModel.js"; export class DatatypeModel extends ValueModel implements DatatypeElement { @@ -23,7 +22,7 @@ export class DatatypeModel extends ValueModel implements Dataty return false; } - static { - Model.types[DatatypeElement.Tag] = this; - } + static Tag = DatatypeElement.Tag; } + +DatatypeModel.register(); diff --git a/packages/model/src/models/DeviceTypeModel.ts b/packages/model/src/models/DeviceTypeModel.ts index af570d848a..a4d9bffc8a 100644 --- a/packages/model/src/models/DeviceTypeModel.ts +++ b/packages/model/src/models/DeviceTypeModel.ts @@ -35,11 +35,11 @@ export class DeviceTypeModel extends Model implements DeviceT ); } - static { - Model.types[DeviceTypeElement.Tag] = this; - } + static Tag = DeviceTypeElement.Tag; } +DeviceTypeModel.register(); + export namespace DeviceTypeModel { export type Child = RequirementModel | FieldModel; } diff --git a/packages/model/src/models/EndpointModel.ts b/packages/model/src/models/EndpointModel.ts index 7e37bb5529..0925594300 100644 --- a/packages/model/src/models/EndpointModel.ts +++ b/packages/model/src/models/EndpointModel.ts @@ -25,7 +25,7 @@ export class EndpointModel extends Model implements EndpointEleme return this.children; } - static { - Model.types[EndpointElement.Tag] = this; - } + static Tag = EndpointElement.Tag; } + +EndpointModel.register(); diff --git a/packages/model/src/models/EventModel.ts b/packages/model/src/models/EventModel.ts index 3016c9fa22..4249488c4d 100644 --- a/packages/model/src/models/EventModel.ts +++ b/packages/model/src/models/EventModel.ts @@ -6,7 +6,6 @@ import { Mei } from "../common/Mei.js"; import { EventElement } from "../elements/index.js"; -import { Model } from "./Model.js"; import { ValueModel } from "./ValueModel.js"; export class EventModel extends ValueModel implements EventElement { @@ -26,9 +25,7 @@ export class EventModel extends ValueModel implements EventElement return { ...super.requiredFields, id: this.id }; } - static { - Model.types[EventElement.Tag] = this; - } - static Tag = EventElement.Tag; } + +EventModel.register(); diff --git a/packages/model/src/models/FabricModel.ts b/packages/model/src/models/FabricModel.ts index 311dc20b49..95e1b24be6 100644 --- a/packages/model/src/models/FabricModel.ts +++ b/packages/model/src/models/FabricModel.ts @@ -25,7 +25,7 @@ export class FabricModel extends Model implements FabricElement { return this.children; } - static { - Model.types[FabricElement.Tag] = this; - } + static Tag = FabricElement.Tag; } + +FabricModel.register(); diff --git a/packages/model/src/models/FieldModel.ts b/packages/model/src/models/FieldModel.ts index 204027e29f..cd97a0b0cb 100644 --- a/packages/model/src/models/FieldModel.ts +++ b/packages/model/src/models/FieldModel.ts @@ -7,7 +7,6 @@ import { Mei } from "../common/Mei.js"; import { Metatype } from "../common/index.js"; import { FieldElement } from "../elements/index.js"; -import { Model } from "./Model.js"; import { PropertyModel } from "./PropertyModel.js"; import { ValueModel } from "./ValueModel.js"; @@ -45,7 +44,7 @@ export class FieldModel extends PropertyM return super.key; } - static { - Model.types[FieldElement.Tag] = this; - } + static Tag = FieldElement.Tag; } + +FieldModel.register(); diff --git a/packages/model/src/models/MatterModel.ts b/packages/model/src/models/MatterModel.ts index cfcb365455..aec9d32477 100644 --- a/packages/model/src/models/MatterModel.ts +++ b/packages/model/src/models/MatterModel.ts @@ -106,11 +106,11 @@ export class MatterModel extends ScopeModel implements MatterElem return this.children.filter(child => child.isSeed).map(child => child.clone()); } - static { - Model.types[MatterElement.Tag] = this; - } + static Tag = MatterElement.Tag; } +MatterModel.register(); + export namespace MatterModel { export type Child = | ClusterModel diff --git a/packages/model/src/models/Model.ts b/packages/model/src/models/Model.ts index bf4d85f4cf..d844ded2e5 100644 --- a/packages/model/src/models/Model.ts +++ b/packages/model/src/models/Model.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { camelize, decamelize, ImplementationError, InternalError } from "#general"; +import { camelize, decamelize, ImplementationError } from "#general"; import { DefinitionError, ElementTag, Metatype, Specification } from "../common/index.js"; import { AnyElement, BaseElement } from "../elements/index.js"; import { ModelTraversal } from "../logic/ModelTraversal.js"; @@ -12,6 +12,11 @@ import { Children } from "./Children.js"; const inspect = Symbol.for("nodejs.util.inspect.custom"); +/** + * Thrown when model API is used incorrectly. + */ +export class StructuralModelError extends ImplementationError {} + /** * A "model" is a class that implements runtime functionality associated with the corresponding element type. * @@ -210,9 +215,25 @@ export abstract class Model { } /** - * Factory support. Populated by derivatives upon definition. + * Factory support. */ - static types = {} as { [type: string]: new (definition: any) => Model }; + static types = {} as { [type: string]: Model.ConcreteType }; + + /** + * Add a new model implementation. + */ + static register(this: Model.ConcreteType) { + Model.types[this.Tag] = this; + } + + /** + * All possible tags for registered models of this type. + */ + static get tags() { + return Object.values(Model.types) + .filter(type => type instanceof this) + .map(type => type.Tag); + } /** * In some circumstances the base type can be inferred. This inference happens here. @@ -289,12 +310,12 @@ export abstract class Model { */ static create(definition: AnyElement) { if (typeof definition !== "object") { - throw new InternalError(`Model definition must be object, not ${typeof definition}`); + throw new StructuralModelError(`Model definition must be object, not ${typeof definition}`); } const t = definition["tag"]; const constructor = Model.types[t]; if (!constructor) { - throw new InternalError(`Unknown element tag "${t}"`); + throw new StructuralModelError(`Unknown element tag "${t}"`); } return new constructor(definition); } @@ -405,6 +426,35 @@ export abstract class Model { return new ModelTraversal().findMember(this, key, allowedTags); } + /** + * Access a member that must exist. + */ + require(type: Model.ConcreteType, key: Children.Selector): T { + let member = this.member(key, [type.Tag]); + if (member === undefined && typeof key === "string") { + member = this.member(camelize(key, true)); + } + if (member !== undefined) { + return member as T; + } + + let what; + switch (typeof key) { + case "string": + what = `"${key}"`; + break; + + case "number": + what = `#${key}"`; + break; + + default: + what = `selected`; + } + + throw new StructuralModelError(`No ${type.Tag} ${what} for ${this.tag} ${this.name}`); + } + /** * Does this model derive from another? */ @@ -456,7 +506,7 @@ export abstract class Model { constructor(definition: Model | BaseElement.Properties, ...children: Model.Definition[]) { if (typeof definition !== "object") { - throw new ImplementationError(`Model definition must be an object, not ${typeof definition}`); + throw new StructuralModelError(`Model definition must be an object, not ${typeof definition}`); } const isClone = definition instanceof Model; @@ -599,6 +649,11 @@ export namespace Model { */ export type Type = abstract new (...args: any) => T; + /** + * A model constructor for a specific element type. + */ + export type ConcreteType = (new (definition: any) => T) & { Tag: ElementTag }; + export type LookupPredicate = Type | { type: Type; test: (model: Model) => boolean }; export type PropertyValidation = { diff --git a/packages/model/src/models/NodeModel.ts b/packages/model/src/models/NodeModel.ts index 570847afb4..2bebf91349 100644 --- a/packages/model/src/models/NodeModel.ts +++ b/packages/model/src/models/NodeModel.ts @@ -25,7 +25,7 @@ export class NodeModel extends Model implements NodeElement { return this.children; } - static { - Model.types[NodeElement.Tag] = this; - } + static Tag = NodeElement.Tag; } + +NodeModel.register(); diff --git a/packages/model/src/models/RequirementModel.ts b/packages/model/src/models/RequirementModel.ts index 246c5764e3..f2cba5fab5 100644 --- a/packages/model/src/models/RequirementModel.ts +++ b/packages/model/src/models/RequirementModel.ts @@ -61,10 +61,6 @@ export class RequirementModel extends Model implements Requi Aspects.setAspect(this, QUALITY, Quality, definition); } - static { - Model.types[RequirementElement.Tag] = this; - } - get requirements() { return this.all(RequirementModel); } @@ -86,8 +82,12 @@ export class RequirementModel extends Model implements Requi get isMandatory() { return this.conformance.isMandatory; } + + static Tag = RequirementElement.Tag; } +RequirementModel.register(); + export namespace RequirementModel { export type Child = RequirementModel | FieldModel; } diff --git a/packages/model/src/models/SemanticNamespaceModel.ts b/packages/model/src/models/SemanticNamespaceModel.ts index 6a4fbf6807..dd163846cd 100644 --- a/packages/model/src/models/SemanticNamespaceModel.ts +++ b/packages/model/src/models/SemanticNamespaceModel.ts @@ -26,7 +26,7 @@ export class SemanticNamespaceModel extends Model impl return this.children; } - static { - Model.types[SemanticNamespaceElement.Tag] = this; - } + static Tag = SemanticNamespaceElement.Tag; } + +SemanticNamespaceModel.register(); diff --git a/packages/model/src/models/SemanticTagModel.ts b/packages/model/src/models/SemanticTagModel.ts index 8a0007428b..6a5764debe 100644 --- a/packages/model/src/models/SemanticTagModel.ts +++ b/packages/model/src/models/SemanticTagModel.ts @@ -20,7 +20,7 @@ export class SemanticTagModel extends Model implements Seman super.children = children; } - static { - Model.types[SemanticTagElement.Tag] = this; - } + static Tag = SemanticTagElement.Tag; } + +SemanticTagModel.register(); diff --git a/packages/model/src/standard/elements/AcceptedCommandList.ts b/packages/model/src/standard/elements/AcceptedCommandList.ts index de58fb265c..e415214f00 100644 --- a/packages/model/src/standard/elements/AcceptedCommandList.ts +++ b/packages/model/src/standard/elements/AcceptedCommandList.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -22,8 +22,12 @@ export const AcceptedCommandList = Attribute( "This attribute shall be a list of the command IDs for client generated commands that are supported " + "and processed by the server." + "\n" + - "For each client request command in this list that mandates a response from the server, the response " + - "command shall be indicated in the GeneratedCommandList attribute.", + "For each client request command in this list that mandates a response from the server, the" + + "\n" + + "response command shall be indicated in the GeneratedCommandList attribute." + + "\n" + + "If any attribute on a server supports atomic writes, this attribute shall contain the command ID " + + "for AtomicRequest.", xref: { document: "core", section: "7.13.4" } }, diff --git a/packages/model/src/standard/elements/AccessControl.ts b/packages/model/src/standard/elements/AccessControl.ts index ff0398cf14..30df4cf9f2 100644 --- a/packages/model/src/standard/elements/AccessControl.ts +++ b/packages/model/src/standard/elements/AccessControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ import { AttributeElement as Attribute, FieldElement as Field, EventElement as Event, + CommandElement as Command, DatatypeElement as Datatype } from "../../elements/index.js"; @@ -31,7 +32,92 @@ export const AccessControl = Cluster( xref: { document: "core", section: "9.10" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "9.10.4" } }, + Field({ + name: "EXTS", conformance: "O", constraint: "0", description: "Extension", + details: "This feature indicates the device supports ACL Extension attribute.", + xref: { document: "core", section: "9.10.4.1" } + }), + + Field({ + name: "MNGD", conformance: "desc", constraint: "1", description: "ManagedDevice", + + details: "This feature is for a device that is managed by a service associated with the device vendor and " + + "which imposes default access restrictions upon each new fabric added to it. This could arise, for " + + "example, if the device is managed by a service provider under contract to an end-user, in such a " + + "way that the manager of the device does not unconditionally grant universal access to all of a " + + "device’s functionality, even for fabric administrators. For example, many Home Routers are managed " + + "by an Internet Service Provider (a service), and these services often have a policy that requires " + + "them to obtain user consent before certain administrative functions can be delegated to a third " + + "party (e.g., a fabric Administrator). These restrictions are expressed using an Access Restriction " + + "List (ARL)." + + "\n" + + "The purpose of this feature on the Access Control cluster is to indicate to a fabric Administrator " + + "that access by it to specific attributes, commands and/or events for specific clusters is currently " + + "prohibited. Attempts to access these restricted data model elements shall result in an error of " + + "ACCESS_RESTRICTED." + + "\n" + + "A device that implements this feature shall have a mechanism to honor the ReviewFabricRestrictions " + + "command, such as user interfaces or service interactions associated with a service provider or the " + + "device manufacturer, which allows the owner (or subscriber) to manage access restrictions for each " + + "fabric. The user interface design, which includes the way restrictions are organized and presented " + + "to the user, is not specified, but SHOULD be usable by non-expert end-users from common mobile " + + "devices, personal computers, or an on-device user interface." + + "\n" + + "Controllers and clients SHOULD incorporate generic handling of the ACCESS_RESTRICTED error code, " + + "when it appears in allowed contexts, in order to gracefully handle situations where this feature is " + + "encountered. Device vendors that adopt this feature SHOULD be judicious in its use given the risk " + + "of unexpected behavior in controllers and clients." + + "\n" + + "For certification testing, a device that implements this feature shall provide a way for all " + + "restrictions to be removed." + + "\n" + + "The ARL attribute provides the set of restrictions currently applied to this fabric." + + "\n" + + "The ReviewFabricRestrictions command provides a way for the fabric Administrator to request that " + + "the server triggers a review of the current fabric restrictions, by involving external entities " + + "such as end-users, or other services associated with the manager of the device hosting the server. " + + "This review process may involve communication between external services and the user, and may take " + + "an unpredictable amount of time to complete since an end-user may need to visit some resources, " + + "such as a mobile application or web site. A FabricRestrictionReviewUpdate event will be generated " + + "by the device within a predictable time period of the ReviewFabricRestrictionsResponse (see " + + "ReviewFabricRestrictions for specification of this time period), and this event can be correlated " + + "with the ReviewFabricRestrictionsResponse using a token provided in both. The device may provide " + + "instructions or a Redirect URL in the FabricRestrictionReviewUpdate event in order to help the user " + + "access the features required for managing per-fabric restrictions." + + "\n" + + "See Section 6.6.2, “Model” for a description of how access control is impacted by the ARL attribute." + + "\n" + + "### Managed Device Feature Usage Restrictions" + + "\n" + + "Use of this feature shall be limited to the mandatory clusters of endpoints having a device type " + + "that explicitly permits its use in the Device Library Specification. As a reminder, the device " + + "types associated with an endpoint are listed in the Descriptor cluster of the endpoint." + + "\n" + + "In addition, use of this feature shall NOT restrict the following clusters on any endpoint:" + + "\n" + + " 1. the Descriptor Cluster (0x001D)" + + "\n" + + " 2. the Binding Cluster (0x001E)" + + "\n" + + " 3. the Network Commissioning Cluster (0x0031)" + + "\n" + + " 4. the Identify Cluster (0x0003)" + + "\n" + + " 5. the Groups Cluster (0x0004)" + + "\n" + + "In addition, use of this feature shall NOT restrict the global attributes of any cluster." + + "\n" + + "Because ARLs cannot be used to restrict root node access or access to any clusters required for " + + "commissioning, administrators may determine the current restrictions of the ARL at any point, " + + "including during commissioning after joining the fabric.", + + xref: { document: "core", section: "9.10.4.2" } + }) + ), Attribute( { @@ -48,7 +134,7 @@ export const AccessControl = Cluster( "Access Control Privilege Granting algorithm to determine if a subject has privilege to interact " + "with targets on the Node.", - xref: { document: "core", section: "9.10.5.3" } + xref: { document: "core", section: "9.10.6.3" } }, Field({ name: "entry", type: "AccessControlEntryStruct" }) @@ -56,12 +142,12 @@ export const AccessControl = Cluster( Attribute( { - name: "Extension", id: 0x1, type: "list", access: "RW F A", conformance: "O", constraint: "desc", + name: "Extension", id: 0x1, type: "list", access: "RW F A", conformance: "EXTS", constraint: "desc", details: "If present, the Access Control Extensions may be used by Administrators to store arbitrary data " + "related to fabric’s Access Control Entries." + "\n" + "The Access Control Extension list shall support a single extension entry per supported fabric.", - xref: { document: "core", section: "9.10.5.4" } + xref: { document: "core", section: "9.10.6.4" } }, Field({ name: "entry", type: "AccessControlExtensionStruct" }) @@ -79,7 +165,7 @@ export const AccessControl = Cluster( "concern for a given implementation, it is recommended to only use the minimum value required and " + "avoid reporting a higher value than the required minimum.", - xref: { document: "core", section: "9.10.5.5" } + xref: { document: "core", section: "9.10.6.5" } }), Attribute({ @@ -94,7 +180,7 @@ export const AccessControl = Cluster( "concern for a given implementation, it is recommended to only use the minimum value required and " + "avoid reporting a higher value than the required minimum.", - xref: { document: "core", section: "9.10.5.6" } + xref: { document: "core", section: "9.10.6.6" } }), Attribute({ @@ -109,15 +195,70 @@ export const AccessControl = Cluster( "concern for a given implementation, it is recommended to only use the minimum value required and " + "avoid reporting a higher value than the required minimum.", - xref: { document: "core", section: "9.10.5.7" } + xref: { document: "core", section: "9.10.6.7" } }), + Attribute( + { + name: "CommissioningArL", id: 0x5, type: "list", access: "R V", conformance: "MNGD", + constraint: "desc", default: [], quality: "F", + + details: "This attribute shall provide the set of CommissioningAccessRestrictionEntryStruct applied during " + + "commissioning on a managed device." + + "\n" + + "When present, the CommissioningARL attribute shall indicate the access restrictions applying during " + + "commissioning." + + "\n" + + "Attempts to access data model elements described by an entry in the CommissioningARL attribute " + + "during commissioning shall result in an error of ACCESS_RESTRICTED. See Access Control Model for " + + "more information about the features related to controlling access to a Node’s Endpoint Clusters " + + "(\"Targets\" hereafter) from other Nodes." + + "\n" + + "See Section 9.10.4.2.1, “Managed Device Feature Usage Restrictions” for limitations on the use of " + + "access restrictions.", + + xref: { document: "core", section: "9.10.6.8" } + }, + + Field({ name: "entry", type: "CommissioningAccessRestrictionEntryStruct" }) + ), + + Attribute( + { + name: "Arl", id: 0x6, type: "list", access: "R F V", conformance: "MNGD", constraint: "desc", + default: [], + + details: "This attribute shall provide the set of AccessRestrictionEntryStruct applied to the associated " + + "fabric on a managed device." + + "\n" + + "When present, the ARL attribute shall indicate the access restrictions applying to the accessing " + + "fabric. In contrast, the CommissioningARL attribute indicates the accessing restrictions that apply " + + "when there is no accessing fabric, such as during commissioning." + + "\n" + + "The access restrictions are externally added/removed based on the particular relationship the " + + "device hosting this server has with external entities such as its owner, external service provider, " + + "or end-user." + + "\n" + + "Attempts to access data model elements described by an entry in the ARL attribute for the accessing " + + "fabric shall result in an error of ACCESS_RESTRICTED. See Access Control Model for more information " + + "about the features related to controlling access to a Node’s Endpoint Clusters (\"Targets\" " + + "hereafter) from other Nodes." + + "\n" + + "See Section 9.10.4.2.1, “Managed Device Feature Usage Restrictions” for limitations on the use of " + + "access restrictions.", + + xref: { document: "core", section: "9.10.6.9" } + }, + + Field({ name: "entry", type: "AccessRestrictionEntryStruct" }) + ), + Event( { name: "AccessControlEntryChanged", id: 0x0, access: "S A", conformance: "M", priority: "info", - details: "The cluster shall send AccessControlEntryChanged events whenever its ACL attribute data is changed " + - "by an Administrator." + + details: "The cluster shall generate AccessControlEntryChanged events whenever its ACL attribute data is " + + "changed by an Administrator." + "\n" + " • Each added entry shall generate an event with ChangeType Added." + "\n" + @@ -125,7 +266,7 @@ export const AccessControl = Cluster( "\n" + " • Each removed entry shall generate an event with ChangeType Removed.", - xref: { document: "core", section: "9.10.7.1" } + xref: { document: "core", section: "9.10.9.1" } }, Field({ @@ -135,7 +276,7 @@ export const AccessControl = Cluster( "\n" + "Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change " + "occurred via a CASE or PASE session; the other shall be null.", - xref: { document: "core", section: "9.10.7.1.1" } + xref: { document: "core", section: "9.10.9.1.1" } }), Field({ @@ -149,13 +290,13 @@ export const AccessControl = Cluster( "Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change " + "occurred via a CASE or PASE session; the other shall be null.", - xref: { document: "core", section: "9.10.7.1.2" } + xref: { document: "core", section: "9.10.9.1.2" } }), Field({ name: "ChangeType", id: 0x3, type: "ChangeTypeEnum", access: "S", conformance: "M", details: "The type of change as appropriate.", - xref: { document: "core", section: "9.10.7.1.3" } + xref: { document: "core", section: "9.10.9.1.3" } }), Field({ @@ -165,7 +306,7 @@ export const AccessControl = Cluster( "\n" + "This field SHOULD be set if resources are adequate for it; otherwise it shall be set to NULL if " + "resources are scarce.", - xref: { document: "core", section: "9.10.7.1.4" } + xref: { document: "core", section: "9.10.9.1.4" } }), Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) @@ -173,10 +314,11 @@ export const AccessControl = Cluster( Event( { - name: "AccessControlExtensionChanged", id: 0x1, access: "S A", conformance: "M", priority: "info", + name: "AccessControlExtensionChanged", id: 0x1, access: "S A", conformance: "EXTS", + priority: "info", - details: "The cluster shall send AccessControlExtensionChanged events whenever its extension attribute data " + - "is changed by an Administrator." + + details: "The cluster shall generate AccessControlExtensionChanged events whenever its extension attribute " + + "data is changed by an Administrator." + "\n" + " • Each added extension shall generate an event with ChangeType Added." + "\n" + @@ -184,7 +326,7 @@ export const AccessControl = Cluster( "\n" + " • Each removed extension shall generate an event with ChangeType Removed.", - xref: { document: "core", section: "9.10.7.2" } + xref: { document: "core", section: "9.10.9.2" } }, Field({ @@ -194,7 +336,7 @@ export const AccessControl = Cluster( "\n" + "Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change " + "occurred via a CASE or PASE session; the other shall be null.", - xref: { document: "core", section: "9.10.7.2.1" } + xref: { document: "core", section: "9.10.9.2.1" } }), Field({ @@ -208,13 +350,13 @@ export const AccessControl = Cluster( "Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change " + "occurred via a CASE or PASE session; the other shall be null.", - xref: { document: "core", section: "9.10.7.2.2" } + xref: { document: "core", section: "9.10.9.2.2" } }), Field({ name: "ChangeType", id: 0x3, type: "ChangeTypeEnum", access: "S", conformance: "M", details: "The type of change as appropriate.", - xref: { document: "core", section: "9.10.7.2.3" } + xref: { document: "core", section: "9.10.9.2.3" } }), Field({ @@ -224,14 +366,286 @@ export const AccessControl = Cluster( "\n" + "This field SHOULD be set if resources are adequate for it; otherwise it shall be set to NULL if " + "resources are scarce.", - xref: { document: "core", section: "9.10.7.2.4" } + xref: { document: "core", section: "9.10.9.2.4" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Event( + { + name: "FabricRestrictionReviewUpdate", id: 0x2, access: "S A", conformance: "MNGD", + priority: "info", + details: "The cluster shall generate a FabricRestrictionReviewUpdate event to indicate completion of a fabric " + + "restriction review. Due to the requirement to generate this event within a bound time frame of " + + "successful receipt of the ReviewFabricRestrictions command, this event may include additional steps " + + "that the client may present to the user in order to help the user locate the user interface for the " + + "Managed Device feature.", + xref: { document: "core", section: "9.10.9.3" } + }, + + Field({ + name: "Token", id: 0x0, type: "uint64", access: "S", conformance: "M", + details: "This field shall indicate the Token that can be used to correlate a " + + "ReviewFabricRestrictionsResponse with a FabricRestrictionReviewUpdate event.", + xref: { document: "core", section: "9.10.9.3.1" } + }), + + Field({ + name: "Instruction", id: 0x1, type: "string", access: "S", conformance: "O", constraint: "max 512", + + details: "This field shall provide human readable text that may be displayed to the user to help them locate " + + "the user interface for managing access restrictions for each fabric." + + "\n" + + "A device SHOULD implement the Localization Configuration Cluster when it has no other means to " + + "determine the locale to use for this text." + + "\n" + + "Examples include \"Please try again and immediately access device display for further instructions.\" " + + "or \"Please check email associated with your Acme account.\"", + + xref: { document: "core", section: "9.10.9.3.2" } }), + Field( + { + name: "ArlRequestFlowUrl", id: 0x2, type: "string", access: "S", conformance: "O", + constraint: "max 256", + + details: "This field shall indicate the URL for the service associated with the device maker which the user " + + "can visit to manage fabric limitations. The syntax of this field shall follow the syntax as " + + "specified in RFC 1738 and shall use the https scheme for internet-hosted URLs." + + "\n" + + " • The URL may embed the token, fabric index, fabric vendor, or other information transparently in " + + " order to pass context about the originating ReviewFabricRestrictions command to the service " + + " associated with the URL. The service associated with the device vendor may perform vendor ID " + + " verification on the fabric from which the ReviewFabricRestrictions command originated." + + "\n" + + " • If the device grants the request, the ARL attribute in the Access Control Cluster shall be " + + " updated to reflect the new access rights and a successful response shall be returned to the " + + " device making the request using the MTaer field of the callbackUrl. If the request is denied, " + + " the ARL attribute shall remain unchanged and a failure response shall be returned to the device " + + " making the request using the MTaer field of the callbackUrl." + + "\n" + + " • The device using this mechanism shall provide a service at the URL that can accept requests for " + + " additional access and return responses indicating whether the requests were granted or denied." + + "\n" + + " • This URL will typically lead to a server which (e.g. by looking at the User-Agent) redirects " + + " the user to allow viewing, downloading, installing or using a manufacturer-provided means for " + + " guiding the user through the process to review and approve or deny the request. The device " + + " manufacturer may choose to use a constructed URL which is valid in a HTTP GET request (i.e. " + + " dedicated for the product) such as, for example, https://domain.example/arl-app?vid=FFF1& " + + " pid=1234. If a client follows or launches the ARLRequestFlowUrl, it shall expand it as " + + " described in Section 9.10.9.3.4, “ARLRequestFlowUrl format”." + + "\n" + + " • A manufacturer contemplating using this flow should realize that" + + "\n" + + " ◦ This flow typically requires internet access to access the URL, and access extension may fail " + + " when internet connectivity is not available." + + "\n" + + " ◦ If the flow prefers to redirect the user to an app which is available on popular platforms, " + + " it SHOULD also provide a fallback option such as a web browser interface to ensure users can " + + " complete access extension." + + "\n" + + "### ARLRequestFlowUrl format" + + "\n" + + "The ARLRequestFlowUrl shall contain a query component (see RFC 3986 section 3.4) composed of one or " + + "more key-value pairs:" + + "\n" + + " • The query shall use the & delimiter between key/value pairs." + + "\n" + + " • The key-value pairs shall in the format name= where name is the key name, and " + + "\n" + + "is the contents of the value encoded with proper URL-encoded escaping." + + "\n" + + " • If key MTcu is present, it shall have a value of \"_\" (i.e. MTcu=_). This is the \"callback URL" + + "\n" + + "backUrl) placeholder\"." + + "\n" + + " • Any key whose name begins with MT not mentioned in the previous bullets shall be reserved for " + + " future use by this specification. Manufacturers shall NOT include query keys starting with MT " + + " in the ARLRequestFlowUrl unless they are referenced by a version of this specification." + + "\n" + + "Any other element in the ARLRequestFlowUrl query field not covered by the above rules, as well as " + + "the fragment field (if present), shall remain including the order of query key/value pairs present." + + "\n" + + "Expansion of ARLRequestFlowUrl by client" + + "\n" + + "Once the URL is obtained, it shall be expanded to form a final URL (ExpandedARLRequestFlowUrl) by " + + "proceeding with the following substitution algorithm on the original ARLRequestFlowUrl:" + + "\n" + + " 1. If key MTcu is present, compute the CallbackUrl desired (see Section 9.10.9.3.5, “CallbackUrl " + + " format for ARL Request Flow response”), and substitute the placeholder value \"_\" (i.e. in " + + " MTcu=_) in the ARLRequestFlowUrl with the desired contents, encoded with proper URL-encoded " + + " escaping (see RFC 3986 section 2)." + + "\n" + + "The final URL after expansion (ExpandedARLRequestFlowUrl) shall be the one to follow, rather than " + + "the original value obtained from the FabricRestrictionReviewUpdate event." + + "\n" + + "### CallbackUrl format for ARL Request Flow response" + + "\n" + + "If a CallbackUrl field (i.e. MTcu=) query field placeholder is present in the ARLRequestFlowUrl, " + + "the client may replace the placeholder value \"_\" in the ExpandedARLRequestFlowUrl with a URL that " + + "the manufacturer flow can use to make a smooth return to the client when the ARL flow has " + + "terminated." + + "\n" + + "This URL field may contain a query component (see RFC 3986 section 3.4). If a query is present, it " + + "shall be composed of one or more key-value pairs:" + + "\n" + + " • The query shall use the & delimiter between key/value pairs." + + "\n" + + " • The key-value pairs shall follow the format name= where name is the key name, and" + + "\n" + + " is the contents of the value encoded with proper URL-encoded escaping." + + "\n" + + " • If key MTaer is present, it shall have a value of \"_\" (i.e. MTaer=_). This is the placeholder " + + " for a \"access extension response\" provided by the manufacturer flow to the client. The " + + " manufacturer flow shall replace this placeholder with the final status of the access extension " + + " request, which shall be formatted following Expansion of CallbackUrl by the manufacturer custom " + + " flow and encoded with proper URL-encoded escaping." + + "\n" + + " • Any key whose name begins with MT not mentioned in the previous bullets shall be reserved for " + + " future use by this specification." + + "\n" + + "Any other element in the CallbackUrl query field not covered by the above rules, as well as the frag" + + "\n" + + "ment field (if present), shall remain as provided by the client through embedding within the" + + "\n" + + "ExpandedARLRequestFlowUrl, including the order of query key/value pairs present." + + "\n" + + "### Expansion of CallbackUrl by the manufacturer custom flow" + + "\n" + + "Once the CallbackUrl is obtained by the manufacturer flow, it may be expanded to form a final " + + "ExpandedARLRequestCallbackUrl URL to be used by proceeding with the following substitution " + + "algorithm on the provided CallbackUrl:" + + "\n" + + " • If key MTaer is present, the manufacturer custom flow having received the initial query " + + " containing the CallbackUrl shall substitute the placeholder value \"_\" (i.e. in MTaer=_) in the " + + " CallbackUrl with the final status of the access extension request flow which shall be one of " + + " the following. Any value returned in the MTaer field not listed above shall be considered an " + + " error and shall be treated as GeneralFailure." + + "\n" + + " ◦ Success - The flow completed successfully and the ARL attribute was updated. The client may " + + " now read the ARL attribute to determine the new access restrictions." + + "\n" + + " ◦ NoChange - The ARL attribute was already listing minimum restrictions for the requesting " + + " fabric." + + "\n" + + " ◦ GeneralFailure - The flow failed for an unspecified reason." + + "\n" + + " ◦ FlowAuthFailure - The user failed to authenticate to the flow." + + "\n" + + " ◦ NotFound - Access extension failed because the target fabric was not found." + + "\n" + + "A manufacturer custom flow having received an ExpandedARLRequestFlowUrl SHOULD attempt to open the " + + "ExpandedARLRequestCallbackUrl, on completion of the request, if an ExpandedARLRequestCallbackUrl " + + "was computed from the CallbackUrl and opening such a URL is supported." + + "\n" + + "Examples of ARLRequestFlowUrl URLs" + + "\n" + + "Below are some examples of valid ExpandedARLRequestFlowUrl for several valid values of " + + "ARLRequestFlowUrl, as well as some examples of invalid values of ARLRequestFlowUrl:" + + "\n" + + " • Invalid URL with no query string: http scheme is not allowed:" + + "\n" + + " ◦ http://company.domain.example/matter/arl/vFFF1p1234" + + "\n" + + " • Valid URL :" + + "\n" + + " ◦ https://company.domain.example/matter/arl/vFFF1p1234" + + "\n" + + " • Valid URL, CallbackUrl requested:" + + "\n" + + " ◦ Before expansion:" + + "\n" + + "https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTcu=_" + + "\n" + + " ◦ After expansion:" + + "\n" + + "https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTcu=https%3A%2F%2Fc " + + "lient.domain.example%2Fcb%3Ftoken%3DmAsJ6_vqbr-vjDiG_w%253D%253D%26MTaer%3D_" + + "\n" + + " ◦ The ExpandedARLRequestFlowUrl URL contains:" + + "\n" + + " ▪ A CallbackUrl with a client-provided arbitrary token= key/value pair and the MTaer= key/value " + + " pair place-holder to indicate support for a return access extension completion status: " + + " https://client.domain.example/cb?token=mAsJ6_vqbr-vjDiG_w%3D%3D&MTaer=_" + + "\n" + + " ▪ After expansion of the CallbackUrl (MTcu key) into an ExpandedCallbackUrl, with an example " + + " return access extension completion status of Success, the ExpandedARLRequestCallbackUrl would " + + " be:" + + "\n" + + "https://client.domain.example/cb?token=mAsJ6_vqbr- vjDiG_w%3D%3D&MTaer=Success" + + "\n" + + "Note that the MTcu key/value pair was initially provided URL-encoded within the " + + "ExpandedARLRequestFlowUrl URL and the MTaer=_ key/value pair placeholder now contains a substituted " + + "returned completion status." + + "\n" + + " • Invalid URL, due to MTza=79 key/value pair in reserved MT-prefixed keys reserved for future use:" + + "\n" + + " ◦ https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTop=_&MTza=79", + + xref: { document: "core", section: "9.10.9.3.3" } + } + ), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) ), + Command( + { + name: "ReviewFabricRestrictions", id: 0x0, access: "F A", conformance: "MNGD", direction: "request", + response: "ReviewFabricRestrictionsResponse", + + details: "This command signals to the service associated with the device vendor that the fabric administrator " + + "would like a review of the current restrictions on the accessing fabric. This command includes an " + + "optional list of ARL entries that the fabric administrator would like removed." + + "\n" + + "In response, a ReviewFabricRestrictionsResponse is sent which contains a token that can be used to " + + "correlate a review request with a FabricRestrictionReviewUpdate event." + + "\n" + + "Within 1 hour of the ReviewFabricRestrictionsResponse, the FabricRestrictionReviewUpdate event " + + "shall be generated, in order to indicate completion of the review and any additional steps required " + + "by the user for the review." + + "\n" + + "A review may include obtaining consent from the user, which can take time. For example, the user " + + "may need to respond to an email or a push notification." + + "\n" + + "The ARL attribute may change at any time due to actions taken by the user, or the service " + + "associated with the device vendor.", + + xref: { document: "core", section: "9.10.8.1" } + }, + + Field( + { + name: "Arl", id: 0x0, type: "list", conformance: "M", constraint: "desc", + details: "When the ARL field is provided, it indicates the specific restrictions that are requested for " + + "review. An empty list represents a generic request for review of all restrictions.", + xref: { document: "core", section: "9.10.8.1.1" } + }, + + Field({ name: "entry", type: "CommissioningAccessRestrictionEntryStruct" }) + ) + ), + + Command( + { + name: "ReviewFabricRestrictionsResponse", id: 0x1, conformance: "MNGD", direction: "response", + details: "Returns the review token for the request, which can be used to correlate with a " + + "FabricRestrictionReviewUpdate event.", + xref: { document: "core", section: "9.10.8.2" } + }, + + Field({ + name: "Token", id: 0x0, type: "uint64", conformance: "M", + details: "This field shall specify a Token that can be used to correlate a ReviewFabricRestrictionsResponse " + + "with a FabricRestrictionReviewUpdate event.", + xref: { document: "core", section: "9.10.8.2.1" } + }) + ), + Datatype( - { name: "ChangeTypeEnum", type: "enum8", xref: { document: "core", section: "9.10.4.1" } }, + { name: "ChangeTypeEnum", type: "enum8", xref: { document: "core", section: "9.10.5.1" } }, Field({ name: "Changed", id: 0x0, conformance: "M", description: "Entry or extension was changed" }), Field({ name: "Added", id: 0x1, conformance: "M", description: "Entry or extension was added" }), Field({ name: "Removed", id: 0x2, conformance: "M", description: "Entry or extension was removed" }) @@ -243,7 +657,7 @@ export const AccessControl = Cluster( details: "Proxy View Value" + "\n" + "This value implicitly grants View privileges", - xref: { document: "core", section: "9.10.4.2" } + xref: { document: "core", section: "9.10.5.2" } }, Field({ @@ -259,40 +673,60 @@ export const AccessControl = Cluster( name: "Operate", id: 0x3, conformance: "M", description: "View privileges, and can perform the primary function of this Node (except Access Control Cluster)", details: "This value implicitly grants View privileges", - xref: { document: "core", section: "9.10.4.2.1" } + xref: { document: "core", section: "9.10.5.2.1" } }), Field({ name: "Manage", id: 0x4, conformance: "M", description: "Operate privileges, and can modify persistent configuration of this Node (except Access Control Cluster)", details: "This value implicitly grants Operate & View privileges", - xref: { document: "core", section: "9.10.4.2.2" } + xref: { document: "core", section: "9.10.5.2.2" } }), Field({ name: "Administer", id: 0x5, conformance: "M", description: "Manage privileges, and can observe and modify the Access Control Cluster", details: "This value implicitly grants Manage, Operate, Proxy View & View privileges", - xref: { document: "core", section: "9.10.4.2.3" } + xref: { document: "core", section: "9.10.5.2.3" } + }) + ), + + Datatype( + { name: "AccessRestrictionTypeEnum", type: "enum8", xref: { document: "core", section: "9.10.5.3" } }, + Field({ + name: "AttributeAccessForbidden", id: 0x0, conformance: "M", + description: "Clients on this fabric are currently forbidden from reading and writing an attribute" + }), + Field({ + name: "AttributeWriteForbidden", id: 0x1, conformance: "M", + description: "Clients on this fabric are currently forbidden from writing an attribute" + }), + Field({ + name: "CommandForbidden", id: 0x2, conformance: "M", + description: "Clients on this fabric are currently forbidden from invoking a command" + }), + Field({ + name: "EventForbidden", id: 0x3, conformance: "M", + description: "Clients on this fabric are currently forbidden from reading an event" }) ), Datatype( - { name: "AccessControlEntryAuthModeEnum", type: "enum8", xref: { document: "core", section: "9.10.4.3" } }, + { name: "AccessControlEntryAuthModeEnum", type: "enum8", xref: { document: "core", section: "9.10.5.4" } }, Field({ name: "Pase", id: 0x1, conformance: "M", description: "Passcode authenticated session" }), Field({ name: "Case", id: 0x2, conformance: "M", description: "Certificate authenticated session" }), Field({ name: "Group", id: 0x3, conformance: "M", description: "Group authenticated session" }) ), Datatype( - { name: "AccessControlTargetStruct", type: "struct", xref: { document: "core", section: "9.10.4.4" } }, + { name: "AccessControlTargetStruct", type: "struct", xref: { document: "core", section: "9.10.5.5" } }, Field({ name: "Cluster", id: 0x0, type: "cluster-id", conformance: "M", quality: "X" }), Field({ name: "Endpoint", id: 0x1, type: "endpoint-no", conformance: "M", quality: "X" }), Field({ name: "DeviceType", id: 0x2, type: "devtype-id", conformance: "M", quality: "X" }) ), Datatype( - { name: "AccessControlEntryStruct", type: "struct", xref: { document: "core", section: "9.10.4.5" } }, + { name: "AccessControlEntryStruct", type: "struct", xref: { document: "core", section: "9.10.5.6" } }, Field({ name: "Privilege", id: 0x1, type: "AccessControlEntryPrivilegeEnum", access: "S", conformance: "M", @@ -309,7 +743,7 @@ export const AccessControl = Cluster( "privilege levels as well. The following diagram illustrates how the higher privilege levels subsume " + "the lower privilege levels:" + "\n" + - "Figure 43. Access Control Privilege Levels" + + "Figure 46. Access Control Privilege Levels" + "\n" + "Individual clusters shall define whether attributes are readable, writable, or both readable and " + "writable. Clusters also shall define which privilege is minimally required to be able to perform a " + @@ -320,13 +754,13 @@ export const AccessControl = Cluster( "Control Cluster itself. The Administer privilege shall NOT be used on Access Control Entries which " + "use the Group auth mode.", - xref: { document: "core", section: "9.10.4.5.1" } + xref: { document: "core", section: "9.10.5.6.1" } }), Field({ name: "AuthMode", id: 0x2, type: "AccessControlEntryAuthModeEnum", access: "S", conformance: "M", details: "The AuthMode field shall specify the authentication mode required by this Access Control Entry.", - xref: { document: "core", section: "9.10.4.5.2" } + xref: { document: "core", section: "9.10.5.6.2" } }), Field( @@ -351,7 +785,7 @@ export const AccessControl = Cluster( "that successfully authenticates via AuthMode. The subjects list shall NOT be empty if the entry’s " + "AuthMode is PASE." + "\n" + - "The PASE AuthMode is reserved for future use (see Section 6.6.2.8, “Bootstrapping of the Access " + + "The PASE AuthMode is reserved for future use (see Section 6.6.2.9, “Bootstrapping of the Access " + "Control Cluster”). An attempt to write an entry with AuthMode set to PASE shall fail with a status " + "code of CONSTRAINT_ERROR." + "\n" + @@ -368,7 +802,7 @@ export const AccessControl = Cluster( "For Group authentication, the Group ID identifies the required group, as defined in the Group Key " + "Management Cluster.", - xref: { document: "core", section: "9.10.4.5.3" } + xref: { document: "core", section: "9.10.5.6.3" } }, Field({ name: "entry", type: "subject-id" }) @@ -398,7 +832,7 @@ export const AccessControl = Cluster( "An empty targets list indicates a wildcard: that is, this entry shall grant access to all cluster " + "instances on all endpoints on this Node.", - xref: { document: "core", section: "9.10.4.5.4" } + xref: { document: "core", section: "9.10.5.6.4" } }, Field({ name: "entry", type: "AccessControlTargetStruct" }) @@ -408,12 +842,13 @@ export const AccessControl = Cluster( ), Datatype( - { name: "AccessControlExtensionStruct", type: "struct", xref: { document: "core", section: "9.10.4.6" } }, + { name: "AccessControlExtensionStruct", type: "struct", xref: { document: "core", section: "9.10.5.7" } }, Field({ name: "Data", id: 0x1, type: "octstr", access: "S", conformance: "M", constraint: "max 128", - details: "This field may be used by manufacturers to store arbitrary TLV-encoded data related to a fabric’s " + + details: "This field may be used by manufacturers to store arbitrary TLV-encoded data related to a fabric’s" + + "\n" + "Access Control Entries." + "\n" + "The contents shall consist of a top-level anonymous list; each list element shall include a " + @@ -423,10 +858,114 @@ export const AccessControl = Cluster( "discretion. The content of each element is not specified, but may be coordinated among " + "manufacturers at their discretion.", - xref: { document: "core", section: "9.10.4.6.1" } + xref: { document: "core", section: "9.10.5.7.1" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "AccessRestrictionStruct", type: "struct", + details: "This structure describes an access restriction that would be applied to a specific data model " + + "element on a given endpoint/cluster pair (see AccessRestrictionEntryStruct).", + xref: { document: "core", section: "9.10.5.8" } + }, + + Field({ + name: "Type", id: 0x0, type: "AccessRestrictionTypeEnum", conformance: "M", + details: "This field shall indicate the type of restriction, for example, AttributeAccessForbidden.", + xref: { document: "core", section: "9.10.5.8.1" } + }), + + Field({ + name: "Id", id: 0x1, type: "uint32", conformance: "M", quality: "X", + + details: "This field shall indicate the element Manufacturer Extensible Identifier (MEI) associated with the " + + "element type subject to the access restriction, based upon the AccessRestrictionTypeEnum. When the " + + "Type is AttributeAccessForbidden or AttributeWriteForbidden, this value shall be considered of type " + + "attrib-id (i.e. an attribute identifier). When the Type is CommandForbidden, this value shall be " + + "considered of type command-id (i.e. an attribute identifier). When the Type is EventForbidden, this " + + "value shall be considered of type event-id (i.e. an event identifier)." + + "\n" + + "A null value shall indicate the wildcard value for the given value of Type (i.e. all elements " + + "associated with the Type under the associated endpoint and cluster for the containing " + + "AccessRestrictionEntryStruct).", + + xref: { document: "core", section: "9.10.5.8.2" } + }) + ), + + Datatype( + { + name: "AccessRestrictionEntryStruct", type: "struct", + details: "This structure describes a current access restriction on the fabric.", + xref: { document: "core", section: "9.10.5.9" } + }, + + Field({ + name: "Endpoint", id: 0x0, type: "endpoint-no", access: "S", conformance: "M", + details: "This field shall indicate the endpoint having associated access restrictions scoped to the " + + "associated fabric of the list containing the entry.", + xref: { document: "core", section: "9.10.5.9.1" } + }), + + Field({ + name: "Cluster", id: 0x1, type: "cluster-id", access: "S", conformance: "M", + details: "This field shall indicate the cluster having associated access restrictions under the entry’s " + + "Endpoint, scoped to the associated fabric of the list containing the entry.", + xref: { document: "core", section: "9.10.5.9.2" } }), + Field( + { + name: "Restrictions", id: 0x2, type: "list", access: "S", conformance: "M", constraint: "min 1", + details: "This field shall indicate the set of restrictions applying to the Cluster under the given Endpoint, " + + "scoped to the associated fabric of the list containing the entry." + + "\n" + + "This list shall NOT be empty.", + xref: { document: "core", section: "9.10.5.9.3" } + }, + + Field({ name: "entry", type: "AccessRestrictionStruct" }) + ), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "CommissioningAccessRestrictionEntryStruct", type: "struct", + details: "This structure describes a current access restriction when there is no accessing fabric.", + xref: { document: "core", section: "9.10.5.10" } + }, + + Field({ + name: "Endpoint", id: 0x0, type: "endpoint-no", conformance: "M", + details: "This field shall indicate the endpoint having associated access restrictions scoped to the " + + "associated fabric of the list containing the entry.", + xref: { document: "core", section: "9.10.5.10.1" } + }), + + Field({ + name: "Cluster", id: 0x1, type: "cluster-id", conformance: "M", + details: "This field shall indicate the cluster having associated access restrictions under the entry’s " + + "Endpoint, scoped to the associated fabric of the list containing the entry.", + xref: { document: "core", section: "9.10.5.10.2" } + }), + + Field( + { + name: "Restrictions", id: 0x2, type: "list", conformance: "M", constraint: "min 1", + details: "This field shall indicate the set of restrictions applying to the Cluster under the given Endpoint, " + + "scoped to the associated fabric of the list containing the entry." + + "\n" + + "This list shall NOT be empty.", + xref: { document: "core", section: "9.10.5.10.3" } + }, + + Field({ name: "entry", type: "AccessRestrictionStruct" }) + ) ) ); diff --git a/packages/model/src/standard/elements/AccountLogin.ts b/packages/model/src/standard/elements/AccountLogin.ts index f66ec3fd70..5c2491356d 100644 --- a/packages/model/src/standard/elements/AccountLogin.ts +++ b/packages/model/src/standard/elements/AccountLogin.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/Actions.ts b/packages/model/src/standard/elements/Actions.ts index 8f01b55cee..1318e9520f 100644 --- a/packages/model/src/standard/elements/Actions.ts +++ b/packages/model/src/standard/elements/Actions.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -25,9 +25,8 @@ export const Actions = Cluster( "\n" + " • Information about logical grouping of endpoints on the Node (example: lights in a room)" + "\n" + - " • Information about named actions that can be performed on such a group of endpoints" + - "\n" + - "ple: recall a scene for a group of lights by its name)" + + " • Information about named actions that can be performed on such a group of endpoints (example: " + + " recall a scene for a group of lights by its name)" + "\n" + " • Commands to trigger such actions" + "\n" + @@ -90,8 +89,8 @@ export const Actions = Cluster( name: "SetupUrl", id: 0x2, type: "string", access: "R V", conformance: "O", constraint: "max 512", details: "The SetupURL attribute (when provided) shall indicate a URL; its syntax shall follow the syntax as " + - "specified in RFC 3986, max. 512 ASCII characters. The location referenced by this URL shall provide " + - "additional information for the actions provided:" + + "specified in RFC 1738, max. 512 ASCII characters and shall use the https scheme. The location " + + "referenced by this URL shall provide additional information for the actions provided:" + "\n" + " • When used without suffix, it shall provide information about the various actions which the " + " cluster provides." + @@ -506,7 +505,9 @@ export const Actions = Cluster( "InstantActionWithTransition), or to bring these endpoints into a more dynamic state (typically " + "using StartAction), where the endpoints would e.g. gradually cycle through certain colors for a " + "pleasing effect. A voice controller could use \"set\" (to map to InstantAction) or \"play\" (to map to " + - "StartAction) to trigger such actions." + + "StartAction) to trig" + + "\n" + + "ger such actions." + "\n" + "Example: see examples 1 and 2.", @@ -618,11 +619,13 @@ export const Actions = Cluster( description: "User-configured group of endpoints where an endpoint can be in any number of zones", details: "Is a more general concept where an endpoint can be part of multiple zones, e.g. a light in the " + - "living room can be part of the \"reading corner\" zone (subset of the lights in the living room) but " + - "also part of the \"downstairs\" zone which contains all the lights on a floor, e.g. combining living " + - "room, kitchen and hallway. This indicates that a user has defined this list of endpoints as " + - "something they logically would like to control as a group, so Matter controllers could provide the " + - "user with a way to do as such.", + "living" + + "\n" + + "room can be part of the \"reading corner\" zone (subset of the lights in the living room) but also " + + "part of the \"downstairs\" zone which contains all the lights on a floor, e.g. combining living room, " + + "kitchen and hallway. This indicates that a user has defined this list of endpoints as something " + + "they logically would like to control as a group, so Matter controllers could provide the user with " + + "a way to do as such.", xref: { document: "core", section: "9.14.4.5.3" } }) @@ -641,7 +644,7 @@ export const Actions = Cluster( }), Field({ - name: "Name", id: 0x1, type: "string", conformance: "M", constraint: "max 32[128]", + name: "Name", id: 0x1, type: "string", conformance: "M", constraint: "max 128{32}", details: "This field shall indicate the name (as assigned by the user or automatically by the server) " + "associated with this action. This can be used for identifying the action to the user by the client. " + "Example: \"my colorful scene\".", @@ -693,7 +696,7 @@ export const Actions = Cluster( }), Field({ - name: "Name", id: 0x1, type: "string", conformance: "M", constraint: "max 32[128]", + name: "Name", id: 0x1, type: "string", conformance: "M", constraint: "max 128{32}", details: "This field shall indicate the name (as assigned by the user or automatically by the server) " + "associated with the set of endpoints in this list. This can be used for identifying the action to " + "the user by the client. Example: \"living room\".", diff --git a/packages/model/src/standard/elements/ActivatedCarbonFilterMonitoring.ts b/packages/model/src/standard/elements/ActivatedCarbonFilterMonitoring.ts index 29f9f28bcf..1db8ca786b 100644 --- a/packages/model/src/standard/elements/ActivatedCarbonFilterMonitoring.ts +++ b/packages/model/src/standard/elements/ActivatedCarbonFilterMonitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/AdministratorCommissioning.ts b/packages/model/src/standard/elements/AdministratorCommissioning.ts index b5e30f29d6..5c4787b3df 100644 --- a/packages/model/src/standard/elements/AdministratorCommissioning.ts +++ b/packages/model/src/standard/elements/AdministratorCommissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -27,7 +27,22 @@ export const AdministratorCommissioning = Cluster( "supported and is described in Section 5.6.3, “Enhanced Commissioning Method (ECM)”." + "\n" + "For the management of Operational Credentials and Trusted Root Certificates, the Node Operational " + - "Credentials cluster is used.", + "Credentials cluster is used." + + "\n" + + "If the Administrator Commissioning Cluster server instance is present on an endpoint with the Root " + + "Node device type in the Descriptor cluster DeviceTypeList, then:" + + "\n" + + " • The Commissioning Window shall be opened or closed on the node that the Root Node endpoint is " + + " on." + + "\n" + + " • The attributes shall indicate the state of the node that the Root Node endpoint is on." + + "\n" + + "If the Administrator Commissioning Cluster server instance is present on an endpoint with the " + + "Bridged Node device type in the Descriptor cluster DeviceTypeList, then:" + + "\n" + + " • The Commissioning Window shall be opened or closed on the node represented by the Bridged Node." + + "\n" + + " • The attributes shall indicate the state of the node that is represented by the Bridged Node.", xref: { document: "core", section: "11.19" } }, @@ -43,12 +58,15 @@ export const AdministratorCommissioning = Cluster( conformance: "M", details: "Indicates whether a new Commissioning window has been opened by an Administrator, using either the " + - "OCW command or the OBCW command." + + "OpenCommissioningWindow command or the OpenBasicCommissioningWindow command." + "\n" + "This attribute shall revert to WindowNotOpen upon expiry of a commissioning window." + "\n" + - "Note that an initial commissioning window is not opened using either the OCW command or the OBCW " + - "command, and therefore this attribute shall be set to WindowNotOpen on initial commissioning.", + "NOTE" + + "\n" + + "An initial commissioning window is not opened using either the OpenCommissioningWindow command or " + + "the OpenBasicCommissioningWindow command, and therefore this attribute shall be set to " + + "WindowNotOpen on initial commissioning.", xref: { document: "core", section: "11.19.7.1" } }), @@ -92,13 +110,14 @@ export const AdministratorCommissioning = Cluster( details: "This command is used by a current Administrator to instruct a Node to go into commissioning mode. " + "The Enhanced Commissioning Method specifies a window of time during which an already commissioned " + "Node accepts PASE sessions. The current Administrator MUST specify a timeout value for the duration " + - "of OCW." + + "of the OpenCommissioningWindow command." + "\n" + - "When OCW expires or commissioning completes, the Node shall remove the Passcode by deleting the " + - "PAKE passcode verifier as well as stop publishing the DNS-SD record corresponding to this command " + - "as described in Section 4.3.1, “Commissionable Node Discovery”. The commissioning into a new Fabric " + - "completes when the Node successfully receives a CommissioningComplete command, see Section 5.5, " + - "“Commissioning Flows”." + + "When the OpenCommissioningWindow command expires or commissioning completes, the Node shall remove " + + "the Passcode by deleting the PAKE passcode verifier as well as stop publishing the DNS-SD record " + + "corresponding to this command as described in Section 4.3.1, “Commissionable" + + "\n" + + "Node Discovery”. The commissioning into a new Fabric completes when the Node successfully receives " + + "a CommissioningComplete command, see Section 5.5, “Commissioning Flows”." + "\n" + "The parameters for OpenCommissioningWindow command are as follows:" + "\n" + @@ -125,14 +144,11 @@ export const AdministratorCommissioning = Cluster( Field({ name: "CommissioningTimeout", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", - details: "This field shall specify the time in seconds during which commissioning session establishment is " + - "allowed by the Node. This is known as Open Commissioning Window (OCW). This timeout value shall " + - "follow guidance as specified in the initial Announcement Duration. The CommissioningTimeout applies " + - "only to cessation of any announcements and to accepting of new commissioning sessions; it does not " + - "apply to abortion of connections, i.e., a commissioning session SHOULD NOT abort prematurely upon " + - "expiration of this timeout.", - + "allowed by the Node. This timeout value shall follow guidance as specified in the initial " + + "Announcement Duration. The CommissioningTimeout applies only to cessation of any announcements and " + + "to accepting of new commissioning sessions; it does not apply to abortion of connections, i.e., a " + + "commissioning session SHOULD NOT abort prematurely upon expiration of this timeout.", xref: { document: "core", section: "11.19.8.1.1" } }), @@ -144,8 +160,8 @@ export const AdministratorCommissioning = Cluster( "this commissioning. The field is concatenation of two values (w0 || L) shall be " + "(CRYPTO_GROUP_SIZE_BYTES + CRYPTO_PUBLIC_KEY_SIZE_BYTES)-octets long as detailed in " + "Crypto_PAKEValues_Responder. It shall be derived from an ephemeral passcode (See PAKE). It shall be " + - "deleted by the Node at the end of commissioning or expiration of OCW, and shall be deleted by the " + - "existing Administrator after sending it to the Node(s).", + "deleted by the Node at the end of commissioning or expiration of the OpenCommissioningWindow " + + "command, and shall be deleted by the existing Administrator after sending it to the Node(s).", xref: { document: "core", section: "11.19.8.1.2" } }), @@ -161,14 +177,11 @@ export const AdministratorCommissioning = Cluster( Field({ name: "Iterations", id: 0x3, type: "uint32", conformance: "M", constraint: "1000 to 100000", - details: "This field shall be used by the Node as the PAKE iteration count associated with the ephemeral PAKE " + "passcode verifier to be used for this commissioning, which shall be sent by the Node to the new " + - "Administrator’s software as response to the PBKDFParamRequest during PASE negotiation." + - "\n" + - "The permitted range of values shall match the range specified in Section 3.9, “Password-Based Key " + + "Administrator’s software as response to the PBKDFParamRequest during PASE negotiation. The " + + "permitted range of values shall match the range specified in Section 3.9, “Password-Based Key " + "Derivation Function (PBKDF)”, within the definition of the Crypto_PBKDFParameterSet.", - xref: { document: "core", section: "11.19.8.1.4" } }), @@ -183,9 +196,8 @@ export const AdministratorCommissioning = Cluster( "\n" + "When a Node receives the Open Commissioning Window command, it shall begin advertising on DNS-SD as " + "described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as described in " + - "Section 11.19.8.1.1, “CommissioningTimeout Field”. When the command is received by a ICD, it shall " + - "enter into active mode. The ICD shall remain in Active Mode as long as one of these conditions is " + - "met:" + + "CommissioningTimeout. When the command is received by a ICD, it shall enter into active mode. The " + + "ICD shall remain in Active Mode as long as one of these conditions is met:" + "\n" + " • A commissioning window is open." + "\n" + @@ -203,7 +215,8 @@ export const AdministratorCommissioning = Cluster( details: "This command may be used by a current Administrator to instruct a Node to go into commissioning " + "mode, if the node supports the Basic Commissioning Method. The Basic Commissioning Method specifies " + "a window of time during which an already commissioned Node accepts PASE sessions. The current " + - "Administrator shall specify a timeout value for the duration of OBCW." + + "Administrator shall specify a timeout value for the duration of the OpenBasicCommissioningWindow " + + "command." + "\n" + "If a commissioning window is already currently open, this command shall fail with a cluster " + "specific status code of Busy." + @@ -225,14 +238,13 @@ export const AdministratorCommissioning = Cluster( name: "CommissioningTimeout", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", details: "This field shall specify the time in seconds during which commissioning session establishment is " + - "allowed by the Node. This is known as Open Basic Commissioning Window (OBCW). This timeout shall " + - "follow guidance as specified in the initial Announcement Duration." + + "allowed by the Node. This timeout shall follow guidance as specified in the initial Announcement " + + "Duration." + "\n" + - "When a Node receives the Open Basic Commissioning Window command, it shall begin advertising on " + - "DNS-SD as described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as " + - "described in Section 11.19.8.2.1, “CommissioningTimeout Field”. When the command is received by a " + - "ICD, it shall enter into active mode. The ICD shall remain in Active Mode as long as one of these " + - "conditions is met:" + + "When a Node receives the OpenBasicCommissioningWindow command, it shall begin advertising on DNS-SD " + + "as described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as described " + + "in CommissioningTimeout. When the command is received by a ICD, it shall enter into active mode. " + + "The ICD shall remain in Active Mode as long as one of these conditions is met:" + "\n" + " • A commissioning window is open." + "\n" + @@ -246,18 +258,19 @@ export const AdministratorCommissioning = Cluster( name: "RevokeCommissioning", id: 0x2, access: "A T", conformance: "M", direction: "request", response: "status", - details: "This command is used by a current Administrator to instruct a Node to revoke any active Open " + - "Commissioning Window or Open Basic Commissioning Window command. This is an idempotent command and " + + details: "This command is used by a current Administrator to instruct a Node to revoke any active " + + "OpenCommissioningWindow or OpenBasicCommissioningWindow command. This is an idempotent command and " + "the Node shall (for ECM) delete the temporary PAKEPasscodeVerifier and associated data, and stop " + - "publishing the DNS-SD record associated with the Open Commissioning Window or Open Basic " + - "Commissioning Window command, see Section 4.3.1, “Commissionable Node Discovery”." + + "publishing the DNS-SD record associated with the OpenCommissioningWindow or " + + "OpenBasicCommissioningWindow command, see Section 4.3.1, “Commissionable Node Discovery”." + "\n" + "If no commissioning window was open at time of receipt, this command shall fail with a cluster " + "specific status code of WindowNotOpen." + "\n" + "If the commissioning window was open and the fail-safe was armed when this command is received, the " + - "device shall immediately expire the fail-safe and perform the cleanup steps outlined in Section " + - "11.10.6.2.2, “Behavior on expiry of Fail-Safe timer”.", + "device shall immediately expire the fail-safe and perform the cleanup steps outlined" + + "\n" + + "in Section 11.10.7.2.2, “Behavior on expiry of Fail-Safe timer”.", xref: { document: "core", section: "11.19.8.3" } }), @@ -277,12 +290,15 @@ export const AdministratorCommissioning = Cluster( Datatype( { name: "StatusCodeEnum", type: "enum8", xref: { document: "core", section: "11.19.6.1" } }, - Field({ name: "Busy", id: 0x2, description: "Could not be completed because another commissioning is in progress" }), Field({ - name: "PakeParameterError", id: 0x3, + name: "Busy", id: 0x2, conformance: "M", + description: "Could not be completed because another commissioning is in progress" + }), + Field({ + name: "PakeParameterError", id: 0x3, conformance: "M", description: "Provided PAKE parameters were incorrectly formatted or otherwise invalid" }), - Field({ name: "WindowNotOpen", id: 0x4, description: "No commissioning window was currently open" }) + Field({ name: "WindowNotOpen", id: 0x4, conformance: "M", description: "No commissioning window was currently open" }) ) ); diff --git a/packages/model/src/standard/elements/AggregatorDT.ts b/packages/model/src/standard/elements/AggregatorDT.ts index eea78b5644..10b1a9a4fc 100644 --- a/packages/model/src/standard/elements/AggregatorDT.ts +++ b/packages/model/src/standard/elements/AggregatorDT.ts @@ -1,20 +1,24 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MatterDefinition } from "../MatterDefinition.js"; -import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; +import { + DeviceTypeElement as DeviceType, + RequirementElement as Requirement, + FieldElement as Field +} from "../../elements/index.js"; export const AggregatorDt = DeviceType( { name: "Aggregator", id: 0xe, category: "Generic", classification: "simple", details: "This device type aggregates endpoints as a collection. Clusters on the endpoint indicating this " + - "device type provide functionality for the collection of descendent endpoints present in the " + + "device type provide functionality for the collection of descendant endpoints present in the " + "PartsList of the endpoint’s descriptor, for example the Actions cluster." + "\n" + "The purpose of this device type is to aggregate functionality for a collection of endpoints. The " + @@ -28,7 +32,7 @@ export const AggregatorDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 14, revision: 1 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 14, revision: 2 } ], element: "attribute" }) ), Requirement({ name: "Actions", id: 0x25, conformance: "O", element: "serverCluster", @@ -37,7 +41,20 @@ export const AggregatorDt = DeviceType( Requirement({ name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", xref: { document: "device", section: "11.2.4" } - }) + }), + Requirement({ + name: "CommissionerControl", id: 0x751, conformance: "FabricSynchronization", + element: "serverCluster", + xref: { document: "device", section: "11.2.4" } + }), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "FabricSynchronization", description: "See description below.", + xref: { document: "device", section: "11.2.3" } + }) + ) ); MatterDefinition.children.push(AggregatorDt); diff --git a/packages/model/src/standard/elements/AirPurifierDT.ts b/packages/model/src/standard/elements/AirPurifierDT.ts index 912dd9e46c..315a00687c 100644 --- a/packages/model/src/standard/elements/AirPurifierDT.ts +++ b/packages/model/src/standard/elements/AirPurifierDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -21,7 +21,7 @@ export const AirPurifierDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 45, revision: 1 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 45, revision: 2 } ], element: "attribute" }) ), Requirement({ name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", @@ -31,6 +31,10 @@ export const AirPurifierDt = DeviceType( name: "Groups", id: 0x4, conformance: "O", element: "serverCluster", xref: { document: "device", section: "9.3.5" } }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.3.5" } + }), Requirement({ name: "FanControl", id: 0x202, conformance: "M", element: "serverCluster", xref: { document: "device", section: "9.3.5" } diff --git a/packages/model/src/standard/elements/AirQuality.ts b/packages/model/src/standard/elements/AirQuality.ts index 436777df7b..66631433d8 100644 --- a/packages/model/src/standard/elements/AirQuality.ts +++ b/packages/model/src/standard/elements/AirQuality.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/AirQualitySensorDT.ts b/packages/model/src/standard/elements/AirQualitySensorDT.ts index 52e09fe79e..29c9e262a6 100644 --- a/packages/model/src/standard/elements/AirQualitySensorDT.ts +++ b/packages/model/src/standard/elements/AirQualitySensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/AlarmBase.ts b/packages/model/src/standard/elements/AlarmBase.ts index 166acdb084..4280072904 100644 --- a/packages/model/src/standard/elements/AlarmBase.ts +++ b/packages/model/src/standard/elements/AlarmBase.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -145,8 +145,7 @@ export const AlarmBase = Cluster( "currently enabled alarm shall respond with a status code of FAILURE; otherwise the server shall " + "respond with a status code of SUCCESS." + "\n" + - "On a SUCCESS case, the server shall also change the value of the Mask attribute to the value of the" + - "\n" + + "On a SUCCESS case, the server shall also change the value of the Mask attribute to the value of the " + "Mask field from this command. After that the server shall also update the value of its State " + "attribute to reflect the status of the new alarm set as indicated by the new value of the Mask " + "attribute.", diff --git a/packages/model/src/standard/elements/ApplicationBasic.ts b/packages/model/src/standard/elements/ApplicationBasic.ts index a01c643ffd..ffe48ca6ae 100644 --- a/packages/model/src/standard/elements/ApplicationBasic.ts +++ b/packages/model/src/standard/elements/ApplicationBasic.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ApplicationLauncher.ts b/packages/model/src/standard/elements/ApplicationLauncher.ts index c7511f3d42..e059efa944 100644 --- a/packages/model/src/standard/elements/ApplicationLauncher.ts +++ b/packages/model/src/standard/elements/ApplicationLauncher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -33,7 +33,7 @@ export const ApplicationLauncher = Cluster( xref: { document: "cluster", section: "6.4" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "6.4.4" } }, @@ -158,10 +158,10 @@ export const ApplicationLauncher = Cluster( "The endpoint may decide to stop the application based on manufacturer specific behavior or resource " + "constraints if any. The Status attribute shall be updated to ActiveHidden or Stopped, depending on " + "the action taken, on the Application Basic cluster of the Endpoint corresponding to the application " + - "on which the action was taken. The Status attribute shall be updated on any other" + + "on which the action was taken. The Status attribute shall be updated on any other application whose " + + "Status may have changed as a result of this command." + "\n" + - "application whose Status may have changed as a result of this command. This command returns a " + - "Launcher Response.", + "This command returns a Launcher Response.", xref: { document: "cluster", section: "6.4.7.3" } }, @@ -194,8 +194,14 @@ export const ApplicationLauncher = Cluster( Datatype( { name: "StatusEnum", type: "enum8", xref: { document: "cluster", section: "6.4.5.1" } }, Field({ name: "Success", id: 0x0, conformance: "M", description: "Command succeeded" }), - Field({ name: "AppNotAvailable", id: 0x1, conformance: "M", description: "Requested app is not available." }), - Field({ name: "SystemBusy", id: 0x2, conformance: "M", description: "Video platform unable to honor command." }) + Field({ name: "AppNotAvailable", id: 0x1, conformance: "M", description: "Requested app is not available" }), + Field({ name: "SystemBusy", id: 0x2, conformance: "M", description: "Video platform unable to honor command" }), + Field({ + name: "PendingUserApproval", id: 0x3, conformance: "M", + description: "User approval for app download is pending" + }), + Field({ name: "Downloading", id: 0x4, conformance: "M", description: "Downloading the requested app" }), + Field({ name: "Installing", id: 0x5, conformance: "M", description: "Installing the requested app" }) ), Datatype( diff --git a/packages/model/src/standard/elements/AreaNamespaceNS.ts b/packages/model/src/standard/elements/AreaNamespaceNS.ts new file mode 100644 index 0000000000..22601bd26c --- /dev/null +++ b/packages/model/src/standard/elements/AreaNamespaceNS.ts @@ -0,0 +1,129 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + SemanticNamespaceElement as SemanticNamespace, + SemanticTagElement as SemanticTag +} from "../../elements/index.js"; + +export const AreaNamespaceNs = SemanticNamespace( + { + name: "AreaNamespace", id: 0x10, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with an indoor or outdoor area of a home.", + xref: { document: "namespace", section: "13" } + }, + + SemanticTag({ name: "Aisle", id: 0x0 }), + SemanticTag({ name: "Attic", id: 0x1 }), + SemanticTag({ name: "Back Door", id: 0x2 }), + SemanticTag({ name: "Back Yard", id: 0x3 }), + SemanticTag({ name: "Balcony", id: 0x4 }), + SemanticTag({ name: "Ballroom", id: 0x5 }), + SemanticTag({ name: "Bathroom", id: 0x6, description: "Also known as Restroom" }), + SemanticTag({ name: "Bedroom", id: 0x7 }), + SemanticTag({ name: "Border", id: 0x8 }), + SemanticTag({ name: "Boxroom", id: 0x9, description: "A small room typically used for storage" }), + SemanticTag({ name: "Breakfast Room", id: 0xa }), + SemanticTag({ name: "Carport", id: 0xb }), + SemanticTag({ name: "Cellar", id: 0xc }), + SemanticTag({ name: "Cloakroom", id: 0xd }), + SemanticTag({ name: "Closet", id: 0xe }), + SemanticTag({ name: "Conservatory", id: 0xf }), + SemanticTag({ name: "Corridor", id: 0x10 }), + SemanticTag({ name: "Craft Room", id: 0x11 }), + SemanticTag({ name: "Cupboard", id: 0x12 }), + SemanticTag({ name: "Deck", id: 0x13 }), + SemanticTag({ + name: "Den", id: 0x14, + description: "A small, comfortable room for individual activities such as work or hobbies" + }), + SemanticTag({ name: "Dining", id: 0x15 }), + SemanticTag({ name: "Drawing Room", id: 0x16 }), + SemanticTag({ name: "Dressing Room", id: 0x17 }), + SemanticTag({ name: "Driveway", id: 0x18 }), + SemanticTag({ name: "Elevator", id: 0x19 }), + SemanticTag({ name: "Ensuite", id: 0x1a, description: "A bathroom directly accessible from a bedroom" }), + SemanticTag({ name: "Entrance", id: 0x1b }), + SemanticTag({ name: "Entryway", id: 0x1c }), + SemanticTag({ name: "Family Room", id: 0x1d }), + SemanticTag({ name: "Foyer", id: 0x1e }), + SemanticTag({ name: "Front Door", id: 0x1f }), + SemanticTag({ name: "Front Yard", id: 0x20 }), + SemanticTag({ name: "Game Room", id: 0x21 }), + SemanticTag({ name: "Garage", id: 0x22 }), + SemanticTag({ name: "Garage Door", id: 0x23 }), + SemanticTag({ name: "Garden", id: 0x24 }), + SemanticTag({ name: "Garden Door", id: 0x25 }), + SemanticTag({ name: "Guest Bathroom", id: 0x26, description: "Also known as Guest Restroom" }), + SemanticTag({ name: "Guest Bedroom", id: 0x27 }), + SemanticTag({ name: "Guest Room", id: 0x28 }), + SemanticTag({ name: "Gym", id: 0x29 }), + SemanticTag({ name: "Hallway", id: 0x2a }), + SemanticTag( + { name: "Hearth Room", id: 0x2b, description: "A cozy room containing a fireplace or other point heat source" } + ), + SemanticTag({ name: "Kids Room", id: 0x2c }), + SemanticTag({ name: "Kids Bedroom", id: 0x2d }), + SemanticTag({ name: "Kitchen", id: 0x2e }), + SemanticTag({ name: "Laundry Room", id: 0x2f }), + SemanticTag({ name: "Lawn", id: 0x30 }), + SemanticTag({ name: "Library", id: 0x31 }), + SemanticTag({ name: "Living Room", id: 0x32 }), + SemanticTag({ name: "Lounge", id: 0x33 }), + SemanticTag({ name: "Media/TV Room", id: 0x34 }), + SemanticTag({ + name: "Mud Room", id: 0x35, + description: "A space used to remove soiled garments prior to entering the domicile proper" + }), + SemanticTag({ name: "Music Room", id: 0x36 }), + SemanticTag({ name: "Nursery", id: 0x37 }), + SemanticTag({ name: "Office", id: 0x38 }), + SemanticTag({ name: "Outdoor Kitchen", id: 0x39 }), + SemanticTag({ name: "Outside", id: 0x3a }), + SemanticTag({ name: "Pantry", id: 0x3b, description: "AKA a larder, a place where food is stored" }), + SemanticTag({ name: "Parking Lot", id: 0x3c }), + SemanticTag({ name: "Parlor", id: 0x3d }), + SemanticTag({ name: "Patio", id: 0x3e }), + SemanticTag({ name: "Play Room", id: 0x3f }), + SemanticTag({ name: "Pool Room", id: 0x40 }), + SemanticTag({ name: "Porch", id: 0x41 }), + SemanticTag({ name: "Primary Bathroom", id: 0x42 }), + SemanticTag({ name: "Primary Bedroom", id: 0x43 }), + SemanticTag({ name: "Ramp", id: 0x44 }), + SemanticTag({ name: "Reception Room", id: 0x45 }), + SemanticTag({ name: "Recreation Room", id: 0x46 }), + SemanticTag({ name: "Roof", id: 0x47 }), + SemanticTag({ name: "Sauna", id: 0x48 }), + SemanticTag({ name: "Scullery", id: 0x49, description: "A utility space for cleaning dishes and laundry" }), + SemanticTag({ name: "Sewing Room", id: 0x4a }), + SemanticTag({ name: "Shed", id: 0x4b }), + SemanticTag({ name: "Side Door", id: 0x4c }), + SemanticTag({ name: "Side Yard", id: 0x4d }), + SemanticTag({ name: "Sitting Room", id: 0x4e }), + SemanticTag({ + name: "Snug", id: 0x4f, + description: "An informal space meant to be 'cozy', 'snug', relaxed, meant to share with family or friends" + }), + SemanticTag({ name: "Spa", id: 0x50 }), + SemanticTag({ name: "Staircase", id: 0x51 }), + SemanticTag({ name: "Steam Room", id: 0x52 }), + SemanticTag({ name: "Storage Room", id: 0x53 }), + SemanticTag({ name: "Studio", id: 0x54 }), + SemanticTag({ name: "Study", id: 0x55 }), + SemanticTag({ name: "Sun Room", id: 0x56 }), + SemanticTag({ name: "Swimming Pool", id: 0x57 }), + SemanticTag({ name: "Terrace", id: 0x58 }), + SemanticTag({ name: "Toilet", id: 0x59, description: "A room dedicated to a toilet; a water closet / WC" }), + SemanticTag({ name: "Utility Room", id: 0x5a }), + SemanticTag({ name: "Ward", id: 0x5b }), + SemanticTag({ name: "Workshop", id: 0x5c }) +); + +MatterDefinition.children.push(AreaNamespaceNs); diff --git a/packages/model/src/standard/elements/AtomicAttributeStatusStruct.ts b/packages/model/src/standard/elements/AtomicAttributeStatusStruct.ts new file mode 100644 index 0000000000..bdfbc50308 --- /dev/null +++ b/packages/model/src/standard/elements/AtomicAttributeStatusStruct.ts @@ -0,0 +1,30 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DatatypeElement as Datatype, FieldElement as Field } from "../../elements/index.js"; + +export const AtomicAttributeStatusStruct = Datatype( + { + name: "AtomicAttributeStatusStruct", type: "struct", + details: "This struct indicates the status of an attribute during an atomic write.", + xref: { document: "core", section: "7.15.5" } + }, + Field({ + name: "AttributeId", id: 0x0, type: "attrib-id", conformance: "M", + details: "This field shall indicate the ID of the attribute with the associated StatusCode.", + xref: { document: "core", section: "7.15.5.1" } + }), + Field({ + name: "StatusCode", id: 0x1, type: "status", conformance: "M", + details: "This field shall indicate the atomic status of an attribute.", + xref: { document: "core", section: "7.15.5.2" } + }) +); + +MatterDefinition.children.push(AtomicAttributeStatusStruct); diff --git a/packages/model/src/standard/elements/AtomicRequestTypeEnum.ts b/packages/model/src/standard/elements/AtomicRequestTypeEnum.ts new file mode 100644 index 0000000000..de2c92c296 --- /dev/null +++ b/packages/model/src/standard/elements/AtomicRequestTypeEnum.ts @@ -0,0 +1,22 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DatatypeElement as Datatype, FieldElement as Field } from "../../elements/index.js"; + +export const AtomicRequestTypeEnum = Datatype( + { name: "AtomicRequestTypeEnum", type: "enum8", xref: { document: "core", section: "7.15.4" } }, + Field({ name: "BeginWrite", id: 0x0, conformance: "M", description: "Begin an atomic write" }), + Field({ name: "CommitWrite", id: 0x1, conformance: "M", description: "Commit an atomic write" }), + Field({ + name: "RollbackWrite", id: 0x2, conformance: "M", + description: "Rollback an atomic write, discarding any pending changes" + }) +); + +MatterDefinition.children.push(AtomicRequestTypeEnum); diff --git a/packages/model/src/standard/elements/AttributeList.ts b/packages/model/src/standard/elements/AttributeList.ts index 9257097772..5af9f054e4 100644 --- a/packages/model/src/standard/elements/AttributeList.ts +++ b/packages/model/src/standard/elements/AttributeList.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/AudioOutput.ts b/packages/model/src/standard/elements/AudioOutput.ts index 0f85da411a..b5686e78d7 100644 --- a/packages/model/src/standard/elements/AudioOutput.ts +++ b/packages/model/src/standard/elements/AudioOutput.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/BallastConfiguration.ts b/packages/model/src/standard/elements/BallastConfiguration.ts index 88b16e75de..44014bbef5 100644 --- a/packages/model/src/standard/elements/BallastConfiguration.ts +++ b/packages/model/src/standard/elements/BallastConfiguration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -71,12 +71,12 @@ export const BallastConfiguration = Cluster( constraint: "minLevel to physicalMaxLevel", default: { type: "reference", name: "PhysicalMaxLevel" }, - details: "This attribute shall specify the light output of the ballast according to the dimming light curve" + - "\n" + + details: "This attribute shall specify the light output of the ballast according to the dimming light curve " + "(see Dimming Curve) when the Level Control Cluster’s CurrentLevel attribute equals to 254 (and the " + "On/Off Cluster’s OnOff attribute equals to TRUE)." + "\n" + - "The value of this attribute shall be both less than or equal to PhysicalMaxLevel and greater than " + + "The value of this attribute shall be both less than or equal to PhysicalMaxLevel and greater than" + + "\n" + "or equal to MinLevel. If an attempt is made to set this attribute to a level where these conditions " + "are not met, a response shall be returned with status code set to CONSTRAINT_ERROR, and the level " + "shall NOT be set.", diff --git a/packages/model/src/standard/elements/BaseDT.ts b/packages/model/src/standard/elements/BaseDT.ts index 003c06a18a..bc890fec3c 100644 --- a/packages/model/src/standard/elements/BaseDT.ts +++ b/packages/model/src/standard/elements/BaseDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/BasicInformation.ts b/packages/model/src/standard/elements/BasicInformation.ts index 2bc2c34464..4167573c97 100644 --- a/packages/model/src/standard/elements/BasicInformation.ts +++ b/packages/model/src/standard/elements/BasicInformation.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,7 @@ export const BasicInformation = Cluster( xref: { document: "core", section: "11.1" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), Attribute({ name: "DataModelRevision", id: 0x0, type: "uint16", access: "R V", conformance: "M", @@ -160,17 +160,15 @@ export const BasicInformation = Cluster( xref: { document: "core", section: "11.1.5.13" } }), - Attribute( - { - name: "ProductUrl", id: 0xd, type: "string", access: "R V", conformance: "O", constraint: "max 256", - quality: "F", - details: "This attribute shall specify a link to a product specific web page. The syntax of the ProductURL " + - "attribute shall follow the syntax as specified in RFC 3986 [https://tools.ietf.org/html/rfc3986]. " + - "The specified URL SHOULD resolve to a maintained web page available for the lifetime of the " + - "product. The maximum length of the ProductUrl attribute is 256 ASCII characters.", - xref: { document: "core", section: "11.1.5.14" } - } - ), + Attribute({ + name: "ProductUrl", id: 0xd, type: "string", access: "R V", conformance: "O", constraint: "max 256", + quality: "F", + details: "This attribute shall specify a link to a product specific web page. The specified URL SHOULD " + + "resolve to a maintained web page available for the lifetime of the product. The syntax of this " + + "attribute shall follow the syntax as specified in RFC 1738 and shall use the https scheme. The " + + "maximum length of this attribute is 256 ASCII characters.", + xref: { document: "core", section: "11.1.5.14" } + }), Attribute({ name: "ProductLabel", id: 0xe, type: "string", access: "R V", conformance: "O", @@ -210,23 +208,34 @@ export const BasicInformation = Cluster( }), Attribute({ - name: "UniqueId", id: 0x12, type: "string", access: "R V", conformance: "O", constraint: "max 32", + name: "UniqueId", id: 0x12, type: "string", access: "R V", conformance: "M", constraint: "max 32", quality: "F", - details: "This attribute (when used) shall indicate a unique identifier for the device, which is constructed " + - "in a manufacturer specific manner." + + details: "Indicates a unique identifier for the device, which is constructed in a manufacturer specific " + + "manner." + "\n" + "It may be constructed using a permanent device identifier (such as device MAC address) as basis. In " + "order to prevent tracking," + "\n" + " • it SHOULD NOT be identical to (or easily derived from) such permanent device identifier" + "\n" + - " • it SHOULD be updated when the device is factory reset" + + " • it shall be updated when the device is factory reset" + + "\n" + + " • it shall NOT be identical to the SerialNumber attribute" + + "\n" + + " • it shall NOT be printed on the product or delivered with the product" + "\n" + - " • it shall not be identical to the SerialNumber attribute" + + "The value does not need to be human readable, since it is intended for machine to machine (M2M) " + + "communication." + "\n" + - " • it shall not be printed on the product or delivered with the product The value does not need to " + - " be human readable.", + "NOTE" + + "\n" + + "NOTE" + + "\n" + + "The conformance of the UniqueID attribute was optional in cluster revisions prior to revision 4." + + "\n" + + "This UniqueID attribute shall NOT be the same as the Persistent Unique ID which is used in the " + + "Rotating Device Identifier mechanism.", xref: { document: "core", section: "11.1.5.19" } }), @@ -245,7 +254,8 @@ export const BasicInformation = Cluster( "rely on the amounts provided in this attribute." + "\n" + "Note that since the fixed values within this attribute may change over time, both increasing and " + - "decreasing, as software versions change for a given Node, clients SHOULD take care not to assume " + + "decreasing, as software versions change for a given Node, clients SHOULD take care not to assume" + + "\n" + "forever unchanging values and SHOULD NOT cache this value permanently at Commissioning time.", xref: { document: "core", section: "11.1.5.20" } @@ -307,9 +317,8 @@ export const BasicInformation = Cluster( details: "Indicates the maximum number of elements in a single InvokeRequests list (see Section 8.8.2, " + "“Invoke Request Action”) that the Node is able to process. Note that since this attribute may " + "change over time, both increasing and decreasing, as software versions change for a given Node, " + - "clients SHOULD take care not to assume forever unchanging values and SHOULD NOT" + - "\n" + - "cache this value permanently at Commissioning time." + + "clients SHOULD take care not to assume forever unchanging values and SHOULD NOT cache this value " + + "permanently at Commissioning time." + "\n" + "If the MaxPathsPerInvoke attribute is absent or zero, such as in Basic Information cluster " + "revisions prior to Revision 3, clients shall assume a value of 1.", @@ -353,8 +362,7 @@ export const BasicInformation = Cluster( "Leave event is generated, it SHOULD be assumed that the fabric recorded in the event is no longer " + "usable, and subsequent interactions targeting that fabric will most likely fail." + "\n" + - "Upon receipt of Leave Event on a subscription, the receiving Node may update other nodes in the" + - "\n" + + "Upon receipt of Leave Event on a subscription, the receiving Node may update other nodes in the " + "fabric by removing related bindings, access control list entries and other data referencing the " + "leaving Node.", diff --git a/packages/model/src/standard/elements/BasicVideoPlayerDT.ts b/packages/model/src/standard/elements/BasicVideoPlayerDT.ts index 926bd61c3a..6ba1652c30 100644 --- a/packages/model/src/standard/elements/BasicVideoPlayerDT.ts +++ b/packages/model/src/standard/elements/BasicVideoPlayerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/BatteryStorageDT.ts b/packages/model/src/standard/elements/BatteryStorageDT.ts new file mode 100644 index 0000000000..465c26c6cf --- /dev/null +++ b/packages/model/src/standard/elements/BatteryStorageDT.ts @@ -0,0 +1,36 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const BatteryStorageDt = DeviceType( + { + name: "BatteryStorage", id: 0x18, category: "Energy", classification: "simple", + + details: "A Battery Storage device is a device that allows a DC battery, which can optionally be comprised of " + + "a set parallel strings of battery packs and associated controller, and an AC inverter, to be " + + "monitored and controlled by an Energy Management System in order to manage the peaks and troughs of " + + "supply and demand, and/or to optimize cost of the energy consumed in premises. It is not intended " + + "to be used for a UPS directly supplying a set of appliances, nor for portable battery storage " + + "devices.", + + xref: { document: "device", section: "14.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 24, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.4.6" } + }) +); + +MatterDefinition.children.push(BatteryStorageDt); diff --git a/packages/model/src/standard/elements/Binding.ts b/packages/model/src/standard/elements/Binding.ts index c349304988..6e57c7c357 100644 --- a/packages/model/src/standard/elements/Binding.ts +++ b/packages/model/src/standard/elements/Binding.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/BooleanState.ts b/packages/model/src/standard/elements/BooleanState.ts index 088355e3c9..1899b1c207 100644 --- a/packages/model/src/standard/elements/BooleanState.ts +++ b/packages/model/src/standard/elements/BooleanState.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/BooleanStateConfiguration.ts b/packages/model/src/standard/elements/BooleanStateConfiguration.ts index 76c5555599..fd176b8d31 100644 --- a/packages/model/src/standard/elements/BooleanStateConfiguration.ts +++ b/packages/model/src/standard/elements/BooleanStateConfiguration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -63,7 +63,7 @@ export const BooleanStateConfiguration = Cluster( Attribute({ name: "CurrentSensitivityLevel", id: 0x0, type: "uint8", access: "RW VO", conformance: "SENSLVL", - constraint: "max SupportedSensitivityLevels - 1", quality: "N", + constraint: "max supportedSensitivityLevels - 1", quality: "N", details: "Indicates the currently selected sensitivity level." + "\n" + "If a write interaction to this attribute contains an unsupported sensitivity value, a " + @@ -89,7 +89,7 @@ export const BooleanStateConfiguration = Cluster( Attribute({ name: "DefaultSensitivityLevel", id: 0x2, type: "uint8", access: "R V", conformance: "[SENSLVL]", - constraint: "max SupportedSensitivityLevels - 1", quality: "F", + constraint: "max supportedSensitivityLevels - 1", quality: "F", details: "Indicates the default sensitivity level selected by the manufacturer.", xref: { document: "cluster", section: "1.8.6.3" } }), diff --git a/packages/model/src/standard/elements/BridgedDeviceBasicInformation.ts b/packages/model/src/standard/elements/BridgedDeviceBasicInformation.ts index 03401d5e6b..d753062183 100644 --- a/packages/model/src/standard/elements/BridgedDeviceBasicInformation.ts +++ b/packages/model/src/standard/elements/BridgedDeviceBasicInformation.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,8 +10,9 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, + FieldElement as Field, EventElement as Event, - FieldElement as Field + CommandElement as Command } from "../../elements/index.js"; export const BridgedDeviceBasicInformation = Cluster( @@ -19,10 +20,11 @@ export const BridgedDeviceBasicInformation = Cluster( name: "BridgedDeviceBasicInformation", id: 0x39, type: "BasicInformation", classification: "endpoint", pics: "BRBINFO", - details: "This Cluster serves two purposes towards a Node communicating with a Bridge:" + + details: "This cluster is a derived cluster of the Basic Information cluster and serves two purposes towards " + + "a Node communicating with a Bridge:" + "\n" + - " • Indicate that the functionality on the Endpoint where it is placed (and its Parts) is bridged " + - " from a non-Matter technology, and" + + " • Indicate that the functionality on the Endpoint where it is placed (and its Parts) is bridged, " + + " and" + "\n" + " • Provide a centralized collection of attributes that the Node may collect to aid in conveying " + " information regarding the Bridged Device to a user, such as the vendor name, the model name, or " + @@ -48,34 +50,72 @@ export const BridgedDeviceBasicInformation = Cluster( xref: { document: "core", section: "9.13" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), - Attribute({ name: "DataModelRevision", id: 0x0, conformance: "X", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "VendorName", id: 0x1, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "VendorId", id: 0x2, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "ProductName", id: 0x3, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "ProductId", id: 0x4, conformance: "X", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "NodeLabel", id: 0x5, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "Location", id: 0x6, conformance: "X", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "HardwareVersion", id: 0x7, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "HardwareVersionString", id: 0x8, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "SoftwareVersion", id: 0x9, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "SoftwareVersionString", id: 0xa, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "ManufacturingDate", id: 0xb, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "PartNumber", id: 0xc, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "ProductUrl", id: 0xd, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "ProductLabel", id: 0xe, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "SerialNumber", id: 0xf, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "LocalConfigDisabled", id: 0x10, conformance: "X", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "Reachable", id: 0x11, conformance: "M", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "UniqueId", id: 0x12, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "CapabilityMinima", id: 0x13, conformance: "X", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "ProductAppearance", id: 0x14, conformance: "O", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "SpecificationVersion", id: 0x15, conformance: "X", xref: { document: "core", section: "9.13.4" } }), - Attribute({ name: "MaxPathsPerInvoke", id: 0x16, conformance: "X", xref: { document: "core", section: "9.13.4" } }), - Event({ name: "StartUp", id: 0x0, conformance: "O", priority: "critical", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "9.13.4" } }, + Field({ + name: "BIS", conformance: "O", constraint: "20", description: "BridgedIcdSupport", + details: "Support bridged ICDs." + }) + ), + + Attribute({ name: "DataModelRevision", id: 0x0, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "VendorName", id: 0x1, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "VendorId", id: 0x2, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductName", id: 0x3, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductId", id: 0x4, conformance: "desc", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "NodeLabel", id: 0x5, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "Location", id: 0x6, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "HardwareVersion", id: 0x7, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "HardwareVersionString", id: 0x8, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "SoftwareVersion", id: 0x9, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "SoftwareVersionString", id: 0xa, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ManufacturingDate", id: 0xb, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "PartNumber", id: 0xc, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductUrl", id: 0xd, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductLabel", id: 0xe, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "SerialNumber", id: 0xf, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "LocalConfigDisabled", id: 0x10, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + + Attribute({ + name: "Reachable", id: 0x11, conformance: "M", + + details: "This attribute shall be used to indicate whether the bridged device is reachable by the bridge, so " + + "a Matter Node which wants to communicate with a bridged device can get an indication that this " + + "might fail (when the attribute is False). Determination of reachability might not be perfect (e.g. " + + "depending on technology employed), so the Matter Node SHOULD be aware of the risk of false " + + "positives and negatives on reachability determination. For example, a bridged device may be marked " + + "as unreachable while it could actually be reached, and vice-versa. Also, detection (and indication) " + + "that a bridged device is not longer reachable may be delayed due to the technique employed (e.g. " + + "detecting that a number of expected messages from the bridged device did not arrive). Also see " + + "event ReachableChanged below.", + + xref: { document: "core", section: "9.13.5.1" } + }), + + Attribute({ + name: "UniqueId", id: 0x12, conformance: "M", + + details: "This attribute shall, for a Bridged Device, be updated when the Bridge is factory reset. If the " + + "bridged device does not provide some unique id (e.g. in the case of bridging from non-Matter " + + "devices, or in case of bridging Matter devices from an earlier revision which were not required to " + + "provide a UniqueID attribute), the bridge shall generate a unique id on behalf of the bridged " + + "device." + + "\n" + + "NOTE The UniqueID attribute was optional in cluster revisions prior to revision 4.", + + xref: { document: "core", section: "9.13.5.2" } + }), + + Attribute({ name: "CapabilityMinima", id: 0x13, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "ProductAppearance", id: 0x14, conformance: "O", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "SpecificationVersion", id: 0x15, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Attribute({ name: "MaxPathsPerInvoke", id: 0x16, conformance: "X", xref: { document: "core", section: "9.13.5" } }), + Event({ name: "StartUp", id: 0x0, conformance: "O", priority: "critical", xref: { document: "core", section: "9.13.7" } }), Event({ name: "ShutDown", id: 0x1, conformance: "O", priority: "critical", - xref: { document: "core", section: "9.13.5" } + xref: { document: "core", section: "9.13.7" } }), Event( @@ -91,7 +131,7 @@ export const BridgedDeviceBasicInformation = Cluster( "context of Bridged Device Basic Information cluster, has no usable fields, but the original Basic " + "Information cluster’s field definition is kept for completeness.", - xref: { document: "core", section: "9.13.5.1" } + xref: { document: "core", section: "9.13.7.1" } }, Field({ name: "FabricIndex", id: 0x0, conformance: "X" }) @@ -100,12 +140,107 @@ export const BridgedDeviceBasicInformation = Cluster( Event({ name: "ReachableChanged", id: 0x3, conformance: "M", priority: "critical", details: "This event shall be generated when there is a change in the Reachable attribute. Its purpose is to " + - "provide an indication towards interested parties that the reachability of a bridged device (over " + - "the non-Matter network) has changed, so they may take appropriate action." + + "provide an indication towards interested parties that the reachability of a bridged device has " + + "changed over its native connectivity technology, so they may take appropriate action." + "\n" + "After (re)start of a bridge this event may be generated.", - xref: { document: "core", section: "9.13.5.2" } - }) + xref: { document: "core", section: "9.13.7.2" } + }), + + Event( + { + name: "ActiveChanged", id: 0x80, access: "V", conformance: "BIS", priority: "info", + details: "This event (when supported) shall be generated the next time a bridged device becomes active after " + + "a KeepActive command is received." + + "\n" + + "See KeepActive for more details.", + xref: { document: "core", section: "9.13.7.3" } + }, + + Field({ + name: "PromisedActiveDuration", id: 0x0, type: "uint32", conformance: "M", constraint: "desc", + + details: "This field shall indicate the minimum duration, in milliseconds, that the bridged device will " + + "remain active after receiving the initial request from the KeepActive processing steps." + + "\n" + + "If the bridged device is a Matter Intermittently Connected Device, PromisedActiveDuration shall be " + + "set to the PromisedActiveDuration value returned in the StayActiveResponse command." + + "\n" + + "If the bridged device is not a Matter Intermittently Connected Device, the implementation of this " + + "is best-effort since it may interact with non-native protocol.", + + xref: { document: "core", section: "9.13.7.3.1" } + }) + ), + + Command( + { + name: "KeepActive", id: 0x80, access: "O", conformance: "BIS", direction: "request", + response: "status", + + details: "Upon receipt, the server shall attempt to keep the bridged device active for the duration specified " + + "by the command, when the device is next active." + + "\n" + + "The implementation of this is best-effort since it may interact with non-native protocols. However, " + + "several specific protocol requirements are:" + + "\n" + + " • If the bridged device is a Matter Intermittently Connected Device, then the server shall send a " + + " StayActiveRequest command with the StayActiveDuration field set to value of the " + + " StayActiveDuration field in the received command to the bridged device when the bridged device " + + " next sends a checks-in message or subscription report. See Intermittently Connected Devices " + + " Behavior for details on ICD state management." + + "\n" + + "When the bridge detects that the bridged device goes into an active state, an ActiveChanged event " + + "shall be generated." + + "\n" + + "In order to avoid unnecessary power consumption in the bridged device:" + + "\n" + + " • The server shall enter a \"pending active\" state for the associated device when the KeepActive " + + " command is received. The server \"pending active\" state shall expire after the amount of time " + + " defined by the TimeoutMs field, in milliseconds, if no subsequent KeepActive command is " + + " received. When a KeepActive command is received, the \"pending active\" state is set, the " + + " StayActiveDuration is updated to the greater of the new value and the previously stored value, " + + " and the TimeoutMs is updated to the greater of the new value and the remaining time until the " + + " prior \"pending active\" state expires." + + "\n" + + " • The server shall only keep the bridged device active once for a request. (The server shall only " + + " consider the operation performed if an associated ActiveChanged event was generated.)", + + xref: { document: "core", section: "9.13.6.1" } + }, + + Field({ + name: "StayActiveDuration", id: 0x0, type: "uint32", conformance: "M", + + details: "This field shall indicate the duration, in milliseconds, that the device is requested to remain " + + "active, once the device becomes active again." + + "\n" + + "The value of this field may be longer than the value supported by the bridged device and would, " + + "typically, be used by the client to request the server of the bridged device to stay active and " + + "responsive for this period to allow a sequence of message exchanges during that period." + + "\n" + + "The client may slightly overestimate the duration it wants the bridged device to be active for, in " + + "order to account for network delays.", + + xref: { document: "core", section: "9.13.6.1.1" } + }), + + Field({ + name: "TimeoutMs", id: 0x1, type: "uint32", conformance: "M", constraint: "30000 to 3600000", + + details: "This field shall indicate the period, in milliseconds, that the server will wait before the " + + "\"pending active\" state expires. See the KeepActive Command description for details." + + "\n" + + "NOTE" + + "\n" + + "TimeoutMs is a timeout for the request, NOT the time the device will be awake for. The server will " + + "wait for up to TimeoutMs for the device. If after TimeoutMs the ICD" + + "\n" + + "device does NOT check-in, the server will not perform any actions.", + + xref: { document: "core", section: "9.13.6.1.2" } + }) + ) ) MatterDefinition.children.push(BridgedDeviceBasicInformation); diff --git a/packages/model/src/standard/elements/BridgedNodeDT.ts b/packages/model/src/standard/elements/BridgedNodeDT.ts index 6717805f28..810e1b9f6c 100644 --- a/packages/model/src/standard/elements/BridgedNodeDT.ts +++ b/packages/model/src/standard/elements/BridgedNodeDT.ts @@ -1,13 +1,17 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MatterDefinition } from "../MatterDefinition.js"; -import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; +import { + DeviceTypeElement as DeviceType, + RequirementElement as Requirement, + FieldElement as Field +} from "../../elements/index.js"; export const BridgedNodeDt = DeviceType( { @@ -21,7 +25,7 @@ export const BridgedNodeDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 19, revision: 2 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 19, revision: 3 } ], element: "attribute" }) ), Requirement({ name: "BridgedDeviceBasicInformation", id: 0x39, conformance: "M", element: "serverCluster", @@ -35,7 +39,25 @@ export const BridgedNodeDt = DeviceType( Requirement({ name: "PowerSource", id: 0x2f, conformance: "BridgedPowerSourceInfo", element: "serverCluster", xref: { document: "device", section: "2.5.5" } - }) + }), + Requirement({ + name: "EcosystemInformation", id: 0x750, conformance: "FabricSynchronizedNode, O", + element: "serverCluster", + xref: { document: "device", section: "2.5.5" } + }), + Requirement({ + name: "AdministratorCommissioning", id: 0x3c, conformance: "FabricSynchronizedNode", + element: "serverCluster", + xref: { document: "device", section: "2.5.5" } + }), + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "FabricSynchronizedNode", description: "See description below.", + xref: { document: "device", section: "2.5.3" } + }) + ) ); MatterDefinition.children.push(BridgedNodeDt); diff --git a/packages/model/src/standard/elements/CarbonDioxideConcentrationMeasurement.ts b/packages/model/src/standard/elements/CarbonDioxideConcentrationMeasurement.ts index 68c0a431f3..3632c57860 100644 --- a/packages/model/src/standard/elements/CarbonDioxideConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/CarbonDioxideConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/CarbonMonoxideConcentrationMeasurement.ts b/packages/model/src/standard/elements/CarbonMonoxideConcentrationMeasurement.ts index f160cb4b63..2d9dd90d36 100644 --- a/packages/model/src/standard/elements/CarbonMonoxideConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/CarbonMonoxideConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/CastingVideoClientDT.ts b/packages/model/src/standard/elements/CastingVideoClientDT.ts index 1229193b43..af9a05e3e1 100644 --- a/packages/model/src/standard/elements/CastingVideoClientDT.ts +++ b/packages/model/src/standard/elements/CastingVideoClientDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/CastingVideoPlayerDT.ts b/packages/model/src/standard/elements/CastingVideoPlayerDT.ts index 9a70775b20..9367d3e9b6 100644 --- a/packages/model/src/standard/elements/CastingVideoPlayerDT.ts +++ b/packages/model/src/standard/elements/CastingVideoPlayerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/Channel.ts b/packages/model/src/standard/elements/Channel.ts index e971f5ae24..31a175ae51 100644 --- a/packages/model/src/standard/elements/Channel.ts +++ b/packages/model/src/standard/elements/Channel.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,13 +17,18 @@ import { export const Channel = Cluster( { - name: "Channel", id: 0x504, asOf: "1.3", classification: "application", pics: "CHANNEL", + name: "Channel", id: 0x504, classification: "application", pics: "CHANNEL", details: "This cluster provides an interface for controlling the current Channel on a device or endpoint." + "\n" + "This cluster server would be supported on Video Player devices or endpoints that allow Channel " + "control such as a Content App. This cluster provides a list of available channels and provides " + - "commands for absolute and relative channel changes." + + "commands for absolute and relative channel changes. Some of these commands and/or their responses " + + "may be large (see Large Message Quality under Data Model section in [MatterCore]), but they do not " + + "have the Large quality indicator (L) because they can also be transferred over MRP (see Message " + + "Reliability Protocol in [MatterCore]) in pages that fit within the MRP MTU limit. However, an " + + "implementation may leverage a transport like TCP that allows large payloads, if available, to " + + "minimize the number of messages required to transfer the corresponding payload." + "\n" + "The cluster server for Channel is implemented by an endpoint that controls the current Channel.", @@ -106,7 +111,7 @@ export const Channel = Cluster( xref: { document: "cluster", section: "6.6.7.2.1" } }), Field({ - name: "Data", id: 0x1, type: "string", conformance: "O", + name: "Data", id: 0x1, type: "string", conformance: "O", constraint: "any", details: "This field shall indicate Optional app-specific data.", xref: { document: "cluster", section: "6.6.7.2.2" } }) @@ -163,14 +168,10 @@ export const Channel = Cluster( { name: "GetProgramGuide", id: 0x4, access: "O", conformance: "EG", direction: "request", response: "ProgramGuideResponse", - details: "This command retrieves the program guide. It accepts several filter parameters to return specific " + "schedule and program information from a content app. The command shall receive in response a " + - "ProgramGuideResponse. Standard error codes shall be used when arguments provided are not" + - "\n" + - "valid. For example, if StartTime is greater than EndTime, the status code INVALID_ACTION shall be " + - "returned.", - + "ProgramGuideResponse. Standard error codes shall be used when arguments provided are not valid. For " + + "example, if StartTime is greater than EndTime, the status code INVALID_ACTION shall be returned.", xref: { document: "cluster", section: "6.6.7.5" } }, @@ -221,7 +222,7 @@ export const Channel = Cluster( details: "This field shall indicate the list of additional external content identifiers.", xref: { document: "cluster", section: "6.6.7.5.6" } }, - Field({ name: "entry", type: "AdditionalInfoStruct" }) + Field({ name: "entry", type: "ContentLauncher.AdditionalInfoStruct" }) ), Field({ @@ -285,7 +286,7 @@ export const Channel = Cluster( details: "This field, if present, shall indicate the list of additional external content identifiers.", xref: { document: "cluster", section: "6.6.7.7.3" } }, - Field({ name: "entry", type: "AdditionalInfoStruct" }) + Field({ name: "entry", type: "ContentLauncher.AdditionalInfoStruct" }) ), Field({ @@ -324,7 +325,7 @@ export const Channel = Cluster( details: "This field, if present, shall indicate the list of additional external content identifiers.", xref: { document: "cluster", section: "6.6.7.8.3" } }, - Field({ name: "entry", type: "AdditionalInfoStruct" }) + Field({ name: "entry", type: "ContentLauncher.AdditionalInfoStruct" }) ), Field({ @@ -417,9 +418,8 @@ export const Channel = Cluster( Field({ name: "AffiliateCallSign", id: 0x4, type: "string", conformance: "O", - details: "This field shall indicate the local affiliate call sign, such as \"KCTS\". This field is optional, but" + - "\n" + - "SHOULD be provided when known.", + details: "This field shall indicate the local affiliate call sign, such as \"KCTS\". This field is optional, " + + "but SHOULD be provided when known.", xref: { document: "cluster", section: "6.6.5.5.5" } }), @@ -546,14 +546,11 @@ export const Channel = Cluster( Field( { name: "Ratings", id: 0x8, type: "list", conformance: "O", constraint: "max 255", default: [], - details: "This field shall be used for indicating the level of parental guidance recommended for of a " + - "particular program. This can be any rating system used in the country or region where the program is" + - "\n" + - "broadcast. For example, in the United States “TV-PG” may contain material that parents can find not " + - "suitable for younger children but can be accepted in general for older children. This field is " + + "particular program. This can be any rating system used in the country or region where the program " + + "is broadcast. For example, in the United States “TV-PG” may contain material that parents can find " + + "not suitable for younger children but can be accepted in general for older children. This field is " + "optional but shall be provided if known.", - xref: { document: "cluster", section: "6.6.5.7.9" } }, @@ -562,21 +559,24 @@ export const Channel = Cluster( Field({ name: "ThumbnailUrl", id: 0x9, type: "string", conformance: "O", constraint: "max 8192", - details: "This field shall represent a url of a thumbnail that clients can use to render an image for the " + - "program.", + details: "This field shall represent a URL of a thumbnail that clients can use to render an image for the " + + "program. The syntax of this field shall follow the syntax as specified in RFC 1738 and shall use " + + "the https scheme.", xref: { document: "cluster", section: "6.6.5.7.10" } }), Field({ name: "PosterArtUrl", id: 0xa, type: "string", conformance: "O", constraint: "max 8192", - details: "This field shall represent a url of a poster that clients can use to render an image for the " + - "program on the detail view.", + details: "This field shall represent a URL of a poster that clients can use to render an image for the " + + "program on the detail view. The syntax of this field shall follow the syntax as specified in RFC " + + "1738 and shall use the https scheme.", xref: { document: "cluster", section: "6.6.5.7.11" } }), Field({ name: "DvbiUrl", id: 0xb, type: "string", conformance: "O", constraint: "max 8192", - details: "This field shall represent the DVB-I url associated to the program.", + details: "This field shall represent the DVB-I URL associated to the program. The syntax of this field shall " + + "follow the syntax as specified in RFC 1738 and shall use the https scheme.", xref: { document: "cluster", section: "6.6.5.7.12" } }), @@ -641,7 +641,7 @@ export const Channel = Cluster( xref: { document: "cluster", section: "6.6.5.7.19" } }, - Field({ name: "entry", type: "AdditionalInfoStruct" }) + Field({ name: "entry", type: "ContentLauncher.AdditionalInfoStruct" }) ) ), @@ -756,9 +756,7 @@ export const Channel = Cluster( "response as the last page.", xref: { document: "cluster", section: "6.6.5.12.2" } }) - ), - - Datatype({ name: "AdditionalInfoStruct", type: "ContentLauncher.AdditionalInfoStruct" }) + ) ); MatterDefinition.children.push(Channel); diff --git a/packages/model/src/standard/elements/ClosureNS.ts b/packages/model/src/standard/elements/ClosureNS.ts index d59d1d7aa3..2dc118043a 100644 --- a/packages/model/src/standard/elements/ClosureNS.ts +++ b/packages/model/src/standard/elements/ClosureNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ClusterRevision.ts b/packages/model/src/standard/elements/ClusterRevision.ts index ab4f245615..f4b1e47ebc 100644 --- a/packages/model/src/standard/elements/ClusterRevision.ts +++ b/packages/model/src/standard/elements/ClusterRevision.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ColorControl.ts b/packages/model/src/standard/elements/ColorControl.ts index 7545ead14a..a4b8ee8deb 100644 --- a/packages/model/src/standard/elements/ColorControl.ts +++ b/packages/model/src/standard/elements/ColorControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -18,78 +18,140 @@ import { export const ColorControl = Cluster( { name: "ColorControl", id: 0x300, classification: "application", pics: "CC", + + details: "This cluster provides an interface for changing the color of a light. Color is specified according " + + "to the CIE 1931 Color space. Color control is carried out in terms of x,y values, as defined by " + + "this specification." + + "\n" + + "Additionally, color may optionally be controlled in terms of color temperature, or as hue and " + + "saturation values based on optionally variable RGB and W color points. It is recommended that the " + + "hue and saturation are interpreted according to the HSV (a.k.a. HSB) color model." + + "\n" + + "Control over luminance is not included, as this is provided by means of the Level Control for " + + "Lighting cluster. It is recommended that the level provided by this cluster be interpreted as " + + "representing a proportion of the maximum intensity achievable at the current color.", + xref: { document: "cluster", section: "3.2" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 6 }), + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 7 }), Attribute( - { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "3.2.5" } }, + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "3.2.4" } }, Field({ - name: "HS", constraint: "0", description: "HueSaturation", + name: "HS", conformance: "EHUE, O", constraint: "0", description: "HueSaturation", details: "Supports color specification via hue/saturation." }), - Field({ name: "EHUE", constraint: "1", description: "EnhancedHue", details: "Enhanced hue is supported." }), - Field({ name: "CL", constraint: "2", description: "ColorLoop", details: "Color loop is supported." }), - Field({ name: "XY", constraint: "3", description: "Xy", details: "Supports color specification via XY." }), Field({ - name: "CT", constraint: "4", description: "ColorTemperature", + name: "EHUE", conformance: "CL, O", constraint: "1", description: "EnhancedHue", + details: "Enhanced hue is supported." + }), + Field({ + name: "CL", conformance: "O", constraint: "2", description: "ColorLoop", + details: "Color loop is supported." + }), + Field({ + name: "XY", conformance: "O", constraint: "3", description: "Xy", + details: "Supports color specification via XY." + }), + Field({ + name: "CT", conformance: "O", constraint: "4", description: "ColorTemperature", details: "Supports specification of color temperature." }) ), Attribute( { - name: "CurrentHue", id: 0x0, type: "uint8", access: "R V", conformance: "HS", - constraint: "0 to 254", default: 0, quality: "N P", + name: "CurrentHue", id: 0x0, type: "uint8", access: "R V", conformance: "HS", constraint: "max 254", + default: 0, quality: "N P Q", details: "The CurrentHue attribute contains the current hue value of the light. It is updated as fast as " + "practical during commands that change the hue." + "\n" + - "The hue in degrees shall be related to the CurrentHue attribute by the relationship: Hue = " + - "CurrentHue x 360 / 254 (CurrentHue in the range 0 to 254 inclusive)" + + "The hue in degrees shall be related to the CurrentHue attribute by the relationship:" + + "\n" + + "Hue = \"CurrentHue\" * 360 / 254" + + "\n" + + "where CurrentHue is in the range from 0 to 254 inclusive." + "\n" + - "If this attribute is implemented then the CurrentSaturation and ColorMode attributes shall also be " + - "implemented.", + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", xref: { document: "cluster", section: "3.2.7.2" } } ), - Attribute({ - name: "CurrentSaturation", id: 0x1, type: "uint8", access: "R V", conformance: "HS", - constraint: "0 to 254", default: 0, quality: "N S P", + Attribute( + { + name: "CurrentSaturation", id: 0x1, type: "uint8", access: "R V", conformance: "HS", + constraint: "max 254", default: 0, quality: "N S P Q", - details: "The CurrentSaturation attribute holds the current saturation value of the light. It is updated as " + - "fast as practical during commands that change the saturation." + - "\n" + - "The saturation shall be related to the CurrentSaturation attribute by the relationship: Saturation " + - "= CurrentSaturation/254 (CurrentSaturation in the range 0 to 254 inclusive)" + - "\n" + - "If this attribute is implemented then the CurrentHue and ColorMode attributes shall also be " + - "implemented.", + details: "Indicates the current saturation value of the light. It is updated as fast as practical during " + + "commands that change the saturation." + + "\n" + + "The saturation (on a scale from 0.0 to 1.0) shall be related to the CurrentSaturation attribute by " + + "the relationship:" + + "\n" + + "Saturation = \"CurrentSaturation\" / 254" + + "\n" + + "where CurrentSaturation is in the range from 0 to 254 inclusive." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", - xref: { document: "cluster", section: "3.2.7.3" } - }), + xref: { document: "cluster", section: "3.2.7.3" } + } + ), Attribute({ name: "RemainingTime", id: 0x2, type: "uint16", access: "R V", conformance: "O", - constraint: "0 to 65535", default: 0, - details: "The RemainingTime attribute holds the time remaining, in 1/10ths of a second, until the currently " + - "active command will be complete.", + constraint: "0 to 65535", default: 0, quality: "Q", + + details: "Indicates the time remaining, in 1/10ths of a second, until transitions due to the currently active " + + "command will be complete." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • When it changes from 0 to any value higher than 10, or" + + "\n" + + " • When it changes, with a delta larger than 10, caused by the invoke of a command, or" + + "\n" + + " • When it changes to 0." + + "\n" + + "For commands with a transition time or changes to the transition time less than 1 second, changes " + + "to this attribute shall NOT be reported." + + "\n" + + "As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the " + + "reporting of this attribute in order to keep track of the remaining duration.", + xref: { document: "cluster", section: "3.2.7.4" } }), Attribute( { name: "CurrentX", id: 0x3, type: "uint16", access: "R V", conformance: "XY", - constraint: "0 to 65279", default: 24939, quality: "N S P", + constraint: "max 65279", default: 24939, quality: "N S P Q", - details: "The CurrentX attribute contains the current value of the normalized chromaticity value x, as " + - "defined in the CIE xyY Color Space. It is updated as fast as practical during commands that change " + - "the color." + + details: "Indicates the current value of the normalized chromaticity value x, as defined in the CIE xyY Color " + + "Space. It is updated as fast as practical during commands that change the color." + + "\n" + + "The value of x shall be related to the CurrentX attribute by the relationship" + "\n" + - "The value of x shall be related to the CurrentX attribute by the relationship x = CurrentX / 65536 " + - "(CurrentX in the range 0 to 65279 inclusive)", + "x = \"CurrentX\" / 65536" + + "\n" + + "where CurrentX is in the range from 0 to 65279 inclusive." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", xref: { document: "cluster", section: "3.2.7.5" } } @@ -98,42 +160,37 @@ export const ColorControl = Cluster( Attribute( { name: "CurrentY", id: 0x4, type: "uint16", access: "R V", conformance: "XY", - constraint: "0 to 65279", default: 24701, quality: "N S P", + constraint: "max 65279", default: 24701, quality: "N S P Q", - details: "The CurrentY attribute contains the current value of the normalized chromaticity value y, as " + - "defined in the CIE xyY Color Space. It is updated as fast as practical during commands that change " + - "the color." + + details: "Indicates the current value of the normalized chromaticity value y, as defined in the CIE xyY Color " + + "Space. It is updated as fast as practical during commands that change the color." + + "\n" + + "The value of y shall be related to the CurrentY attribute by the relationship" + + "\n" + + "y = \"CurrentY\" / 65536" + + "\n" + + "where CurrentY is in the range from 0 to 65279 inclusive." + "\n" + - "The value of y shall be related to the CurrentY attribute by the relationship y = CurrentY / 65536 " + - "(CurrentY in the range 0 to 65279 inclusive)", + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", xref: { document: "cluster", section: "3.2.7.6" } } ), - Attribute( - { - name: "DriftCompensation", id: 0x5, type: "enum8", access: "R V", conformance: "O", - constraint: "0 to 4", - details: "The DriftCompensation attribute indicates what mechanism, if any, is in use for compensation for " + - "color/intensity drift over time. It shall be one of the non-reserved values in Values of the " + - "DriftCompensation Attribute." + - "\n" + - "### Table 8. Values of the DriftCompensation Attribute", - xref: { document: "cluster", section: "3.2.7.7" } - }, - - Field({ name: "None", id: 0x0 }), - Field({ name: "OtherUnknown", id: 0x1 }), - Field({ name: "TemperatureMonitoring", id: 0x2 }), - Field({ name: "OpticalLuminanceMonitoringAndFeedback", id: 0x3 }), - Field({ name: "OpticalColorMonitoringAndFeedback", id: 0x4 }) - ), + Attribute({ + name: "DriftCompensation", id: 0x5, type: "DriftCompensationEnum", access: "R V", conformance: "O", + details: "Indicates what mechanism, if any, is in use for compensation for color/intensity drift over time.", + xref: { document: "cluster", section: "3.2.7.7" } + }), Attribute({ name: "CompensationText", id: 0x6, type: "string", access: "R V", conformance: "O", constraint: "max 254", - details: "The CompensationText attribute holds a textual indication of what mechanism, if any, is in use to " + + details: "This attribute shall contain a textual indication of what mechanism, if any, is in use to " + "compensate for color/intensity drift over time.", xref: { document: "cluster", section: "3.2.7.8" } }), @@ -142,284 +199,105 @@ export const ColorControl = Cluster( { name: "ColorTemperatureMireds", id: 0x7, type: "uint16", access: "R V", conformance: "CT", constraint: "colorTempPhysicalMinMireds to colorTempPhysicalMaxMireds", default: 250, - quality: "N S P", - - details: "The ColorTemperatureMireds attribute contains a scaled inverse of the current value of the color " + - "temperature. The unit of ColorTemperatureMireds is the mired (micro reciprocal degree), a.k.a. " + - "mirek (micro reciprocal kelvin). It is updated as fast as practical during commands that change the " + - "color." + - "\n" + - "The color temperature value in kelvins shall be related to the ColorTemperatureMireds attribute in " + - "mireds by the relationship" + - "\n" + - "Color temperature in kelvins = 1,000,000 / ColorTemperatureMireds, where ColorTemperatureMireds is " + - "in the range 1 to 65279 mireds inclusive, giving a color temperature range from 1,000,000 kelvins " + - "to 15.32 kelvins." + - "\n" + - "If this attribute is implemented then the ColorMode attribute shall also be implemented.", - - xref: { document: "cluster", section: "3.2.7.9" } - } - ), - - Attribute( - { - name: "ColorMode", id: 0x8, type: "enum8", access: "R V", conformance: "M", constraint: "0 to 2", - quality: "N", + quality: "N S P Q", - details: "The ColorMode attribute indicates which attributes are currently determining the color of the " + - "device." + + details: "Indicates a scaled inverse of the current value of the color temperature. The unit of " + + "ColorTemperatureMireds is the mired (micro reciprocal degree), a.k.a. mirek (micro reciprocal " + + "kelvin). It is updated as fast as practical during commands that change the color." + "\n" + - "The value of the ColorMode attribute cannot be written directly - it is set upon reception of any " + - "command in section Commands to the appropriate mode for that command." + + "Changes to this attribute shall only be marked as reportable in the following cases:" + "\n" + - "Table 9. Values of the ColorMode Attribute", - - xref: { document: "cluster", section: "3.2.7.10" } - }, - - Field({ name: "CurrentHueAndCurrentSaturation", id: 0x0, conformance: "HS" }), - Field({ name: "CurrentXAndCurrentY", id: 0x1, conformance: "XY" }), - Field({ name: "ColorTemperatureMireds", id: 0x2, conformance: "CT" }) - ), - - Attribute( - { - name: "Options", id: 0xf, type: "map8", access: "RW VO", conformance: "M", constraint: "desc", - default: 0, - - details: "The Options attribute is meant to be changed only during commissioning. The Options attribute is a " + - "bitmap that determines the default behavior of some cluster commands. Each command that is " + - "dependent on the Options attribute shall first construct a temporary Options bitmap that is in " + - "effect during the command processing. The temporary Options bitmap has the same format and meaning " + - "as the Options attribute, but includes any bits that may be overridden by command fields." + - "\n" + - "Below is the format and description of the Options attribute and temporary Options bitmap and the " + - "effect on dependent commands." + + " • At most once per second or" + "\n" + - "Table 10. Options Attribute" + + " • At the end of the movement/transition." + "\n" + - "ExecuteIfOff Options bit: Command execution shall NOT continue beyond the Options processing if all " + - "of these criteria are true:" + + "The color temperature value in kelvins shall be related to the ColorTemperatureMireds attribute in " + + "mired by the relationship" + "\n" + - " • The On/Off cluster exists on the same endpoint as this cluster." + + "\"Color temperature [K]\" = \"1,000,000\" / \"ColorTemperatureMireds\"" + "\n" + - " • The OnOff attribute of the On/Off cluster, on this endpoint, is FALSE." + + "where ColorTemperatureMireds is in the range from 1 to 65279 inclusive, giving a color temperature " + + "range from 1,000,000 K to 15.32 K." + "\n" + - " • The value of the ExecuteIfOff bit is 0.", - - xref: { document: "cluster", section: "3.2.7.11" } - }, + "If this attribute is implemented then the ColorMode attribute shall also be implemented.", - Field({ name: "ExecuteIfOff", constraint: "0" }) + xref: { document: "cluster", section: "3.2.7.9" } + } ), Attribute({ - name: "EnhancedCurrentHue", id: 0x4000, type: "uint16", access: "R V", conformance: "EHUE", - default: 0, quality: "N S", - - details: "The EnhancedCurrentHue attribute represents non-equidistant steps along the CIE 1931 color " + - "triangle, and it provides 16-bits precision." + + name: "ColorMode", id: 0x8, type: "ColorModeEnum", access: "R V", conformance: "M", quality: "N", + details: "Indicates which attributes are currently determining the color of the device." + "\n" + - "The upper 8 bits of this attribute shall be used as an index in the implementation specific XY " + - "lookup table to provide the non-equidistance steps. The lower 8 bits shall be used to interpolate " + - "between these steps in a linear way in order to provide color zoom for the user." + - "\n" + - "To provide compatibility with standard ZCL, the CurrentHue attribute shall contain a hue value in " + - "the range 0 to 254, calculated from the EnhancedCurrentHue attribute.", - - xref: { document: "cluster", section: "3.2.7.12" } - }), - - Attribute( - { - name: "EnhancedColorMode", id: 0x4001, type: "enum8", access: "R V", conformance: "M", - constraint: "0 to 3", default: 1, quality: "N S", - - details: "The EnhancedColorMode attribute specifies which attributes are currently determining the color of " + - "the device, as detailed in Values of the EnhancedColorMode Attribute." + - "\n" + - "### Table 11. Values of the EnhancedColorMode Attribute" + - "\n" + - "To provide compatibility with standard ZCL, the original ColorMode attribute shall indicate " + - "‘CurrentHue and CurrentSaturation’ when the light uses the EnhancedCurrentHue attribute. If the " + - "ColorMode attribute is changed, e.g., due to one of the standard Color Control cluster commands " + - "defined in the ZCL, its new value shall be copied to the EnhancedColorMode attribute.", - - xref: { document: "cluster", section: "3.2.7.13" } - }, - - Field({ name: "CurrentHueAndCurrentSaturation", id: 0x0 }), - Field({ name: "CurrentXAndCurrentY", id: 0x1 }), - Field({ name: "ColorTemperatureMireds", id: 0x2 }), - Field({ name: "EnhancedCurrentHueAndCurrentSaturation", id: 0x3 }) - ), - - Attribute( - { - name: "ColorLoopActive", id: 0x4002, type: "enum16", access: "R V", conformance: "CL", default: 0, - quality: "N S", - details: "The ColorLoopActive attribute specifies the current active status of the color loop. If this " + - "attribute has the value 0, the color loop shall not be active. If this attribute has the value 1, " + - "the color loop shall be active. All other values (2 to 254) are reserved.", - xref: { document: "cluster", section: "3.2.7.14" } - }, - - Field({ name: "Inactive", id: 0x0 }), - Field({ name: "Active", id: 0x1 }) - ), - - Attribute( - { - name: "ColorLoopDirection", id: 0x4003, type: "enum16", access: "R V", conformance: "CL", - default: 0, quality: "N S", - details: "The ColorLoopDirection attribute specifies the current direction of the color loop. If this " + - "attribute has the value 0, the EnhancedCurrentHue attribute shall be decremented. If this attribute " + - "has the value 1, the EnhancedCurrentHue attribute shall be incremented. All other values (2 to 254) " + - "are reserved.", - xref: { document: "cluster", section: "3.2.7.15" } - }, - - Field({ name: "Decrement", id: 0x0 }), - Field({ name: "Increment", id: 0x1 }) - ), - - Attribute({ - name: "ColorLoopTime", id: 0x4004, type: "uint16", access: "R V", conformance: "CL", default: 25, - quality: "N S", - details: "The ColorLoopTime attribute specifies the number of seconds it shall take to perform a full color " + - "loop, i.e., to cycle all values of the EnhancedCurrentHue attribute (between 0 and 0xFFFE).", - xref: { document: "cluster", section: "3.2.7.16" } - }), - - Attribute({ - name: "ColorLoopStartEnhancedHue", id: 0x4005, type: "uint16", access: "R V", conformance: "CL", - default: 8960, - details: "The ColorLoopStartEnhancedHue attribute specifies the value of the EnhancedCurrentHue attribute " + - "from which the color loop shall be started.", - xref: { document: "cluster", section: "3.2.7.17" } - }), - - Attribute({ - name: "ColorLoopStoredEnhancedHue", id: 0x4006, type: "uint16", access: "R V", conformance: "CL", - default: 0, - details: "The ColorLoopStoredEnhancedHue attribute specifies the value of the EnhancedCurrentHue attribute " + - "before the color loop was started. Once the color loop is complete, the EnhancedCurrentHue " + - "attribute shall be restored to this value.", - xref: { document: "cluster", section: "3.2.7.18" } - }), - - Attribute( - { - name: "ColorCapabilities", id: 0x400a, type: "map16", access: "R V", conformance: "M", - constraint: "0 to 31", default: 0, - details: "Bits 0-4 of the ColorCapabilities attribute shall have the same values as the corresponding bits of " + - "the FeatureMap attribute. All other bits in ColorCapabilities shall be 0.", - xref: { document: "cluster", section: "3.2.7.19" } - }, - - Field({ name: "HueSaturation", constraint: "0" }), - Field({ name: "EnhancedHue", constraint: "1" }), - Field({ name: "ColorLoop", constraint: "2" }), - Field({ name: "XY", constraint: "3" }), - Field({ name: "ColorTemperature", constraint: "4" }) - ), - - Attribute({ - name: "ColorTempPhysicalMinMireds", id: 0x400b, type: "uint16", access: "R V", conformance: "CT", - constraint: "0 to 65279", default: 0, - details: "The ColorTempPhysicalMinMireds attribute indicates the minimum mired value supported by the " + - "hardware. ColorTempPhysicalMinMireds corresponds to the maximum color temperature in kelvins " + - "supported by the hardware. ColorTempPhysicalMinMireds <= ColorTemperatureMireds.", - xref: { document: "cluster", section: "3.2.7.20" } + "The value of the ColorMode attribute cannot be written directly - it is set upon reception of any " + + "command in section Commands to the appropriate mode for that command.", + xref: { document: "cluster", section: "3.2.7.10" } }), Attribute({ - name: "ColorTempPhysicalMaxMireds", id: 0x400c, type: "uint16", access: "R V", conformance: "CT", - constraint: "0 to 65279", default: 65279, - details: "The ColorTempPhysicalMaxMireds attribute indicates the maximum mired value supported by the " + - "hardware. ColorTempPhysicalMaxMireds corresponds to the minimum color temperature in kelvins " + - "supported by the hardware. ColorTemperatureMireds <= ColorTempPhysicalMaxMireds.", - xref: { document: "cluster", section: "3.2.7.21" } - }), - - Attribute( - { - name: "CoupleColorTempToLevelMinMireds", id: 0x400d, type: "uint16", access: "R V", - conformance: "CT & ColorTemperatureMireds", - constraint: "colorTempPhysicalMinMireds to colorTemperatureMireds", - - details: "The CoupleColorTempToLevelMinMireds attribute specifies a lower bound on the value of the " + - "ColorTemperatureMireds attribute for the purposes of coupling the ColorTemperatureMireds attribute " + - "to the CurrentLevel attribute when the CoupleColorTempToLevel bit of the Options attribute of the " + - "Level Control cluster is equal to 1. When coupling the ColorTemperatureMireds attribute to the " + - "CurrentLevel attribute, this value shall correspond to a CurrentLevel value of 0xFE (100%)." + - "\n" + - "This attribute shall be set such that the following relationship exists: ColorTempPhysicalMinMireds " + - "≤ CoupleColorTempToLevelMinMireds ≤ ColorTemperatureMireds" + - "\n" + - "Note that since this attribute is stored as a micro reciprocal degree (mired) value (i.e. color " + - "temperature in kelvins = 1,000,000 / CoupleColorTempToLevelMinMireds), the " + - "CoupleColorTempToLevelMinMireds attribute corresponds to an upper bound on the value of the color " + - "temperature in kelvins supported by the device.", - - xref: { document: "cluster", section: "3.2.7.22" } - } - ), - - Attribute({ - name: "StartUpColorTemperatureMireds", id: 0x4010, type: "uint16", access: "RW VM", - conformance: "CT & ColorTemperatureMireds", constraint: "0 to 65279", quality: "X N", + name: "Options", id: 0xf, type: "OptionsBitmap", access: "RW VO", conformance: "M", + constraint: "desc", default: 0, - details: "The StartUpColorTemperatureMireds attribute shall define the desired startup color temperature " + - "value a lamp shall use when it is supplied with power and this value shall be reflected in the " + - "ColorTemperatureMireds attribute. In addition, the ColorMode and EnhancedColorMode attributes shall " + - "be set to 0x02 (color temperature). The values of the StartUpColorTemperatureMireds attribute are " + - "listed in the table below," + + details: "Indicates a bitmap that determines the default behavior of some cluster commands. Each command that " + + "is dependent on the Options attribute shall first construct a temporary Options bitmap that is in " + + "effect during the command processing. The temporary Options bitmap has the same format and meaning " + + "as the Options attribute, but includes any bits that may be overridden by command fields." + + "\n" + + "This attribute is meant to be changed only during commissioning." + + "\n" + + "Below is the format and description of the Options attribute and temporary Options bitmap and the " + + "effect on dependent commands." + + "\n" + + "Command execution shall NOT continue beyond the Options processing if all of these criteria are " + + "true:" + "\n" + - "Table 12. Values of the StartUpColorTemperatureMireds attribute", + " • The On/Off cluster exists on the same endpoint as this cluster." + + "\n" + + " • The OnOff attribute of the On/Off cluster, on this endpoint, is FALSE." + + "\n" + + " • The value of the ExecuteIfOff bit is 0.", - xref: { document: "cluster", section: "3.2.7.23" } + xref: { document: "cluster", section: "3.2.7.11" } }), Attribute({ name: "NumberOfPrimaries", id: 0x10, type: "uint8", access: "R V", conformance: "M", - constraint: "0 to 6", quality: "X F", + constraint: "max 6", quality: "X F", - details: "The NumberOfPrimaries attribute contains the number of color primaries implemented on this device. " + - "A value of null shall indicate that the number of primaries is unknown." + + details: "Indicates the number of color primaries implemented on this device. A value of null shall indicate " + + "that the number of primaries is unknown." + "\n" + "Where this attribute is implemented, the attributes below for indicating the “x” and “y” color " + "values of the primaries shall also be implemented for each of the primaries from 1 to " + "NumberOfPrimaries, without leaving gaps. Implementation of the Primary1Intensity attribute and " + "subsequent intensity attributes is optional.", - xref: { document: "cluster", section: "3.2.8.1" } + xref: { document: "cluster", section: "3.2.7.24" } }), Attribute( { name: "Primary1X", id: 0x11, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 0", - constraint: "0 to 65279", quality: "F", - details: "The Primary1X attribute contains the normalized chromaticity value x for this primary, as defined " + - "in the CIE xyY Color Space." + + constraint: "max 65279", quality: "F", + details: "Indicates the normalized chromaticity value x for this primary, as defined in the CIE xyY Color " + + "Space." + "\n" + "The value of x shall be related to the Primary1X attribute by the relationship x = Primary1X / " + "65536 (Primary1X in the range 0 to 65279 inclusive)", - xref: { document: "cluster", section: "3.2.8.2" } + xref: { document: "cluster", section: "3.2.7.25" } } ), Attribute( { name: "Primary1Y", id: 0x12, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 0", - constraint: "0 to 65279", quality: "F", - details: "The Primary1Y attribute contains the normalized chromaticity value y for this primary, as defined " + - "in the CIE xyY Color Space." + + constraint: "max 65279", quality: "F", + details: "Indicates the normalized chromaticity value y for this primary, as defined in the CIE xyY Color " + + "Space." + "\n" + "The value of y shall be related to the Primary1Y attribute by the relationship y = Primary1Y / " + "65536 (Primary1Y in the range 0 to 65279 inclusive)", - xref: { document: "cluster", section: "3.2.8.3" } + xref: { document: "cluster", section: "3.2.7.26" } } ), @@ -427,144 +305,147 @@ export const ColorControl = Cluster( name: "Primary1Intensity", id: 0x13, type: "uint8", access: "R V", conformance: "NumberOfPrimaries > 0", quality: "X F", - details: "The Primary1intensity attribute contains a representation of the maximum intensity of this primary " + - "as defined in the Dimming Light Curve in the Ballast Configuration cluster (see Ballast " + - "Configuration Cluster), normalized such that the primary with the highest maximum intensity " + - "contains the value 0xFE." + + details: "Indicates a representation of the maximum intensity of this primary as defined in the Dimming Light " + + "Curve in the Ballast Configuration cluster (see Ballast Configuration Cluster), normalized such " + + "that the primary with the highest maximum intensity contains the value 254." + "\n" + - "A value of null shall indicate that this primary is not available.", + "A value of null shall indicate that this primary is not available." + + "\n" + + "3.2.7.28. Primary2X, Primary2Y, Primary2Intensity, Primary3X, Primary3Y, Primary3Intensity, " + + "Primary4X, Primary4Y, Primary4Intensity, Primary5X, Primary5Y, Primary5Intensity, Primary6X, " + + "Primary6Y and Primary6Intensity Attributes" + + "\n" + + "These attributes shall represent the capabilities of the 2nd, 3rd, 4th, 5th and 6th primaries, " + + "where present, in the same way as for the Primary1X, Primary1Y and Primary1Intensity attributes.", - xref: { document: "cluster", section: "3.2.8.4" } + xref: { document: "cluster", section: "3.2.7.27" } }), Attribute({ name: "Primary2X", id: 0x15, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 1", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.8" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary2Y", id: 0x16, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 1", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.8" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary2Intensity", id: 0x17, type: "uint8", access: "R V", conformance: "NumberOfPrimaries > 1", quality: "X F", - xref: { document: "cluster", section: "3.2.8" } + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary3X", id: 0x19, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 2", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.8" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary3Y", id: 0x1a, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 2", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.8" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary3Intensity", id: 0x1b, type: "uint8", access: "R V", conformance: "NumberOfPrimaries > 2", quality: "X F", - xref: { document: "cluster", section: "3.2.8" } + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary4X", id: 0x20, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 3", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.9" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary4Y", id: 0x21, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 3", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.9" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary4Intensity", id: 0x22, type: "uint8", access: "R V", conformance: "NumberOfPrimaries > 3", quality: "X F", - xref: { document: "cluster", section: "3.2.9" } + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary5X", id: 0x24, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 4", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.9" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary5Y", id: 0x25, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 4", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.9" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary5Intensity", id: 0x26, type: "uint8", access: "R V", conformance: "NumberOfPrimaries > 4", quality: "X F", - xref: { document: "cluster", section: "3.2.9" } + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary6X", id: 0x28, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 5", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.9" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary6Y", id: 0x29, type: "uint16", access: "R V", conformance: "NumberOfPrimaries > 5", - constraint: "0 to 65279", quality: "F", - xref: { document: "cluster", section: "3.2.9" } + constraint: "max 65279", quality: "F", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "Primary6Intensity", id: 0x2a, type: "uint8", access: "R V", conformance: "NumberOfPrimaries > 5", quality: "X F", - xref: { document: "cluster", section: "3.2.9" } + xref: { document: "cluster", section: "3.2.7" } }), Attribute( { name: "WhitePointX", id: 0x30, type: "uint16", access: "RW VM", conformance: "O", - constraint: "0 to 65279", - details: "The WhitePointX attribute contains the normalized chromaticity value x, as defined in the CIE xyY " + - "Color Space, of the current white point of the device." + + constraint: "max 65279", + details: "Indicates the normalized chromaticity value x, as defined in the CIE xyY Color Space, of the " + + "current white point of the device." + "\n" + "The value of x shall be related to the WhitePointX attribute by the relationship x = WhitePointX / " + "65536 (WhitePointX in the range 0 to 65279 inclusive)", - xref: { document: "cluster", section: "3.2.10.1" } + xref: { document: "cluster", section: "3.2.7.29" } } ), Attribute( { name: "WhitePointY", id: 0x31, type: "uint16", access: "RW VM", conformance: "O", - constraint: "0 to 65279", - - details: "The WhitePointY attribute contains the normalized chromaticity value y, as defined in the CIE xyY" + - "\n" + - "Color Space, of the current white point of the device." + + constraint: "max 65279", + details: "Indicates the normalized chromaticity value y, as defined in the CIE xyY Color Space, of the " + + "current white point of the device." + "\n" + "The value of y shall be related to the WhitePointY attribute by the relationship y = WhitePointY / " + "65536 (WhitePointY in the range 0 to 65279 inclusive)", - - xref: { document: "cluster", section: "3.2.10.2" } + xref: { document: "cluster", section: "3.2.7.30" } } ), Attribute( { name: "ColorPointRx", id: 0x32, type: "uint16", access: "RW VM", conformance: "O", - constraint: "0 to 65279", - details: "The ColorPointRX attribute contains the normalized chromaticity value x, as defined in the CIE xyY " + - "Color Space, of the red color point of the device." + + constraint: "max 65279", + details: "Indicates the normalized chromaticity value x, as defined in the CIE xyY Color Space, of the red " + + "color point of the device." + "\n" + "The value of x shall be related to the ColorPointRX attribute by the relationship x = ColorPointRX " + "/ 65536 (ColorPointRX in the range 0 to 65279 inclusive)", - xref: { document: "cluster", section: "3.2.10.3" } + xref: { document: "cluster", section: "3.2.7.31" } } ), Attribute( { name: "ColorPointRy", id: 0x33, type: "uint16", access: "RW VM", conformance: "O", - constraint: "0 to 65279", - details: "The ColorPointRY attribute contains the normalized chromaticity value y, as defined in the CIE xyY " + - "Color Space, of the red color point of the device." + + constraint: "max 65279", + details: "Indicates the normalized chromaticity value y, as defined in the CIE xyY Color Space, of the red " + + "color point of the device." + "\n" + "The value of y shall be related to the ColorPointRY attribute by the relationship y = ColorPointRY " + "/ 65536 (ColorPointRY in the range 0 to 65279 inclusive)", - xref: { document: "cluster", section: "3.2.10.4" } + xref: { document: "cluster", section: "3.2.7.32" } } ), @@ -572,72 +453,237 @@ export const ColorControl = Cluster( name: "ColorPointRIntensity", id: 0x34, type: "uint8", access: "RW VM", conformance: "O", quality: "X", - details: "The ColorPointRIntensity attribute contains a representation of the relative intensity of the red " + - "color point as defined in the Dimming Light Curve in the Ballast Configuration cluster (see Ballast " + - "Configuration Cluster), normalized such that the color point with the highest relative intensity " + - "contains the value 0xFE." + + details: "Indicates a representation of the relative intensity of the red color point as defined in the " + + "Dimming Light Curve in the Ballast Configuration cluster (see Ballast Configuration Cluster), " + + "normalized such that the color point with the highest relative intensity contains the value 254." + + "\n" + + "A value of null shall indicate an invalid value." + "\n" + - "A value of null shall indicate an invalid value.", + "3.2.7.34. ColorPointGX, ColorPointGY, ColorPointGIntensity, ColorPointBX, ColorPointBY and " + + "ColorPointBIntensity Attributes" + + "\n" + + "These attributes shall represent the chromaticity values and intensities of the green and blue " + + "color points, in the same way as for the ColorPointRX, ColorPointRY and ColorPointRIntensity " + + "attributes." + + "\n" + + "If any one of these red, green or blue color point attributes is implemented then they shall all be " + + "implemented.", - xref: { document: "cluster", section: "3.2.10.5" } + xref: { document: "cluster", section: "3.2.7.33" } }), Attribute({ name: "ColorPointGx", id: 0x36, type: "uint16", access: "RW VM", conformance: "O", - constraint: "0 to 65279", - xref: { document: "cluster", section: "3.2.10" } + constraint: "max 65279", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "ColorPointGy", id: 0x37, type: "uint16", access: "RW VM", conformance: "O", - constraint: "0 to 65279", - xref: { document: "cluster", section: "3.2.10" } + constraint: "max 65279", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "ColorPointGIntensity", id: 0x38, type: "uint8", access: "RW VM", conformance: "O", quality: "X", - xref: { document: "cluster", section: "3.2.10" } + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "ColorPointBx", id: 0x3a, type: "uint16", access: "RW VM", conformance: "O", - constraint: "0 to 65279", - xref: { document: "cluster", section: "3.2.10" } + constraint: "max 65279", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "ColorPointBy", id: 0x3b, type: "uint16", access: "RW VM", conformance: "O", - constraint: "0 to 65279", - xref: { document: "cluster", section: "3.2.10" } + constraint: "max 65279", + xref: { document: "cluster", section: "3.2.7" } }), Attribute({ name: "ColorPointBIntensity", id: 0x3c, type: "uint8", access: "RW VM", conformance: "O", quality: "X", - xref: { document: "cluster", section: "3.2.10" } + xref: { document: "cluster", section: "3.2.7" } + }), + + Attribute({ + name: "EnhancedCurrentHue", id: 0x4000, type: "uint16", access: "R V", conformance: "EHUE", + default: 0, quality: "N S Q", + + details: "Indicates the non-equidistant steps along the CIE 1931 color triangle, and it provides 16-bits " + + "precision." + + "\n" + + "The upper 8 bits of this attribute shall be used as an index in the implementation specific XY " + + "lookup table to provide the non-equidistant steps. The lower 8 bits shall be used to interpolate " + + "between these steps in a linear way in order to provide color zoom for the user." + + "\n" + + "To provide compatibility with clients not supporting EHUE, the CurrentHue attribute shall contain a " + + "hue value in the range 0 to 254, calculated from the EnhancedCurrentHue attribute." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second or" + + "\n" + + " • At the end of the movement/transition.", + + xref: { document: "cluster", section: "3.2.7.12" } + }), + + Attribute({ + name: "EnhancedColorMode", id: 0x4001, type: "EnhancedColorModeEnum", access: "R V", + conformance: "M", default: 1, quality: "N S", + + details: "Indicates which attributes are currently determining the color of the device." + + "\n" + + "To provide compatibility with clients not supporting EHUE, the original ColorMode attribute shall " + + "indicate CurrentHue and CurrentSaturation when the light uses the EnhancedCurrentHue attribute. If " + + "the ColorMode attribute is changed, its new value shall be copied to the EnhancedColorMode " + + "attribute.", + + xref: { document: "cluster", section: "3.2.7.13" } + }), + + Attribute( + { + name: "ColorLoopActive", id: 0x4002, type: "enum16", access: "R V", conformance: "CL", + constraint: "max 1", default: 0, quality: "N S", + details: "Indicates the current active status of the color loop. If this attribute has the value 0, the color " + + "loop shall NOT be active. If this attribute has the value 1, the color loop shall be active.", + xref: { document: "cluster", section: "3.2.7.14" } + }, + + Field({ name: "Inactive", id: 0x0 }), + Field({ name: "Active", id: 0x1 }) + ), + + Attribute({ + name: "ColorLoopDirection", id: 0x4003, type: "ColorLoopDirectionEnum", access: "R V", asOf: "1.4", + conformance: "CL", constraint: "max 1", default: 0, quality: "N S", + details: "Indicates the current direction of the color loop. If this attribute has the value 0, the " + + "EnhancedCurrentHue attribute shall be decremented. If this attribute has the value 1, the " + + "EnhancedCurrentHue attribute shall be incremented.", + xref: { document: "cluster", section: "3.2.7.15" } + }), + + Attribute({ + name: "ColorLoopTime", id: 0x4004, type: "uint16", access: "R V", conformance: "CL", default: 25, + quality: "N S", + details: "Indicates the number of seconds it shall take to perform a full color loop, i.e., to cycle all " + + "values of the EnhancedCurrentHue attribute (between 0 and 65534).", + xref: { document: "cluster", section: "3.2.7.16" } + }), + + Attribute({ + name: "ColorLoopStartEnhancedHue", id: 0x4005, type: "uint16", access: "R V", conformance: "CL", + default: 8960, + details: "Indicates the value of the EnhancedCurrentHue attribute from which the color loop shall be started.", + xref: { document: "cluster", section: "3.2.7.17" } + }), + + Attribute({ + name: "ColorLoopStoredEnhancedHue", id: 0x4006, type: "uint16", access: "R V", conformance: "CL", + default: 0, + details: "Indicates the value of the EnhancedCurrentHue attribute before the color loop was started. Once the " + + "color loop is complete, the EnhancedCurrentHue attribute shall be restored to this value.", + xref: { document: "cluster", section: "3.2.7.18" } + }), + + Attribute( + { + name: "ColorCapabilities", id: 0x400a, type: "map16", access: "R V", conformance: "M", + constraint: "max 31", default: 0, + details: "Indicates the color control capabilities of the device." + + "\n" + + "Bits 0-4 of the ColorCapabilities attribute shall have the same values as the corresponding bits of " + + "the FeatureMap attribute. All other bits in ColorCapabilities shall be 0.", + xref: { document: "cluster", section: "3.2.7.19" } + }, + + Field({ name: "HueSaturation", constraint: "0", description: "Supports color specification via hue/saturation." }), + Field({ name: "EnhancedHue", constraint: "1", description: "Enhanced hue is supported." }), + Field({ name: "ColorLoop", constraint: "2", description: "Color loop is supported." }), + Field({ name: "XY", constraint: "3", description: "Supports color specification via XY." }), + Field({ + name: "ColorTemperature", constraint: "4", + description: "Supports color specification via color temperature." + }) + ), + + Attribute({ + name: "ColorTempPhysicalMinMireds", id: 0x400b, type: "uint16", access: "R V", conformance: "CT", + constraint: "1 to 65279", default: 1, + details: "Indicates the minimum mired value supported by the hardware. ColorTempPhysicalMinMireds corresponds " + + "to the maximum color temperature in kelvins supported by the hardware." + + "\n" + + "ColorTempPhysicalMinMireds <= ColorTemperatureMireds.", + xref: { document: "cluster", section: "3.2.7.20" } + }), + + Attribute({ + name: "ColorTempPhysicalMaxMireds", id: 0x400c, type: "uint16", access: "R V", conformance: "CT", + constraint: "max 65279", default: 65279, + details: "Indicates the maximum mired value supported by the hardware. ColorTempPhysicalMaxMireds corresponds " + + "to the minimum color temperature in kelvins supported by the hardware." + + "\n" + + "ColorTemperatureMireds <= ColorTempPhysicalMaxMireds.", + xref: { document: "cluster", section: "3.2.7.21" } + }), + + Attribute( + { + name: "CoupleColorTempToLevelMinMireds", id: 0x400d, type: "uint16", access: "R V", + conformance: "CT & ColorTemperatureMireds", + constraint: "colorTempPhysicalMinMireds to colorTemperatureMireds", + + details: "Indicates a lower bound on the value of the ColorTemperatureMireds attribute for the purposes of " + + "coupling the ColorTemperatureMireds attribute to the CurrentLevel attribute when the " + + "CoupleColorTempToLevel bit of the Options attribute of the Level Control cluster is equal to 1. " + + "When coupling the ColorTemperatureMireds attribute to the CurrentLevel attribute, this value shall " + + "correspond to a CurrentLevel value of 254 (100%)." + + "\n" + + "This attribute shall be set such that the following relationship exists: ColorTempPhysicalMinMireds " + + "<= CoupleColorTempToLevelMinMireds <= ColorTemperatureMireds" + + "\n" + + "Note that since this attribute is stored as a micro reciprocal degree (mired) value (i.e. color " + + "temperature in kelvins = 1,000,000 / CoupleColorTempToLevelMinMireds), the " + + "CoupleColorTempToLevelMinMireds attribute corresponds to an upper bound on the value of the color " + + "temperature" + + "\n" + + "in kelvins supported by the device.", + + xref: { document: "cluster", section: "3.2.7.22" } + } + ), + + Attribute({ + name: "StartUpColorTemperatureMireds", id: 0x4010, type: "uint16", access: "RW VM", + conformance: "CT & ColorTemperatureMireds", constraint: "1 to 65279", quality: "X N", + details: "Indicates the desired startup color temperature value the light shall use when it is supplied with " + + "power and this value shall be reflected in the ColorTemperatureMireds attribute. In addition, the " + + "ColorMode and EnhancedColorMode attributes shall be set to 2 (ColorTemperatureMireds). The values " + + "of the StartUpColorTemperatureMireds attribute are listed in the table below,", + xref: { document: "cluster", section: "3.2.7.23" } }), Command( { name: "MoveToHue", id: 0x0, access: "O", conformance: "HS", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.4" } + xref: { document: "cluster", section: "3.2.8.4" } }, Field({ - name: "Hue", id: 0x0, type: "uint8", conformance: "M", constraint: "0 to 254", - details: "The Hue field specifies the hue to be moved to.", - xref: { document: "cluster", section: "3.2.11.4.1" } + name: "Hue", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the hue to be moved to.", + xref: { document: "cluster", section: "3.2.8.4.1" } }), - Field({ - name: "Direction", id: 0x1, type: "Direction", conformance: "M", constraint: "desc", - details: "The Direction field shall be one of the non-reserved values in Values of the Direction Field." + - "\n" + - "### Table 17. Values of the Direction Field", - xref: { document: "cluster", section: "3.2.11.4.2" } + name: "Direction", id: 0x1, type: "DirectionEnum", conformance: "M", + details: "This field shall indicate the movement direction.", + xref: { document: "cluster", section: "3.2.8.4.2" } }), Field({ - name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 65534", - details: "The TransitionTime field specifies, in 1/10ths of a second, the time that shall be taken to move to " + - "the new hue.", - xref: { document: "cluster", section: "3.2.11.4.3" } + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field shall indicate, in 1/10ths of a second, the time that shall be taken to move to the new " + + "hue.", + xref: { document: "cluster", section: "3.2.8.4.3" } }), Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -647,26 +693,19 @@ export const ColorControl = Cluster( Command( { name: "MoveHue", id: 0x1, access: "O", conformance: "HS", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.5" } + xref: { document: "cluster", section: "3.2.8.5" } }, - Field({ - name: "MoveMode", id: 0x0, type: "MoveMode", conformance: "M", constraint: "desc", - details: "The MoveMode field shall be one of the non-reserved values in Values of the MoveMode Field. If the " + - "MoveMode field is equal to 0 (Stop), the Rate field shall be ignored." + - "\n" + - "### Table 18. Values of the MoveMode Field", - xref: { document: "cluster", section: "3.2.11.5.1" } + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", + details: "This field shall indicate the mode of movement.", + xref: { document: "cluster", section: "3.2.8.5.1" } }), Field({ name: "Rate", id: 0x1, type: "uint8", conformance: "M", - details: "The Rate field specifies the rate of movement in steps per second. A step is a change in the " + - "device’s hue of one unit. If the MoveMode field is set to 1 (up) or 3 (down) and the Rate field has " + - "a value of zero, the command has no effect and a response command shall be sent in response, with " + - "the status code set to INVALID_COMMAND. If the MoveMode field is set to 0 (stop) the Rate field " + - "shall be ignored.", - xref: { document: "cluster", section: "3.2.11.5.2" } + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + + "device’s hue of one unit.", + xref: { document: "cluster", section: "3.2.8.5.2" } }), Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -676,35 +715,34 @@ export const ColorControl = Cluster( Command( { name: "StepHue", id: 0x2, access: "O", conformance: "HS", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.6" } + xref: { document: "cluster", section: "3.2.8.6" } }, - Field({ - name: "StepMode", id: 0x0, type: "StepMode", conformance: "M", constraint: "desc", - details: "The StepMode field shall be one of the non-reserved values in Values of the StepMode Field." + - "\n" + - "### Table 20. Values of the StepMode Field", - xref: { document: "cluster", section: "3.2.11.6.1" } + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", + details: "This field shall indicate the mode of the step to be performed.", + xref: { document: "cluster", section: "3.2.8.6.1" } }), Field({ name: "StepSize", id: 0x1, type: "uint8", conformance: "M", - details: "The change to be added to (or subtracted from) the current value of the device’s hue.", - xref: { document: "cluster", section: "3.2.11.6.2" } + details: "This field shall indicate the change to be added to (or subtracted from) the current value of the " + + "device’s hue.", + xref: { document: "cluster", section: "3.2.8.6.2" } }), Field({ name: "TransitionTime", id: 0x2, type: "uint8", conformance: "M", - details: "The TransitionTime field specifies, in 1/10ths of a second, the time that shall be taken to perform " + - "the step. A step is a change in the device’s hue of ‘Step size’ units." + + details: "This field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the step." + + "\n" + + "A step is a change in the device’s hue of Step size units." + "\n" + "NOTE" + "\n" + "Here the TransitionTime data field is of data type uint8, where uint16 is more common for " + "TransitionTime data fields in other clusters / commands.", - xref: { document: "cluster", section: "3.2.11.6.3" } + xref: { document: "cluster", section: "3.2.8.6.3" } }), Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -715,10 +753,10 @@ export const ColorControl = Cluster( { name: "MoveToSaturation", id: 0x3, access: "O", conformance: "HS", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.7" } + xref: { document: "cluster", section: "3.2.8.7" } }, - Field({ name: "Saturation", id: 0x0, type: "uint8", conformance: "M", constraint: "0 to 254" }), - Field({ name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", constraint: "0 to 65534" }), + Field({ name: "Saturation", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254" }), + Field({ name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", constraint: "max 65534" }), Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) ), @@ -727,26 +765,19 @@ export const ColorControl = Cluster( { name: "MoveSaturation", id: 0x4, access: "O", conformance: "HS", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.8" } + xref: { document: "cluster", section: "3.2.8.8" } }, - Field({ - name: "MoveMode", id: 0x0, type: "MoveMode", conformance: "M", constraint: "desc", - details: "The MoveMode field shall be one of the non-reserved values in Values of the MoveMode Field. If the " + - "MoveMode field is equal to 0 (Stop), the Rate field shall be ignored." + - "\n" + - "### Table 22. Values of the MoveMode Field", - xref: { document: "cluster", section: "3.2.11.8.1" } + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", + details: "This field shall indicate the mode of movement, as described in the MoveHue command.", + xref: { document: "cluster", section: "3.2.8.8.1" } }), Field({ name: "Rate", id: 0x1, type: "uint8", conformance: "M", - details: "The Rate field specifies the rate of movement in steps per second. A step is a change in the " + - "device’s saturation of one unit. If the MoveMode field is set to 1 (up) or 3 (down) and the Rate " + - "field has a value of zero, the command has no effect and a response command shall be sent in " + - "response, with the status code set to INVALID_COMMAND. If the MoveMode field is set to 0 (stop) the " + - "Rate field shall be ignored.", - xref: { document: "cluster", section: "3.2.11.8.2" } + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + + "device’s saturation of one unit.", + xref: { document: "cluster", section: "3.2.8.8.2" } }), Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -757,35 +788,33 @@ export const ColorControl = Cluster( { name: "StepSaturation", id: 0x5, access: "O", conformance: "HS", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.9" } + xref: { document: "cluster", section: "3.2.8.9" } }, - Field({ - name: "StepMode", id: 0x0, type: "StepMode", conformance: "M", constraint: "desc", - details: "The StepMode field shall be one of the non-reserved values in Values of the StepMode Field." + - "\n" + - "### Table 24. Values of the StepMode Field", - xref: { document: "cluster", section: "3.2.11.9.1" } + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", + details: "This field shall indicate the mode of the step to be performed, as described in the StepHue command.", + xref: { document: "cluster", section: "3.2.8.9.1" } }), Field({ name: "StepSize", id: 0x1, type: "uint8", conformance: "M", - details: "The change to be added to (or subtracted from) the current value of the device’s saturation.", - xref: { document: "cluster", section: "3.2.11.9.2" } + details: "This field shall indicate the change to be added to (or subtracted from) the current value of the " + + "device’s saturation.", + xref: { document: "cluster", section: "3.2.8.9.2" } }), Field({ name: "TransitionTime", id: 0x2, type: "uint8", conformance: "M", - details: "The TransitionTime field specifies, in 1/10ths of a second, the time that shall be taken to perform " + - "the step. A step is a change in the device’s saturation of ‘Step size’ units." + + details: "This field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the " + + "step. A step is a change in the device’s saturation of Step size units." + "\n" + "NOTE" + "\n" + "Here the TransitionTime data field is of data type uint8, where uint16 is more common for " + "TransitionTime data fields in other clusters / commands.", - xref: { document: "cluster", section: "3.2.11.9.3" } + xref: { document: "cluster", section: "3.2.8.9.3" } }), Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -796,11 +825,11 @@ export const ColorControl = Cluster( { name: "MoveToHueAndSaturation", id: 0x6, access: "O", conformance: "HS", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.10" } + xref: { document: "cluster", section: "3.2.8.10" } }, - Field({ name: "Hue", id: 0x0, type: "uint8", conformance: "M", constraint: "0 to 254" }), - Field({ name: "Saturation", id: 0x1, type: "uint8", conformance: "M", constraint: "0 to 254" }), - Field({ name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 65534" }), + Field({ name: "Hue", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254" }), + Field({ name: "Saturation", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254" }), + Field({ name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534" }), Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) ), @@ -809,11 +838,11 @@ export const ColorControl = Cluster( { name: "MoveToColor", id: 0x7, access: "O", conformance: "XY", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.11" } + xref: { document: "cluster", section: "3.2.8.11" } }, - Field({ name: "ColorX", id: 0x0, type: "uint16", conformance: "M", constraint: "0 to 65279" }), - Field({ name: "ColorY", id: 0x1, type: "uint16", conformance: "M", constraint: "0 to 65279" }), - Field({ name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 65534" }), + Field({ name: "ColorX", id: 0x0, type: "uint16", conformance: "M", constraint: "max 65279" }), + Field({ name: "ColorY", id: 0x1, type: "uint16", conformance: "M", constraint: "max 65279" }), + Field({ name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534" }), Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) ), @@ -822,21 +851,21 @@ export const ColorControl = Cluster( { name: "MoveColor", id: 0x8, access: "O", conformance: "XY", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.12" } + xref: { document: "cluster", section: "3.2.8.12" } }, Field({ name: "RateX", id: 0x0, type: "int16", conformance: "M", - details: "The RateX field specifies the rate of movement in steps per second. A step is a change in the " + + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + "device’s CurrentX attribute of one unit.", - xref: { document: "cluster", section: "3.2.11.12.1" } + xref: { document: "cluster", section: "3.2.8.12.1" } }), Field({ name: "RateY", id: 0x1, type: "int16", conformance: "M", - details: "The RateY field specifies the rate of movement in steps per second. A step is a change in the " + + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + "device’s CurrentY attribute of one unit.", - xref: { document: "cluster", section: "3.2.11.12.2" } + xref: { document: "cluster", section: "3.2.8.12.2" } }), Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -847,16 +876,16 @@ export const ColorControl = Cluster( { name: "StepColor", id: 0x9, access: "O", conformance: "XY", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.13" } + xref: { document: "cluster", section: "3.2.8.13" } }, Field({ name: "StepX", id: 0x0, type: "int16", conformance: "M" }), Field({ name: "StepY", id: 0x1, type: "int16", conformance: "M" }), Field({ - name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 65534", - details: "The TransitionTime field specifies, in 1/10ths of a second, the time that shall be taken to perform " + - "the color change.", - xref: { document: "cluster", section: "3.2.11.13.2" } + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "The field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the color " + + "change.", + xref: { document: "cluster", section: "3.2.8.13.2" } }), Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -867,10 +896,10 @@ export const ColorControl = Cluster( { name: "MoveToColorTemperature", id: 0xa, access: "O", conformance: "CT", direction: "request", response: "status", - xref: { document: "cluster", section: "3.2.11.14" } + xref: { document: "cluster", section: "3.2.8.14" } }, - Field({ name: "ColorTemperatureMireds", id: 0x0, type: "uint16", conformance: "M", constraint: "0 to 65279" }), - Field({ name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", constraint: "0 to 65534" }), + Field({ name: "ColorTemperatureMireds", id: 0x0, type: "uint16", conformance: "M", constraint: "max 65279" }), + Field({ name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", constraint: "max 65534" }), Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) ), @@ -879,31 +908,26 @@ export const ColorControl = Cluster( { name: "EnhancedMoveToHue", id: 0x40, access: "O", conformance: "EHUE", direction: "request", response: "status", - details: "The EnhancedMoveToHue command allows lamps to be moved in a smooth continuous transition from their " + - "current hue to a target hue.", - xref: { document: "cluster", section: "3.2.11.15" } + details: "This command allows the light to be moved in a smooth continuous transition from their current hue " + + "to a target hue.", + xref: { document: "cluster", section: "3.2.8.15" } }, Field({ name: "EnhancedHue", id: 0x0, type: "uint16", conformance: "M", - details: "The EnhancedHue field specifies the target extended hue for the lamp.", - xref: { document: "cluster", section: "3.2.11.15.1" } + details: "This field shall indicate the target extended hue for the light.", + xref: { document: "cluster", section: "3.2.8.15.1" } }), - Field({ - name: "Direction", id: 0x1, type: "Direction", conformance: "M", constraint: "desc", - details: "This field is identical to the Direction field of the MoveToHue command of the Color Control " + - "cluster (see sub-clause Use of the OptionsMask and OptionsOverride fields).", - xref: { document: "cluster", section: "3.2.11.15.2" } + name: "Direction", id: 0x1, type: "DirectionEnum", conformance: "M", + details: "This field shall indicate the movement direction.", + xref: { document: "cluster", section: "3.2.8.15.2" } }), - Field({ - name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 65534", - details: "This field is identical to the TransitionTime field of the MoveToHue command of the Color Control " + - "cluster (see sub-clause Use of the OptionsMask and OptionsOverride fields).", - xref: { document: "cluster", section: "3.2.11.15.3" } + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field shall indicate the transition time, as described in the MoveToHue command.", + xref: { document: "cluster", section: "3.2.8.15.3" } }), - Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) ), @@ -912,27 +936,21 @@ export const ColorControl = Cluster( { name: "EnhancedMoveHue", id: 0x41, access: "O", conformance: "EHUE", direction: "request", response: "status", - details: "The EnhancedMoveHue command allows lamps to be moved in a continuous stepped transition from their " + - "current hue to a target hue.", - xref: { document: "cluster", section: "3.2.11.16" } + details: "This command allows the light to start a continuous transition starting from their current hue.", + xref: { document: "cluster", section: "3.2.8.16" } }, Field({ - name: "MoveMode", id: 0x0, type: "MoveMode", conformance: "M", constraint: "desc", - details: "This field is identical to the MoveMode field of the MoveHue command of the Color Control cluster " + - "(see sub-clause MoveHue Command). If the MoveMode field is equal to 0 (Stop), the Rate field shall " + - "be ignored.", - xref: { document: "cluster", section: "3.2.11.16.1" } + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the mode of movement, as described in the MoveHue command.", + xref: { document: "cluster", section: "3.2.8.16.1" } }), Field({ name: "Rate", id: 0x1, type: "uint16", conformance: "M", - details: "The Rate field specifies the rate of movement in steps per second. A step is a change in the " + - "extended hue of a device by one unit. If the MoveMode field is set to 1 (up) or 3 (down) and the " + - "Rate field has a value of zero, the command has no effect and a response command shall be sent in " + - "response, with the status code set to INVALID_COMMAND. If the MoveMode field is set to 0 (stop) the " + - "Rate field shall be ignored.", - xref: { document: "cluster", section: "3.2.11.16.2" } + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the " + + "extended hue of a device by one unit.", + xref: { document: "cluster", section: "3.2.8.16.2" } }), Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -943,38 +961,37 @@ export const ColorControl = Cluster( { name: "EnhancedStepHue", id: 0x42, access: "O", conformance: "EHUE", direction: "request", response: "status", - details: "The EnhancedStepHue command allows lamps to be moved in a stepped transition from their current hue " + - "to a target hue, resulting in a linear transition through XY space.", - xref: { document: "cluster", section: "3.2.11.17" } + details: "This command allows the light to be moved in a stepped transition from their current hue, resulting " + + "in a linear transition through XY space.", + xref: { document: "cluster", section: "3.2.8.17" } }, Field({ - name: "StepMode", id: 0x0, type: "StepMode", conformance: "M", constraint: "desc", - details: "This field is identical to the StepMode field of the StepHue command of the Color Control cluster " + - "(see sub-clause StepHue Command).", - xref: { document: "cluster", section: "3.2.11.17.1" } + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the mode of the step to be performed, as described in the StepHue command.", + xref: { document: "cluster", section: "3.2.8.17.1" } }), Field({ name: "StepSize", id: 0x1, type: "uint16", conformance: "M", - details: "The StepSize field specifies the change to be added to (or subtracted from) the current value of " + - "the device’s enhanced hue.", - xref: { document: "cluster", section: "3.2.11.17.2" } + details: "This field shall indicate the change to be added to (or subtracted from) the current value of the " + + "device’s enhanced hue.", + xref: { document: "cluster", section: "3.2.8.17.2" } }), Field({ - name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 65534", + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", - details: "The TransitionTime field specifies, in units of 1/10ths of a second, the time that shall be taken " + - "to perform the step. A step is a change to the device’s enhanced hue of a magnitude corresponding " + - "to the StepSize field." + + details: "The field shall indicate, in units of 1/10ths of a second, the time that shall be taken to perform " + + "the step. A step is a change to the device’s enhanced hue of a magnitude corresponding to the " + + "StepSize field." + "\n" + "NOTE" + "\n" + "Here TransitionTime data field is of data type uint16, while the TransitionTime data field of the " + "StepHue command is of data type uint8.", - xref: { document: "cluster", section: "3.2.11.17.3" } + xref: { document: "cluster", section: "3.2.8.17.3" } }), Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -985,32 +1002,26 @@ export const ColorControl = Cluster( { name: "EnhancedMoveToHueAndSaturation", id: 0x43, access: "O", conformance: "EHUE", direction: "request", response: "status", - details: "The EnhancedMoveToHueAndSaturation command allows lamps to be moved in a smooth continuous " + - "transition from their current hue to a target hue and from their current saturation to a target " + - "saturation.", - xref: { document: "cluster", section: "3.2.11.18" } + details: "This command allows the light to be moved in a smooth continuous transition from their current hue " + + "to a target hue and from their current saturation to a target saturation.", + xref: { document: "cluster", section: "3.2.8.18" } }, Field({ name: "EnhancedHue", id: 0x0, type: "uint16", conformance: "M", - details: "The EnhancedHue field specifies the target extended hue for the lamp.", - xref: { document: "cluster", section: "3.2.11.18.1" } + details: "This field shall indicate the target extended hue for the light.", + xref: { document: "cluster", section: "3.2.8.18.1" } }), - Field({ - name: "Saturation", id: 0x1, type: "uint8", conformance: "M", constraint: "0 to 254", - details: "This field is identical to the Saturation field of the MoveToHueAndSaturation command of the Color " + - "Control cluster (see sub-clause MoveToHueAndSaturation Command).", - xref: { document: "cluster", section: "3.2.11.18.2" } + name: "Saturation", id: 0x1, type: "uint8", conformance: "M", constraint: "max 254", + details: "This field shall indicate the saturation, as described in the MoveToHueAndSaturation command.", + xref: { document: "cluster", section: "3.2.8.18.2" } }), - Field({ - name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 65534", - details: "This field is identical to the TransitionTime field of the MoveToHue command of the Color Control " + - "cluster (see sub-clause MoveToHueAndSaturation Command).", - xref: { document: "cluster", section: "3.2.11.18.3" } + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field shall indicate the transition time, as described in the MoveToHue command.", + xref: { document: "cluster", section: "3.2.8.18.3" } }), - Field({ name: "OptionsMask", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }), Field({ name: "OptionsOverride", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }) ), @@ -1019,88 +1030,33 @@ export const ColorControl = Cluster( { name: "ColorLoopSet", id: 0x44, access: "O", conformance: "CL", direction: "request", response: "status", - details: "The Color Loop Set command allows a color loop to be activated such that the color lamp cycles " + - "through its range of hues.", - xref: { document: "cluster", section: "3.2.11.19" } + details: "This command allows a color loop to be activated such that the color light cycles through its range " + + "of hues.", + xref: { document: "cluster", section: "3.2.8.19" } }, - Field( - { - name: "UpdateFlags", id: 0x0, type: "map8", conformance: "M", constraint: "desc", - - details: "The UpdateFlags field specifies which color loop attributes to update before the color loop is " + - "started. This field shall be formatted as illustrated in Format of the UpdateFlags Field of the " + - "ColorLoopSet Command." + - "\n" + - "### Table 28. Format of the UpdateFlags Field of the ColorLoopSet Command" + - "\n" + - "The UpdateAction sub-field is 1 bit in length and specifies whether the device shall adhere to the " + - "action field in order to process the command. If this sub-field is set to 1, the device shall " + - "adhere to the action field. If this sub-field is set to 0, the device shall ignore the Action field." + - "\n" + - "The UpdateDirection sub-field is 1 bit in length and specifies whether the device shall update the " + - "ColorLoopDirection attribute with the Direction field. If this sub-field is set to 1, the device " + - "shall update the value of the ColorLoopDirection attribute with the value of the Direction field. " + - "If this sub-field is set to 0, the device shall ignore the Direction field." + - "\n" + - "The UpdateTime sub-field is 1 bit in length and specifies whether the device shall update the " + - "ColorLoopTime attribute with the Time field. If this sub-field is set to 1, the device shall update " + - "the value of the ColorLoopTime attribute with the value of the Time field. If this sub-field is set " + - "to 0, the device shall ignore the Time field." + - "\n" + - "The UpdateStartHue sub-field is 1 bit in length and specifies whether the device shall update the " + - "ColorLoopStartEnhancedHue attribute with the StartHue field. If this sub-field is set to 1, the " + - "device shall update the value of the ColorLoopStartEnhancedHue attribute with the value of the " + - "StartHue field. If this sub-field is set to 0, the device shall ignore the StartHue field.", - - xref: { document: "cluster", section: "3.2.11.19.1" } - }, - - Field({ name: "UpdateAction", constraint: "0" }), - Field({ name: "UpdateDirection", constraint: "1" }), - Field({ name: "UpdateTime", constraint: "2" }), - Field({ name: "UpdateStartHue", constraint: "3" }), - Field({ name: "Reserved", constraint: "4 to 8" }) - ), - - Field( - { - name: "Action", id: 0x1, type: "enum8", conformance: "M", constraint: "desc", - details: "The Action field specifies the action to take for the color loop if the UpdateAction sub-field of " + - "the UpdateFlags field is set to 1. This field shall be set to one of the non-reserved values listed " + - "in Values of the Action Field of the ColorLoopSet Command." + - "\n" + - "### Table 29. Values of the Action Field of the ColorLoopSet Command", - xref: { document: "cluster", section: "3.2.11.19.2" } - }, - - Field({ name: "DeActivateTheColorLoop", id: 0x0 }), - Field({ name: "ActivateTheColorLoopFromTheValueInTheColorLoopStartEnhancedHueField", id: 0x1 }), - Field({ name: "ActivateTheColorLoopFromTheValueOfTheEnhancedCurrentHueAttribute", id: 0x2 }) - ), - - Field( - { - name: "Direction", id: 0x2, type: "enum8", conformance: "M", constraint: "desc", - details: "The Direction field specifies the direction for the color loop if the Update Direction field of the " + - "UpdateFlags field is set to 1. This field shall be set to one of the non-reserved values listed in " + - "Values of the Direction Field of the ColorLoopSet Command." + - "\n" + - "### Table 30. Values of the Direction Field of the ColorLoopSet Command", - xref: { document: "cluster", section: "3.2.11.19.3" } - }, - - Field({ name: "DecrementTheHueInTheColorLoop", id: 0x0 }), - Field({ name: "IncrementTheHueInTheColorLoop", id: 0x1 }) - ), + Field({ + name: "UpdateFlags", id: 0x0, type: "UpdateFlagsBitmap", conformance: "M", + details: "This field shall indicate which color loop attributes to update (from the values supplied in the " + + "other fields, see field descriptions below) before the color loop is started.", + xref: { document: "cluster", section: "3.2.8.19.1" } + }), + Field({ + name: "Action", id: 0x1, type: "ColorLoopActionEnum", conformance: "M", + details: "This field shall indicate the action to take for the color loop.", + xref: { document: "cluster", section: "3.2.8.19.2" } + }), + Field({ + name: "Direction", id: 0x2, type: "ColorLoopDirectionEnum", conformance: "M", + details: "This field shall indicate the direction for the color loop.", + xref: { document: "cluster", section: "3.2.8.19.3" } + }), Field({ name: "Time", id: 0x3, type: "uint16", conformance: "M", - details: "The Time field specifies the number of seconds over which to perform a full color loop if the " + - "UpdateTime sub-field of the UpdateFlags field is set to 1.", - xref: { document: "cluster", section: "3.2.11.19.4" } + details: "This field shall indicate the number of seconds over which to perform a full color loop.", + xref: { document: "cluster", section: "3.2.8.19.4" } }), - Field({ name: "StartHue", id: 0x4, type: "uint16", conformance: "M" }), Field({ name: "OptionsMask", id: 0x5, type: "Options", conformance: "M", constraint: "desc", default: 0 }), Field({ name: "OptionsOverride", id: 0x6, type: "Options", conformance: "M", constraint: "desc", default: 0 }) @@ -1110,11 +1066,12 @@ export const ColorControl = Cluster( { name: "StopMoveStep", id: 0x47, access: "O", conformance: "HS | XY | CT", direction: "request", response: "status", - details: "The StopMoveStep command is provided to allow MoveTo and Step commands to be stopped. (Note this " + - "automatically provides symmetry to the Level Control cluster.)" + + details: "This command is provided to allow MoveTo and Step commands to be stopped." + "\n" + - "NOTE the StopMoveStep command has no effect on an active color loop.", - xref: { document: "cluster", section: "3.2.11.20" } + "NOTE This automatically provides symmetry to the Level Control cluster." + + "\n" + + "NOTE The StopMoveStep command has no effect on an active color loop.", + xref: { document: "cluster", section: "3.2.8.20" } }, Field({ name: "OptionsMask", id: 0x0, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -1125,35 +1082,29 @@ export const ColorControl = Cluster( { name: "MoveColorTemperature", id: 0x4b, access: "O", conformance: "CT", direction: "request", response: "status", - details: "The MoveColorTemperature command allows the color temperature of a lamp to be moved at a specified " + - "rate.", - xref: { document: "cluster", section: "3.2.11.21" } + details: "This command allows the color temperature of the light to be moved at a specified rate.", + xref: { document: "cluster", section: "3.2.8.21" } }, Field({ - name: "MoveMode", id: 0x0, type: "MoveMode", conformance: "M", constraint: "desc", - details: "This field is identical to the MoveMode field of the MoveHue command of the Color Control cluster " + - "(see sub-clause MoveHue Command). If the MoveMode field is equal to 0 (Stop), the Rate field shall " + - "be ignored.", - xref: { document: "cluster", section: "3.2.11.21.1" } + name: "MoveMode", id: 0x0, type: "MoveModeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the mode of movement, as described in the MoveHue command.", + xref: { document: "cluster", section: "3.2.8.21.1" } }), Field({ name: "Rate", id: 0x1, type: "uint16", conformance: "M", - details: "The Rate field specifies the rate of movement in steps per second. A step is a change in the color " + - "temperature of a device by one unit. If the MoveMode field is set to 1 (up) or 3 (down) and the " + - "Rate field has a value of zero, the command has no effect and a response command shall be sent in " + - "response, with the status code set to INVALID_COMMAND. If the MoveMode field is set to 0 (stop) the " + - "Rate field shall be ignored.", - xref: { document: "cluster", section: "3.2.11.21.2" } + details: "This field shall indicate the rate of movement in steps per second. A step is a change in the color " + + "temperature of a device by one unit.", + xref: { document: "cluster", section: "3.2.8.21.2" } }), Field({ name: "ColorTemperatureMinimumMireds", id: 0x2, type: "uint16", conformance: "M", - constraint: "0 to 65279", + constraint: "max 65279", - details: "The ColorTemperatureMinimumMireds field specifies a lower bound on the ColorTemperatureMireds " + - "attribute (≡ an upper bound on the color temperature in kelvins) for the current move operation" + + details: "This field shall indicate a lower bound on the ColorTemperatureMireds attribute (≡ an upper bound " + + "on the color temperature in kelvins) for the current move operation" + "\n" + "ColorTempPhysicalMinMireds <= ColorTemperatureMinimumMireds field <= ColorTemperatureMireds" + "\n" + @@ -1162,15 +1113,15 @@ export const ColorControl = Cluster( "If the ColorTemperatureMinimumMireds field is set to 0, ColorTempPhysicalMinMireds shall be used as " + "the lower bound for the ColorTemperatureMireds attribute.", - xref: { document: "cluster", section: "3.2.11.21.3" } + xref: { document: "cluster", section: "3.2.8.21.3" } }), Field({ name: "ColorTemperatureMaximumMireds", id: 0x3, type: "uint16", conformance: "M", - constraint: "0 to 65279", + constraint: "max 65279", - details: "The ColorTemperatureMaximumMireds field specifies an upper bound on the ColorTemperatureMireds " + - "attribute (≡ a lower bound on the color temperature in kelvins) for the current move operation" + + details: "This field shall indicate an upper bound on the ColorTemperatureMireds attribute (≡ a lower bound " + + "on the color temperature in kelvins) for the current move operation" + "\n" + "ColorTemperatureMireds <= ColorTemperatureMaximumMireds field <= ColorTempPhysicalMaxMireds" + "\n" + @@ -1179,7 +1130,7 @@ export const ColorControl = Cluster( "If the ColorTemperatureMaximumMireds field is set to 0, ColorTempPhysicalMaxMireds shall be used as " + "the upper bound for the ColorTemperatureMireds attribute.", - xref: { document: "cluster", section: "3.2.11.21.4" } + xref: { document: "cluster", section: "3.2.8.21.4" } }), Field({ name: "OptionsMask", id: 0x4, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -1190,65 +1141,63 @@ export const ColorControl = Cluster( { name: "StepColorTemperature", id: 0x4c, access: "O", conformance: "CT", direction: "request", response: "status", - details: "The StepColorTemperature command allows the color temperature of a lamp to be stepped with a " + - "specified step size.", - xref: { document: "cluster", section: "3.2.11.22" } + details: "This command allows the color temperature of the light to be stepped with a specified step size.", + xref: { document: "cluster", section: "3.2.8.22" } }, Field({ - name: "StepMode", id: 0x0, type: "StepMode", conformance: "M", constraint: "desc", - details: "This field is identical to the StepMode field of the StepHue command of the Color Control cluster " + - "(see sub-clause StepHue Command).", - xref: { document: "cluster", section: "3.2.11.22.1" } + name: "StepMode", id: 0x0, type: "StepModeEnum", conformance: "M", constraint: "desc", + details: "This field shall indicate the mode of the step to be performed, as described in the StepHue command.", + xref: { document: "cluster", section: "3.2.8.22.1" } }), Field({ name: "StepSize", id: 0x1, type: "uint16", conformance: "M", - details: "The StepSize field specifies the change to be added to (or subtracted from) the current value of " + - "the device’s color temperature.", - xref: { document: "cluster", section: "3.2.11.22.2" } + details: "This field shall indicate the change to be added to (or subtracted from) the current value of the " + + "device’s color temperature.", + xref: { document: "cluster", section: "3.2.8.22.2" } }), Field({ - name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "0 to 65534", - details: "The TransitionTime field specifies, in units of 1/10ths of a second, the time that shall be taken " + - "to perform the step. A step is a change to the device’s color temperature of a magnitude " + - "corresponding to the StepSize field.", - xref: { document: "cluster", section: "3.2.11.22.3" } + name: "TransitionTime", id: 0x2, type: "uint16", conformance: "M", constraint: "max 65534", + details: "This field shall indicate, in units of 1/10ths of a second, the time that shall be taken to perform " + + "the step. A step is a change to the device’s color temperature of a magnitude corresponding to the " + + "StepSize field.", + xref: { document: "cluster", section: "3.2.8.22.3" } }), Field({ name: "ColorTemperatureMinimumMireds", id: 0x3, type: "uint16", conformance: "M", - constraint: "0 to 65279", + constraint: "max 65279", - details: "The ColorTemperatureMinimumMireds field specifies a lower bound on the ColorTemperatureMireds " + - "attribute (≡ an upper bound on the color temperature in kelvins) for the current step operation" + + details: "This field shall indicate a lower bound on the ColorTemperatureMireds attribute (≡ an upper bound " + + "on the color temperature in kelvins) for the current step operation" + "\n" + "ColorTempPhysicalMinMireds <= ColorTemperatureMinimumMireds field <= ColorTemperatureMireds" + "\n" + "As such if the step operation takes the ColorTemperatureMireds attribute towards the value of the " + - "Color Temperature Minimum Mireds field it shall be clipped so that the above invariant is " + - "satisfied. If the ColorTemperatureMinimumMireds field is set to 0, ColorTempPhysicalMinMireds shall " + - "be used as the lower bound for the ColorTemperatureMireds attribute.", + "ColorTemperatureMinimumMireds field it shall be clipped so that the above invariant is satisfied. " + + "If the ColorTemperatureMinimumMireds field is set to 0, ColorTempPhysicalMinMireds shall be used as " + + "the lower bound for the ColorTemperatureMireds attribute.", - xref: { document: "cluster", section: "3.2.11.22.4" } + xref: { document: "cluster", section: "3.2.8.22.4" } }), Field({ name: "ColorTemperatureMaximumMireds", id: 0x4, type: "uint16", conformance: "M", - constraint: "0 to 65279", + constraint: "max 65279", - details: "The ColorTemperatureMaximumMireds field specifies an upper bound on the ColorTemperatureMireds " + - "attribute (≡ a lower bound on the color temperature in kelvins) for the current step operation" + + details: "This field shall indicate an upper bound on the ColorTemperatureMireds attribute (≡ a lower bound " + + "on the color temperature in kelvins) for the current step operation" + "\n" + "ColorTemperatureMireds ≤ ColorTemperatureMaximumMireds field ≤ ColorTempPhysicalMaxMireds" + "\n" + "As such if the step operation takes the ColorTemperatureMireds attribute towards the value of the " + "ColorTemperatureMaximumMireds field it shall be clipped so that the above invariant is satisfied. " + - "If the ColorTemperatureMaximum Mireds field is set to 0, ColorTempPhysicalMaxMireds shall be used " + - "as the upper bound for the ColorTemperatureMireds attribute.", + "If the ColorTemperatureMaximumMireds field is set to 0, ColorTempPhysicalMaxMireds shall be used as " + + "the upper bound for the ColorTemperatureMireds attribute.", - xref: { document: "cluster", section: "3.2.11.22.5" } + xref: { document: "cluster", section: "3.2.8.22.5" } }), Field({ name: "OptionsMask", id: 0x5, type: "Options", conformance: "M", constraint: "desc", default: 0 }), @@ -1256,24 +1205,181 @@ export const ColorControl = Cluster( ), Datatype( - { name: "MoveMode", type: "enum8", xref: { document: "cluster", section: "3.2.11.5.1" } }, - Field({ name: "Stop", id: 0x0 }), - Field({ name: "Up", id: 0x1 }), - Field({ name: "Down", id: 0x3 }) + { name: "OptionsBitmap", type: "map8", xref: { document: "cluster", section: "3.2.6.2" } }, + Field({ + name: "ExecuteIfOff", constraint: "0", description: "Dependency on On/Off cluster", + details: "This bit shall indicate if this cluster server instance has a dependency with the On/Off cluster.", + xref: { document: "cluster", section: "3.2.6.2.1" } + }) ), Datatype( - { name: "StepMode", type: "enum8", xref: { document: "cluster", section: "3.2.11.6.1" } }, - Field({ name: "Up", id: 0x1 }), - Field({ name: "Down", id: 0x3 }) + { + name: "UpdateFlagsBitmap", type: "map8", + details: "This data type is derived from map8 and is used in the ColorLoopSet command.", + xref: { document: "cluster", section: "3.2.6.3" } + }, + + Field( + { + name: "UpdateAction", constraint: "0", + description: "Device adheres to the associated action field.", + + details: "This bit shall indicate whether the server adheres to the Action field in order to process the " + + "command." + + "\n" + + " • 0 = Device shall ignore the Action field." + + "\n" + + " • 1 = Device shall adhere to the Action field.", + + xref: { document: "cluster", section: "3.2.6.3.1" } + } + ), + + Field( + { + name: "UpdateDirection", constraint: "1", + description: "Device updates the associated direction attribute.", + + details: "This bit shall indicate whether the device updates the ColorLoopDirection attribute with the " + + "Direction field." + + "\n" + + " • 0 = Device shall ignore the Direction field." + + "\n" + + " • 1 = Device shall update the ColorLoopDirection attribute with the value of the Direction field.", + + xref: { document: "cluster", section: "3.2.6.3.2" } + } + ), + + Field( + { + name: "UpdateTime", constraint: "2", description: "Device updates the associated time attribute.", + + details: "This bit shall indicate whether the device updates the ColorLoopTime attribute with the Time field." + + "\n" + + " • 0 = Device shall ignore the Time field." + + "\n" + + " • 1 = Device shall update the value of the ColorLoopTime attribute with the value of the Time " + + " field.", + + xref: { document: "cluster", section: "3.2.6.3.3" } + } + ), + + Field( + { + name: "UpdateStartHue", constraint: "3", + description: "Device updates the associated start hue attribute.", + + details: "This bit shall indicate whether the device updates the ColorLoopStartEnhancedHue attribute with the " + + "value of the StartHue field." + + "\n" + + " • 0 = Device shall ignore the StartHue field." + + "\n" + + " • 1 = Device shall update the value of the ColorLoopStartEnhancedHue attribute with the value of " + + " the StartHue field.", + + xref: { document: "cluster", section: "3.2.6.3.4" } + } + ) + ), + + Datatype( + { name: "DriftCompensationEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.4" } }, + Field({ name: "None", id: 0x0, conformance: "M", description: "There is no compensation." }), + Field({ + name: "OtherOrUnknown", id: 0x1, conformance: "M", + description: "The compensation is based on other or unknown mechanism." + }), + Field({ + name: "TemperatureMonitoring", id: 0x2, conformance: "M", + description: "The compensation is based on temperature monitoring." + }), + Field({ + name: "OpticalLuminanceMonitoringAndFeedback", id: 0x3, conformance: "M", + description: "The compensation is based on optical luminance monitoring and feedback." + }), + Field({ + name: "OpticalColorMonitoringAndFeedback", id: 0x4, conformance: "M", + description: "The compensation is based on optical color monitoring and feedback." + }) + ), + + Datatype( + { name: "ColorModeEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.5" } }, + Field({ + name: "CurrentHueAndCurrentSaturation", id: 0x0, conformance: "M", + description: "The current hue and saturation attributes determine the color." + }), + Field({ + name: "CurrentXAndCurrentY", id: 0x1, conformance: "M", + description: "The current X and Y attributes determine the color." + }), + Field({ + name: "ColorTemperatureMireds", id: 0x2, conformance: "M", + description: "The color temperature attribute determines the color." + }) + ), + + Datatype( + { name: "EnhancedColorModeEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.6" } }, + Field({ + name: "CurrentHueAndCurrentSaturation", id: 0x0, conformance: "M", + description: "The current hue and saturation attributes determine the color." + }), + Field({ + name: "CurrentXAndCurrentY", id: 0x1, conformance: "M", + description: "The current X and Y attributes determine the color." + }), + Field({ + name: "ColorTemperatureMireds", id: 0x2, conformance: "M", + description: "The color temperature attribute determines the color." + }), + Field({ + name: "EnhancedCurrentHueAndCurrentSaturation", id: 0x3, conformance: "M", + description: "The enhanced current hue and saturation attributes determine the color." + }) + ), + + Datatype( + { name: "DirectionEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.7" } }, + Field({ name: "Shortest", id: 0x0, conformance: "M", description: "Shortest distance" }), + Field({ name: "Longest", id: 0x1, conformance: "M", description: "Longest distance" }), + Field({ name: "Up", id: 0x2, conformance: "M", description: "Up" }), + Field({ name: "Down", id: 0x3, conformance: "M", description: "Down" }) + ), + + Datatype( + { name: "MoveModeEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.8" } }, + Field({ name: "Stop", id: 0x0, conformance: "M", description: "Stop the movement" }), + Field({ name: "Up", id: 0x1, conformance: "M", description: "Move in an upwards direction" }), + Field({ name: "Down", id: 0x3, conformance: "M", description: "Move in a downwards direction" }) + ), + + Datatype( + { name: "StepModeEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.9" } }, + Field({ name: "Up", id: 0x1, conformance: "M", description: "Step in an upwards direction" }), + Field({ name: "Down", id: 0x3, conformance: "M", description: "Step in a downwards direction" }) + ), + + Datatype( + { name: "ColorLoopActionEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.10" } }, + Field({ name: "Deactivate", id: 0x0, conformance: "M", description: "De-activate the color loop." }), + Field({ + name: "ActivateFromColorLoopStartEnhancedHue", id: 0x1, conformance: "M", + description: "Activate the color loop from the value in the ColorLoopStartEnhancedHue field." + }), + Field({ + name: "ActivateFromEnhancedCurrentHue", id: 0x2, conformance: "M", + description: "Activate the color loop from the value of the EnhancedCurrentHue attribute." + }) ), Datatype( - { name: "Direction", type: "enum8", xref: { document: "cluster", section: "3.2.11.4.2" } }, - Field({ name: "ShortestDistance", id: 0x0 }), - Field({ name: "LongestDistance", id: 0x1 }), - Field({ name: "Up", id: 0x2 }), - Field({ name: "Down", id: 0x3 }) + { name: "ColorLoopDirectionEnum", type: "enum8", xref: { document: "cluster", section: "3.2.6.11" } }, + Field({ name: "Decrement", id: 0x0, conformance: "M", description: "Decrement the hue in the color loop." }), + Field({ name: "Increment", id: 0x1, conformance: "M", description: "Increment the hue in the color loop." }) ) ); diff --git a/packages/model/src/standard/elements/ColorDimmerSwitchDT.ts b/packages/model/src/standard/elements/ColorDimmerSwitchDT.ts index 4ee58d8cb1..42600a718a 100644 --- a/packages/model/src/standard/elements/ColorDimmerSwitchDT.ts +++ b/packages/model/src/standard/elements/ColorDimmerSwitchDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ColorTemperatureLightDT.ts b/packages/model/src/standard/elements/ColorTemperatureLightDT.ts index e86c9a64d3..42526b242b 100644 --- a/packages/model/src/standard/elements/ColorTemperatureLightDT.ts +++ b/packages/model/src/standard/elements/ColorTemperatureLightDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/CommissionerControl.ts b/packages/model/src/standard/elements/CommissionerControl.ts new file mode 100644 index 0000000000..d74ea8eef9 --- /dev/null +++ b/packages/model/src/standard/elements/CommissionerControl.ts @@ -0,0 +1,194 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + EventElement as Event, + FieldElement as Field, + CommandElement as Command, + DatatypeElement as Datatype +} from "../../elements/index.js"; + +export const CommissionerControl = Cluster( + { + name: "CommissionerControl", id: 0x751, classification: "node", pics: "CCTRL", + + details: "The Commissioner Control Cluster supports the ability for clients to request the commissioning of " + + "themselves or other nodes onto a fabric which the cluster server can commission onto. An example " + + "use case is ecosystem to ecosystem Fabric Synchronization setup." + + "\n" + + "The generalized flow supported by the Commissioner Control Cluster can be seen in the following " + + "diagram." + + "\n" + + "Figure 101. Commissioner Control Cluster - General Flow", + + xref: { document: "core", section: "11.26" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "SupportedDeviceCategories", id: 0x0, type: "SupportedDeviceCategoryBitmap", access: "R M", + conformance: "M", default: 0, + details: "Indicates the device categories specified in SupportedDeviceCategoryBitmap that are supported by " + + "this Commissioner Control Cluster server." + + "\n" + + "A client shall NOT send the RequestCommissioningApproval command if the intended node to be " + + "commissioned does not conform to any of the values specified in SupportedDeviceCategories.", + xref: { document: "core", section: "11.26.5.1" } + }), + + Event( + { + name: "CommissioningRequestResult", id: 0x0, access: "S M", conformance: "M", priority: "info", + + details: "This event shall be generated by the server following a RequestCommissioningApproval command which " + + "the server responded to with SUCCESS." + + "\n" + + "NOTE" + + "\n" + + "The approval is valid for a period determined by the manufacturer and characteristics of the node " + + "presenting the Commissioner Control Cluster. Clients SHOULD send the CommissionNode command " + + "immediately upon receiving a CommissioningRequestResult event." + + "\n" + + "11.26.7.2. RequestID / ClientNodeID Fields" + + "\n" + + "The RequestID shall match the RequestID provided to RequestCommissioningApproval and the " + + "ClientNodeID shall match the NodeID of the client which generated the RequestCommissioningAp" + + "\n" + + "proval command.", + + xref: { document: "core", section: "11.26.7.1" } + }, + + Field({ name: "RequestId", id: 0x0, type: "uint64", access: "S", conformance: "M" }), + Field({ name: "ClientNodeId", id: 0x1, type: "node-id", access: "S", conformance: "M" }), + Field({ name: "StatusCode", id: 0x2, type: "status", access: "S", conformance: "M", constraint: "desc" }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Command( + { + name: "RequestCommissioningApproval", id: 0x0, access: "M", conformance: "M", direction: "request", + response: "status", + + details: "This command is sent by a client to request approval for a future CommissionNode call. This is " + + "required to be a separate step in order to provide the server time for interacting with a user " + + "before informing the client that the CommissionNode operation may be successful." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "The server may request approval from the user, but it is not required." + + "\n" + + "The server shall always return SUCCESS to a correctly formatted RequestCommissioningApproval " + + "command, and then generate a CommissioningRequestResult event associated with the command’s" + + "\n" + + "accessing fabric once the result is ready." + + "\n" + + "Clients SHOULD avoid using the same RequestID. If the RequestID and client NodeID of a " + + "RequestCommissioningApproval match a previously received RequestCommissioningApproval and the " + + "server has not returned an error or completed commissioning of a device for the prior request, then " + + "the server SHOULD return FAILURE." + + "\n" + + "The parameters for RequestCommissioningApproval command are as follows:", + + xref: { document: "core", section: "11.26.6.1" } + }, + + Field({ name: "RequestId", id: 0x0, type: "uint64", conformance: "M" }), + Field({ name: "VendorId", id: 0x1, type: "vendor-id", conformance: "M" }), + Field({ name: "ProductId", id: 0x2, type: "uint16", conformance: "M" }), + Field({ name: "Label", id: 0x3, type: "string", conformance: "O", constraint: "max 64" }) + ), + + Command( + { + name: "CommissionNode", id: 0x1, access: "M", conformance: "M", direction: "request", + response: "ReverseOpenCommissioningWindow", + + details: "This command is sent by a client to request that the server begins commissioning a previously " + + "approved request." + + "\n" + + "The server shall return FAILURE if the CommissionNode command is not sent from the same NodeID and " + + "on the same fabric as the RequestCommissioningApproval or if the provided RequestID to " + + "CommissionNode does not match the value provided to RequestCommissioningApproval." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of" + + "\n" + + "UNSUPPORTED_ACCESS." + + "\n" + + "Upon receipt, the server shall respond with ReverseOpenCommissioningWindow if " + + "CommissioningRequestResult was generated with StatusCode of SUCCESS for the matching RequestID " + + "field and NodeID of the client." + + "\n" + + "The server shall return FAILURE if the CommissionNode command is received after the server has " + + "already responded to a client with ReverseOpenCommissioningWindow for a matching RequestID field " + + "and NodeID of the client unless the client has sent another RequestCommissioningApproval and " + + "received an additional CommissioningRequestResult." + + "\n" + + "The parameters for CommissionNode command are as follows:", + + xref: { document: "core", section: "11.26.6.5" } + }, + + Field({ name: "RequestId", id: 0x0, type: "uint64", conformance: "M" }), + Field({ + name: "ResponseTimeoutSeconds", id: 0x1, type: "uint16", conformance: "M", constraint: "30 to 120", + default: 30 + }) + ), + + Command( + { + name: "ReverseOpenCommissioningWindow", id: 0x2, conformance: "M", direction: "response", + + details: "When received within the timeout specified by ResponseTimeoutSeconds in the CommissionNode command, " + + "the client shall open a commissioning window on a node which matches the VendorID and ProductID " + + "provided in the associated RequestCommissioningApproval command." + + "\n" + + "When commissioning this node, the server shall check that the VendorID and ProductID fields " + + "provided in the RequestCommissioningApproval command match the VendorID and ProductID attributes of " + + "the Basic Information Cluster which have already been verified during the Device Attestation " + + "Procedure. If they do not match, the server shall NOT complete commissioning and SHOULD indicate an " + + "error to the user." + + "\n" + + "NOTE" + + "\n" + + "This is an alias onto the Open Commissioning Window command within the Administrator Commissioning " + + "Cluster. Refer to the Open Commissioning Window command for a description of the command behavior " + + "and parameters." + + "\n" + + "The parameters for ReverseOpenCommissioningWindow command are as follows:", + + xref: { document: "core", section: "11.26.6.8" } + }, + + Field({ name: "CommissioningTimeout", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }), + Field({ name: "PakePasscodeVerifier", id: 0x1, type: "octstr", conformance: "M" }), + Field({ name: "Discriminator", id: 0x2, type: "uint16", conformance: "M", constraint: "max 4095" }), + Field({ name: "Iterations", id: 0x3, type: "uint32", conformance: "M", constraint: "1000 to 100000" }), + Field({ name: "Salt", id: 0x4, type: "octstr", conformance: "M", constraint: "16 to 32" }) + ), + + Datatype( + { name: "SupportedDeviceCategoryBitmap", type: "map32", xref: { document: "core", section: "11.26.4.1" } }, + + Field({ + name: "FabricSynchronization", constraint: "0", + description: "Aggregators which support Fabric Synchronization may be commissioned.", + details: "The FabricSynchronization bit shall be set to 1 if and only if the server supports commissioning " + + "nodes that support Fabric Synchronization.", + xref: { document: "core", section: "11.26.4.1.1" } + }) + ) +); + +MatterDefinition.children.push(CommissionerControl); diff --git a/packages/model/src/standard/elements/CompassDirectionNS.ts b/packages/model/src/standard/elements/CompassDirectionNS.ts index 7547188429..59d6db93eb 100644 --- a/packages/model/src/standard/elements/CompassDirectionNS.ts +++ b/packages/model/src/standard/elements/CompassDirectionNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/CompassLocationNS.ts b/packages/model/src/standard/elements/CompassLocationNS.ts index c4d59da2f5..ef86f06691 100644 --- a/packages/model/src/standard/elements/CompassLocationNS.ts +++ b/packages/model/src/standard/elements/CompassLocationNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ConcentrationMeasurement.ts b/packages/model/src/standard/elements/ConcentrationMeasurement.ts index ddd5c61016..7701a614e6 100644 --- a/packages/model/src/standard/elements/ConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/ConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -64,8 +64,8 @@ export const ConcentrationMeasurement = Cluster( }), Attribute({ - name: "MinMeasuredValue", id: 0x1, type: "single", access: "R V", conformance: "MEA", - constraint: "max maxMeasuredValue", default: null, quality: "X", + name: "MinMeasuredValue", id: 0x1, type: "single", access: "R V", conformance: "MEA", default: null, + quality: "X", details: "Indicates the minimum value of MeasuredValue that is capable of being measured. A MinMeasuredValue " + "of null indicates that the MinMeasuredValue is not defined.", xref: { document: "cluster", section: "2.10.6.2" } diff --git a/packages/model/src/standard/elements/ContactSensorDT.ts b/packages/model/src/standard/elements/ContactSensorDT.ts index eb8390036f..b4648e8931 100644 --- a/packages/model/src/standard/elements/ContactSensorDT.ts +++ b/packages/model/src/standard/elements/ContactSensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ContentAppDT.ts b/packages/model/src/standard/elements/ContentAppDT.ts index f95e74ab9a..a58fc2a24b 100644 --- a/packages/model/src/standard/elements/ContentAppDT.ts +++ b/packages/model/src/standard/elements/ContentAppDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ContentAppObserver.ts b/packages/model/src/standard/elements/ContentAppObserver.ts index d3cb0c3487..1ac62c570c 100644 --- a/packages/model/src/standard/elements/ContentAppObserver.ts +++ b/packages/model/src/standard/elements/ContentAppObserver.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ContentControl.ts b/packages/model/src/standard/elements/ContentControl.ts index 3eab92adf0..6ac69f15a8 100644 --- a/packages/model/src/standard/elements/ContentControl.ts +++ b/packages/model/src/standard/elements/ContentControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -182,9 +182,8 @@ export const ContentControl = Cluster( name: "BlockUnrated", id: 0x7, type: "bool", access: "R V", conformance: "BU", details: "Indicates whether the playback of unrated content is allowed when the Content Control feature is " + - "activated. If this attribute equals FALSE, then playback of unrated content" + - "\n" + - "shall be permitted. Otherwise, the media device shall prevent the playback of unrated content." + + "activated. If this attribute equals FALSE, then playback of unrated content shall be permitted. " + + "Otherwise, the media device shall prevent the playback of unrated content." + "\n" + "When this attribute changes, the device SHOULD make the user aware of any limits of this feature. " + "For example, if the feature does not control content within apps, then the device should make this " + @@ -220,7 +219,7 @@ export const ContentControl = Cluster( "when the Content Control feature is activated. The media device shall reject any request to play " + "content during one period of this attribute. If it is entering any one period of this attribute, " + "the media device shall block content which is playing and generate an event " + - "EnteringBlockContentTimeWindow. There shall not be multiple entries in this attribute list for the " + + "EnteringBlockContentTimeWindow. There shall NOT be multiple entries in this attribute list for the " + "same day of week.", xref: { document: "cluster", section: "6.13.7.11" } @@ -326,9 +325,8 @@ export const ContentControl = Cluster( details: "The purpose of this command is to add the extra screen time for the user." + "\n" + - "If a client with Operate privilege invokes this command, the media device shall check whether" + - "\n" + - "the PINCode passed in the command matches the current PINCode value. If these match, then the " + + "If a client with Operate privilege invokes this command, the media device shall check whether the " + + "PINCode passed in the command matches the current PINCode value. If these match, then the " + "RemainingScreenTime attribute shall be increased by the specified BonusTime value." + "\n" + "If the PINs do not match, then a response with InvalidPINCode error status shall be returned, and " + @@ -364,7 +362,7 @@ export const ContentControl = Cluster( Field({ name: "BonusTime", id: 0x1, type: "elapsed-s", conformance: "M", constraint: "desc", default: 300, details: "This field shall indicate the amount of extra time (in seconds) to increase RemainingScreenTime. " + - "This field shall not exceed the remaining time of this day.", + "This field shall NOT exceed the remaining time of this day.", xref: { document: "cluster", section: "6.13.8.6.2" } }) ), @@ -382,8 +380,7 @@ export const ContentControl = Cluster( Field({ name: "ScreenTime", id: 0x0, type: "elapsed-s", conformance: "M", constraint: "max 86400", - details: "This field shall indicate the time (in seconds) which the User is allowed to spend watching TV on" + - "\n" + + details: "This field shall indicate the time (in seconds) which the User is allowed to spend watching TV on " + "this media device within one day.", xref: { document: "cluster", section: "6.13.8.7.1" } }) @@ -446,9 +443,7 @@ export const ContentControl = Cluster( Field({ name: "Rating", id: 0x0, type: "string", conformance: "M", constraint: "max 8", details: "This field indicates a threshold rating for filtering scheduled content. This field shall be set to " + - "one" + - "\n" + - "of the values present in the ScheduledContentRatings attribute.", + "one of the values present in the ScheduledContentRatings attribute.", xref: { document: "cluster", section: "6.13.8.11.1" } }) ), @@ -460,9 +455,10 @@ export const ContentControl = Cluster( details: "The purpose of this command is to set BlockChannelList attribute." + "\n" + - "Upon receipt of the AddBlockChannels command, the media device shall check if the channels passed " + - "in this command are valid. If the channel is invalid, then a response with InvalidChannel error " + - "Status shall be returned." + + "Upon receipt of the AddBlockChannels command, the media device shall check if the channels" + + "\n" + + "passed in this command are valid. If the channel is invalid, then a response with InvalidChannel " + + "error Status shall be returned." + "\n" + "If there is at least one channel in Channels field which is not in the BlockChannelList attribute, " + "the media device shall process the request by adding these new channels into the BlockChannelList " + @@ -524,7 +520,8 @@ export const ContentControl = Cluster( "\n" + "Upon receipt of the AddBlockApplications command, the media device shall check if the Applications " + "passed in this command are installed. If there is an application in Applications field which is not " + - "identified by media device, then a response with UnidentifiableApplication error Status may be " + + "identified by media device, then a response with UnidentifiableApplication error Status may be" + + "\n" + "returned." + "\n" + "If there is one or more applications which are not present in BlockApplicationList attribute, the " + @@ -583,8 +580,7 @@ export const ContentControl = Cluster( details: "The purpose of this command is to set the BlockContentTimeWindow attribute." + "\n" + - "Upon receipt of the SetBlockContentTimeWindow command, the media device shall check if the" + - "\n" + + "Upon receipt of the SetBlockContentTimeWindow command, the media device shall check if the " + "TimeWindowIndex field passed in this command is NULL. If the TimeWindowIndex field is NULL, the " + "media device shall check if there is an entry in the BlockContentTimeWindow attribute which matches " + "with the TimePeriod and DayOfWeek fields passed in this command. * If Yes, then a response with " + @@ -634,35 +630,42 @@ export const ContentControl = Cluster( ), Datatype( - { name: "RatingNameStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.1" } }, + { name: "DayOfWeekBitmap", type: "map8", xref: { document: "cluster", section: "6.13.5.1" } }, + Field({ name: "Sunday", constraint: "0", description: "Sunday" }), + Field({ name: "Monday", constraint: "1", description: "Monday" }), + Field({ name: "Tuesday", constraint: "2", description: "Tuesday" }), + Field({ name: "Wednesday", constraint: "3", description: "Wednesday" }), + Field({ name: "Thursday", constraint: "4", description: "Thursday" }), + Field({ name: "Friday", constraint: "5", description: "Friday" }), + Field({ name: "Saturday", constraint: "6", description: "Saturday" }) + ), + + Datatype( + { name: "RatingNameStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.2" } }, Field({ name: "RatingName", id: 0x0, type: "string", conformance: "M", constraint: "max 8", details: "This field shall indicate the name of the rating level of the applied rating system. The applied " + "rating system is dependent upon the region or country where the Node has been provisioned, and may " + "vary from one country to another.", - xref: { document: "cluster", section: "6.13.5.1.1" } + xref: { document: "cluster", section: "6.13.5.2.1" } }), Field({ name: "RatingNameDesc", id: 0x1, type: "string", conformance: "O", constraint: "max 64", details: "This field shall specify a human readable (displayable) description for RatingName.", - xref: { document: "cluster", section: "6.13.5.1.2" } + xref: { document: "cluster", section: "6.13.5.2.2" } }) ), Datatype( - { - name: "BlockChannelStruct", type: "struct", - details: "[options=\"header\",valign=\"middle\"]b", - xref: { document: "cluster", section: "6.13.5.2" } - }, + { name: "BlockChannelStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.3" } }, Field({ name: "BlockChannelIndex", id: 0x0, type: "uint16", conformance: "M", quality: "X", details: "This field shall indicate a unique index value for a blocked channel. This value may be used to " + "indicate one selected channel which will be removed from BlockChannelList attribute.", - xref: { document: "cluster", section: "6.13.5.2.1" } + xref: { document: "cluster", section: "6.13.5.3.1" } }), Field({ @@ -671,7 +674,7 @@ export const ContentControl = Cluster( "channel number is expressed as a string, such as \"13.1\" or \"256\", the major number would be 13 or " + "256, respectively. This field is required but shall be set to 0 for channels such as over-the-top " + "channels that are not represented by a major or minor number.", - xref: { document: "cluster", section: "6.13.5.2.2" } + xref: { document: "cluster", section: "6.13.5.3.2" } }), Field({ @@ -680,19 +683,19 @@ export const ContentControl = Cluster( "channel number is expressed as a string, such as \"13.1\" or \"256\", the minor number would be 1 or 0, " + "respectively. This field is required but shall be set to 0 for channels such as over-the-top " + "channels that are not represented by a major or minor number.", - xref: { document: "cluster", section: "6.13.5.2.3" } + xref: { document: "cluster", section: "6.13.5.3.3" } }), Field({ name: "Identifier", id: 0x3, type: "string", conformance: "O", details: "This field shall indicate the unique identifier for a specific channel. This field is optional, but " + "SHOULD be provided when MajorNumber and MinorNumber are not available.", - xref: { document: "cluster", section: "6.13.5.2.4" } + xref: { document: "cluster", section: "6.13.5.3.4" } }) ), Datatype( - { name: "AppInfoStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.3" } }, + { name: "AppInfoStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.4" } }, Field({ name: "CatalogVendorId", id: 0x0, type: "uint16", conformance: "M", @@ -701,54 +704,43 @@ export const ContentControl = Cluster( "\n" + "Content App Platform providers will have their own catalog vendor ID (set to their own Vendor ID) " + "and will assign an ApplicationID to each Content App.", - xref: { document: "cluster", section: "6.13.5.3.1" } + xref: { document: "cluster", section: "6.13.5.4.1" } }), Field({ name: "ApplicationId", id: 0x1, type: "string", conformance: "M", details: "This field shall indicate the application identifier, expressed as a string, such as \"PruneVideo\" " + "or \"Company X\". This field shall be unique within a catalog.", - xref: { document: "cluster", section: "6.13.5.3.2" } + xref: { document: "cluster", section: "6.13.5.4.2" } }) ), Datatype( - { name: "TimeWindowStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.4" } }, + { name: "TimeWindowStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.5" } }, Field({ name: "TimeWindowIndex", id: 0x0, type: "uint16", conformance: "M", quality: "X", details: "This field shall indicate a unique index of a specific time window. This value may be used to " + "indicate a selected time window which will be removed from the BlockContentTimeWindow attribute.", - xref: { document: "cluster", section: "6.13.5.4.1" } + xref: { document: "cluster", section: "6.13.5.5.1" } }), Field({ name: "DayOfWeek", id: 0x1, type: "DayOfWeekBitmap", conformance: "M", constraint: "desc", details: "This field shall indicate a day of week.", - xref: { document: "cluster", section: "6.13.5.4.2" } + xref: { document: "cluster", section: "6.13.5.5.2" } }), Field( { name: "TimePeriod", id: 0x2, type: "list", conformance: "M", constraint: "desc", details: "This field shall indicate one or more discrete time periods.", - xref: { document: "cluster", section: "6.13.5.4.3" } + xref: { document: "cluster", section: "6.13.5.5.3" } }, Field({ name: "entry", type: "TimePeriodStruct" }) ) ), - Datatype( - { name: "DayOfWeekBitmap", type: "enum8", xref: { document: "cluster", section: "6.13.5.5" } }, - Field({ name: "Sunday", id: 0x0, description: "Sunday" }), - Field({ name: "Monday", id: 0x1, description: "Monday" }), - Field({ name: "Tuesday", id: 0x2, description: "Tuesday" }), - Field({ name: "Wednesday", id: 0x3, description: "Wednesday" }), - Field({ name: "Thursday", id: 0x4, description: "Thursday" }), - Field({ name: "Friday", id: 0x5, description: "Friday" }), - Field({ name: "Saturday", id: 0x6, description: "Saturday" }) - ), - Datatype( { name: "TimePeriodStruct", type: "struct", xref: { document: "cluster", section: "6.13.5.6" } }, Field({ diff --git a/packages/model/src/standard/elements/ContentLauncher.ts b/packages/model/src/standard/elements/ContentLauncher.ts index 3fc16304f2..9710d13831 100644 --- a/packages/model/src/standard/elements/ContentLauncher.ts +++ b/packages/model/src/standard/elements/ContentLauncher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,8 +17,7 @@ import { export const ContentLauncher = Cluster( { - name: "ContentLauncher", id: 0x50a, asOf: "1.3", classification: "application", - pics: "CONTENTLAUNCHER", + name: "ContentLauncher", id: 0x50a, classification: "application", pics: "CONTENTLAUNCHER", details: "This cluster provides an interface for launching content on a Video Player device such as a " + "Streaming Media Player, Smart TV or Smart Screen." + @@ -63,7 +62,8 @@ export const ContentLauncher = Cluster( { name: "AcceptHeader", id: 0x0, type: "list", access: "R V", conformance: "UP", constraint: "max 100[max 1024]", default: [], quality: "N", - details: "This attribute shall provide a list of content types supported by the Video Player or Content App " + + details: "This attribute shall provide a list of content types supported by the Video Player or Content App" + + "\n" + "in the form of entries in the HTTP \"Accept\" request header.", xref: { document: "cluster", section: "6.7.6.1" } }, @@ -147,9 +147,8 @@ export const ContentLauncher = Cluster( details: "Upon receipt, this shall launch content from the specified URL." + "\n" + - "The content types supported include those identified in the AcceptHeader and SupportedStreaming" + - "\n" + - "Protocols attributes." + + "The content types supported include those identified in the AcceptHeader and " + + "SupportedStreamingProtocols attributes." + "\n" + "A check shall be made to ensure the URL is secure (uses HTTPS)." + "\n" + @@ -166,13 +165,14 @@ export const ContentLauncher = Cluster( }, Field({ - name: "ContentUrl", id: 0x0, type: "string", conformance: "M", - details: "This field shall indicate the URL of content to launch.", + name: "ContentUrl", id: 0x0, type: "string", conformance: "M", constraint: "any", + details: "This field shall indicate the URL of content to launch. The syntax of this field shall follow the " + + "syntax as specified in RFC 1738 and shall use the https scheme.", xref: { document: "cluster", section: "6.7.7.2.1" } }), Field({ - name: "DisplayString", id: 0x1, type: "string", conformance: "O", + name: "DisplayString", id: 0x1, type: "string", conformance: "O", constraint: "any", details: "This field, if present, shall provide a string that may be used to describe the content being " + "accessed at the given URL.", xref: { document: "cluster", section: "6.7.7.2.2" } @@ -180,6 +180,7 @@ export const ContentLauncher = Cluster( Field({ name: "BrandingInformation", id: 0x2, type: "BrandingInformationStruct", conformance: "O", + constraint: "any", details: "This field, if present, shall indicate the branding information that may be displayed when playing " + "back the given content.", xref: { document: "cluster", section: "6.7.7.2.3" } @@ -187,6 +188,7 @@ export const ContentLauncher = Cluster( Field({ name: "PlaybackPreferences", id: 0x3, type: "PlaybackPreferencesStruct", conformance: "O", + constraint: "any", details: "This field, if present, shall indicate the user’s preferred Text/AudioTracks and playbackPosition " + "for the media, sent from the client to the server. If the server does not find an available track " + @@ -434,7 +436,8 @@ export const ContentLauncher = Cluster( Field({ name: "ImageUrl", id: 0x0, type: "string", conformance: "O", constraint: "max 8192", details: "This field shall indicate the URL of image used for Styling different Video Player sections like " + - "Logo, Watermark etc.", + "Logo, Watermark etc. The syntax of this field shall follow the syntax as specified in RFC 1738 and " + + "shall use the https scheme.", xref: { document: "cluster", section: "6.7.5.9.1" } }), @@ -458,7 +461,9 @@ export const ContentLauncher = Cluster( Field({ name: "Size", id: 0x2, type: "DimensionStruct", conformance: "O", details: "This field shall indicate the size of the image used for Styling different Video Player sections " + - "like Logo, Watermark etc.", + "like" + + "\n" + + "Logo, Watermark etc.", xref: { document: "cluster", section: "6.7.5.9.3" } }) ), @@ -527,9 +532,8 @@ export const ContentLauncher = Cluster( "from. In case the position falls in the middle of a frame, the server shall set the position to the " + "beginning of that frame and set the SampledPosition attribute on the MediaPlayback cluster " + "accordingly. A value of null shall indicate that playback position is not applicable for the " + - "current state of the media playback." + - "\n" + - "ported).", + "current state of the media playback. (For example : Live media with no known duration and where " + + "seek is not supported).", xref: { document: "cluster", section: "6.7.5.11.1" } }), @@ -579,7 +583,7 @@ export const ContentLauncher = Cluster( xref: { document: "cluster", section: "6.7.5.12.2" } }, - Field({ name: "entry", type: "CharacteristicEnum" }) + Field({ name: "entry", type: "MediaPlayback.CharacteristicEnum" }) ), Field({ @@ -591,15 +595,12 @@ export const ContentLauncher = Cluster( "\n" + "This field shall NOT be present if the track is not an audio track." + "\n" + - "If the track is an audio track, this field MUST be present. A value of null shall indicate that the" + - "\n" + + "If the track is an audio track, this field MUST be present. A value of null shall indicate that the " + "server can choose the audio output(s) to play the Audio Track on.", xref: { document: "cluster", section: "6.7.5.12.3" } }) - ), - - Datatype({ name: "CharacteristicEnum", type: "MediaPlayback.CharacteristicEnum" }) + ) ); MatterDefinition.children.push(ContentLauncher); diff --git a/packages/model/src/standard/elements/ControlBridgeDT.ts b/packages/model/src/standard/elements/ControlBridgeDT.ts index 8bb3cff029..74decb0e95 100644 --- a/packages/model/src/standard/elements/ControlBridgeDT.ts +++ b/packages/model/src/standard/elements/ControlBridgeDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/CookSurfaceDT.ts b/packages/model/src/standard/elements/CookSurfaceDT.ts index c4b16bab8f..b302ca8576 100644 --- a/packages/model/src/standard/elements/CookSurfaceDT.ts +++ b/packages/model/src/standard/elements/CookSurfaceDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/CooktopDT.ts b/packages/model/src/standard/elements/CooktopDT.ts index 159d401fbd..3ecc279cf7 100644 --- a/packages/model/src/standard/elements/CooktopDT.ts +++ b/packages/model/src/standard/elements/CooktopDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/Descriptor.ts b/packages/model/src/standard/elements/Descriptor.ts index 2df952f99d..d32cac44a5 100644 --- a/packages/model/src/standard/elements/Descriptor.ts +++ b/packages/model/src/standard/elements/Descriptor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/DeviceEnergyManagement.ts b/packages/model/src/standard/elements/DeviceEnergyManagement.ts index 6960b7b088..7ddaefb02b 100644 --- a/packages/model/src/standard/elements/DeviceEnergyManagement.ts +++ b/packages/model/src/standard/elements/DeviceEnergyManagement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,13 +20,14 @@ export const DeviceEnergyManagement = Cluster( { name: "DeviceEnergyManagement", id: 0x98, classification: "application", pics: "DEM", - details: "This cluster allows a client to manage the power draw of a device. An example of such a client " + - "could be an Energy Management System (EMS) which controls an Energy Smart Appliance (ESA)." + + details: "This cluster allows a client to manage the power draw of a device. An example of such a client could" + "\n" + - "In most deployments the EMS will be the client, and the ESA will host the Energy Management Cluster " + - "server." + + "be an Energy Management System (EMS) which controls an Energy Smart Appliance (ESA)." + "\n" + - "Figure 15. Example of the how an EMS is a client of multiple ESAs Energy Management clusters." + + "In most deployments the EMS will be the client, and the ESA will host the Device Energy Management " + + "Cluster server." + + "\n" + + "Figure 17. Example of the how an EMS is a client of multiple ESAs Device Energy Management clusters." + "\n" + "This cluster is intended to be generic in nature and could apply to any electrical load or " + "generator (e.g. a Battery Electric Storage System - BESS, solar PV inverter, EVSE, HVAC, heat pump, " + @@ -55,7 +56,7 @@ export const DeviceEnergyManagement = Cluster( "'grid carbon intensity', 'time of use' or 'type of use' tariffs to schedule its operation to run at " + "the cheapest and greenest times." + "\n" + - "Figure 16. Example of the how an HVAC may use multiple clusters" + + "Figure 18. Example of the how an HVAC may use multiple clusters" + "\n" + "NOTE" + "\n" + @@ -65,40 +66,39 @@ export const DeviceEnergyManagement = Cluster( "NOTE" + "\n" + "Different markets may follow different approaches, but the UK [PAS1878] and [EUCodeOfConduct] give " + - "examples of how ESAs may be mandated to support these features in the future." + - "\n" + - "NOTE Support of Device Energy Management Cluster is provisional.", + "examples of how ESAs may be mandated to support these features in the future.", xref: { document: "cluster", section: "9.2" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.2.4" } }, Field({ - name: "PA", conformance: "O.a+", constraint: "0", description: "PowerAdjustment", + name: "PA", conformance: "O", constraint: "0", description: "PowerAdjustment", details: "For Energy Smart Appliances (ESA) the definition of being 'smart' mandates that they can report " + "their current power adjustment capability and have an EMS request a temporary adjustment. This may " + "typically be to curtail power requirements during peak periods, but can also be used to turn on an " + "ESA if there is excess renewable or local generation (Solar PV)." + "\n" + - "For example, a home may have solar PV which often produces more power than the home requires," + - "\n" + + "For example, a home may have solar PV which often produces more power than the home requires, " + "resulting in the excess power flowing into the grid. This excess power naturally fluctuates when " + "clouds pass overhead and other loads in the home are switched on and off." + "\n" + "EVSE Example: An EMS may therefore be able to turn on the EVSE (if the vehicle is plugged in) and " + "can start charging the vehicle, and periodically modify the charging power depending on PV " + - "generation and other home loads, so as to minimize import and export to the grid.", + "generation and other home loads, so as to minimize import and export to the grid. An EMS may also " + + "use this feature to control the discharging (and re-charging) of the vehicle if the EVSE and " + + "vehicle support the V2X feature of the EVSE cluster of the associated EVSE device.", xref: { document: "cluster", section: "9.2.4.1" } }), Field({ - name: "PFR", conformance: "(STA | PAU | FA | CON) & !SFR, O.a+", constraint: "1", + name: "PFR", conformance: "[!PA].a, STA | PAU | FA | CON, O", constraint: "1", description: "PowerForecastReporting", details: "For Energy Smart Appliances (ESA) the definition of being 'smart' implies that they can report " + @@ -144,8 +144,7 @@ export const DeviceEnergyManagement = Cluster( }), Field({ - name: "SFR", conformance: "(STA | PAU | FA | CON) & !PFR, O.a+", constraint: "2", - description: "StateForecastReporting", + name: "SFR", conformance: "[!PA].a", constraint: "2", description: "StateForecastReporting", details: "Some ESAs do not know their actual power consumption, but do know the state of operation. Like the " + "PowerForecastingReporting feature, this uses the same slot structure mechanism to indicate a change " + @@ -165,7 +164,7 @@ export const DeviceEnergyManagement = Cluster( }), Field({ - name: "STA", conformance: "O.a+", constraint: "3", description: "StartTimeAdjustment", + name: "STA", conformance: "O", constraint: "3", description: "StartTimeAdjustment", details: "ESAs which support the Start Time Adjustment feature, allow an EMS to recommend a change to the " + "start time of the energy transfer that the ESA has previously suggested it would use." + @@ -190,9 +189,10 @@ export const DeviceEnergyManagement = Cluster( }), Field({ - name: "PAU", conformance: "O.a+", constraint: "4", description: "Pausable", + name: "PAU", conformance: "O", constraint: "4", description: "Pausable", - details: "ESAs which support the Pausable feature, allow an EMS to recommend a pause in the middle of a " + + details: "ESAs which support the Pausable feature, allow an EMS to recommend a pause in the middle of a" + + "\n" + "forecast power profile that the ESA is currently using." + "\n" + "Washing machine example: A Washing Machine is in operation, and starting its water heating step." + @@ -215,7 +215,7 @@ export const DeviceEnergyManagement = Cluster( }), Field({ - name: "FA", conformance: "P, O.a+", constraint: "5", description: "ForecastAdjustment", + name: "FA", conformance: "O", constraint: "5", description: "ForecastAdjustment", details: "ESAs which support the Forecast adjustment feature, allow an EMS to recommend a change to the " + "start, duration and/or power level limits of the steps of the power profile that the ESA has " + @@ -246,12 +246,13 @@ export const DeviceEnergyManagement = Cluster( }), Field({ - name: "CON", conformance: "P, O.a+", constraint: "6", description: "ConstraintBasedAdjustment", + name: "CON", conformance: "O", constraint: "6", description: "ConstraintBasedAdjustment", details: "ESAs which support the Constraint-Based Adjustment feature allow an EMS to inform the ESA of " + "periods during which power usage should be modified (for example when the EMS has been made aware " + - "that the grid supplier has requested reduced energy usage due to overall peak grid demand) and may " + - "cause the ESA to modify the intended power profile has previously suggested it would use." + + "that the grid supplier has requested reduced energy usage due to overall peak grid demand)" + + "\n" + + "and may cause the ESA to modify the intended power profile has previously suggested it would use." + "\n" + "EVSE example: An EVSE scheduling system may have determined that the vehicle would be charged " + "starting at a moderate rate at 1am, so that it has enough charge by the time it is needed later " + @@ -260,8 +261,7 @@ export const DeviceEnergyManagement = Cluster( "However, the DSR service provider has informed the EMS that due to high forecast winds it is now " + "forecast that there will be very cheap energy available from wind generation between 2am and 3am." + "\n" + - "The EMS first requests the Forecast data from each of its registered ESAs. It determines that the" + - "\n" + + "The EMS first requests the Forecast data from each of its registered ESAs. It determines that the " + "EVSE has a power profile suggesting it plans to start charging the vehicle at 1am." + "\n" + "The EMS can then try to reduce the cost of charging the EV by informing the EVSE of the desire to " + @@ -305,17 +305,17 @@ export const DeviceEnergyManagement = Cluster( "whether the power values reported by the ESA need to have their sign inverted when dealing with " + "forecasts and adjustments." + "\n" + - "For example, a solar PV inverter (being a generator) may produce positive values to indicate " + - "generation, however an EMS when predicting the total home load would need to subtract these " + - "positive values from the loads to compute a net import at the grid meter." + + "For example, a solar PV inverter (being a generator) may produce negative values to indicate " + + "generation (since power is flowing out of the node into the home), however a display showing the " + + "power to the consumers may need to present a positive solar production value to the consumer." + "\n" + "For example, a home battery storage system (BESS) which needs to charge the battery and then " + "discharge to the home loads, would be classed as a generator. These types of devices shall have " + "this field set to true. When generating its forecast or advertising its PowerAdjustmentCapability, " + - "the power values shall be positive to indicate discharging to the loads in the home, and negative " + + "the power values shall be negative to indicate discharging to the loads in the home, and positive " + "to indicate when it is charging its battery." + "\n" + - "GRID meter = Σ LoadPowers - Σ GeneratorPowers" + + "GRID meter = Σ LoadPowers + Σ GeneratorPowers" + "\n" + "Example:", @@ -346,73 +346,76 @@ export const DeviceEnergyManagement = Cluster( details: "Indicates the minimum electrical power that the ESA can consume when switched on. This does not " + "include when in power save or standby modes." + "\n" + - "Note that for Generator ESAs that can charge an internal battery (such as a battery storage " + - "inverter), the AbsMinPower will be a negative number representing the maximum power that the ESA " + - "can charge its internal battery.", + "NOTE" + + "\n" + + "For Generator ESAs that can discharge an internal battery (such as a battery storage inverter) to " + + "loads in the home, the AbsMinPower will be a negative number representing the maximum power that " + + "the ESA can discharge its internal battery.", xref: { document: "cluster", section: "9.2.8.4" } }), Attribute({ - name: "AbsMaxPower", id: 0x4, type: "power-mW", access: "R V", conformance: "M", default: 0, + name: "AbsMaxPower", id: 0x4, type: "power-mW", access: "R V", conformance: "M", + constraint: "min absMinPower", default: 0, details: "Indicates the maximum electrical power that the ESA can consume when switched on." + "\n" + - "The value of the AbsMaxPower attribute shall be limited" + - "\n" + - "AbsMaxPower >= AbsMinPower" + - "\n" + - "Note that for Generator ESAs that can discharge a battery to loads in the home (such as a battery " + - "storage inverter), the AbsMaxPower will be a positive number representing the maximum power at " + - "which the ESA can discharge its internal battery." + + "Note that for Generator ESAs that can charge a battery by importing power into the node (such as a " + + "battery storage inverter), the AbsMaxPower will be a positive number representing the maximum power " + + "at which the ESA can charge its internal battery." + "\n" + "For example, a battery storage inverter that can charge its battery at a maximum power of 2000W and " + - "can discharge the battery at a maximum power of 3000W, would have a AbsMinPower: -2000, " + - "AbsMaxPower: 3000W.", + "can discharge the battery at a maximum power of 3000W, would have a AbsMinPower: -3000, " + + "AbsMaxPower: 2000W.", xref: { document: "cluster", section: "9.2.8.5" } }), - Attribute( - { - name: "PowerAdjustmentCapability", id: 0x5, type: "list", access: "R V", conformance: "PA", - constraint: "max 8", default: null, quality: "X", - - details: "Indicates how the ESA can be adjusted at the current time. This attribute SHOULD be updated " + - "regularly by ESAs." + - "\n" + - "For example, a battery storage inverter may need to regulate its internal temperature, or the " + - "charging rate of the battery may be limited due to cold temperatures, or a change in the state of " + - "charge of the battery may mean that the maximum charging or discharging rate is limited." + - "\n" + - "An empty list shall indicate that no power adjustment is currently possible." + - "\n" + - "Multiple entries in the list allow to indicate that permutations of scenarios may be possible." + - "\n" + - "For example, a 10kWh battery could be at 80% state of charge. If charging at 2kW, then it would be " + - "full in 1 hour. However, it could be discharged at 2kW for 4 hours." + - "\n" + - "In this example the list of PowerAdjustStructs allows multiple scenarios to be offered as follows:", + Attribute({ + name: "PowerAdjustmentCapability", id: 0x5, type: "PowerAdjustCapabilityStruct", access: "R V", + conformance: "PA", default: null, quality: "X Q", - xref: { document: "cluster", section: "9.2.8.6" } - }, + details: "Indicates how the ESA can be adjusted at the current time, and the state of any active adjustment." + + "\n" + + "A null value indicates that no power adjustment is currently possible, and nor is any adjustment " + + "currently active." + + "\n" + + "This attribute SHOULD be updated periodically by ESAs to reflect any changes in internal state, for " + + "example temperature or stored energy, which would affect the power or duration limits." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds on changes, or" + + "\n" + + " • When it changes from null to any other value and vice versa.", - Field({ name: "entry", type: "PowerAdjustStruct" }) - ), + xref: { document: "cluster", section: "9.2.8.6" } + }), Attribute({ name: "Forecast", id: 0x6, type: "ForecastStruct", access: "R V", conformance: "PFR | SFR", - default: null, quality: "X", + default: null, quality: "X Q", details: "This attribute allows an ESA to share its intended forecast with a client (such as an Energy " + "Management System)." + "\n" + - "A null value indicates that there is no forecast currently available" + - "\n" + - "yet been selected by the user)." + + "A null value indicates that there is no forecast currently available (for example, a program has " + + "not yet been selected by the user)." + "\n" + "A server may reset this value attribute to null on a reboot, and it does not need to persist any " + - "previous forecasts.", + "previous forecasts." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds on changes, or" + + "\n" + + " • When it changes from null to any other value and vice versa, or" + + "\n" + + " • As a result of a command which causes the forecast to be updated, or" + + "\n" + + " • As a result of a change in the opt-out status which in turn may cause the ESA to recalculate " + + " its forecast.", xref: { document: "cluster", section: "9.2.8.7" } }), @@ -429,9 +432,29 @@ export const DeviceEnergyManagement = Cluster( "optimization reasons, it shall reject any commands which have the AdjustmentCauseEnum value " + "LocalOptimization. If the ESA is in the GridOptOut or OptOut states, so it cannot be controlled by " + "an EMS for grid optimization reasons, it shall reject any commands which have the " + - "AdjustmentCauseEnum value GridOptimization. If the ESA is in the LocalOptOut, GridOptOut, or " + - "NoOptOut states, the device is still permitted to optimize its own energy usage, for example, using " + - "tariff information it may obtain.", + "AdjustmentCauseEnum value GridOptimization." + + "\n" + + "If the user changes the Opt-Out state of the ESA which is currently operating with a Forecast that " + + "is due to a previous StartTimeAdjustRequest, ModifyForecastRequest or " + + "RequestConstraintBasedForecast command that would now not be permitted due to the new Opt-out state" + + "\n" + + "attribute ForecastUpdateReason field currently contains a reason which is now opted out), the ESA " + + "shall behave as if it had received a CancelRequest command." + + "\n" + + "If the user changes the Opt-Out state of the ESA which currently has the ESAStateEnum with value " + + "Paused due to a previous PauseRequest command that would now not be permitted due to the new " + + "Opt-out state, and the ESA supports the PFR or SFR features (i.e. the Forecast attribute " + + "ForecastUpdateReason field currently contains a reason which is now opted out), the ESA shall " + + "behave as if it had received a ResumeRequest command." + + "\n" + + "If the user changes the Opt-Out state of the ESA which currently has the ESAStateEnum with value " + + "PowerAdjustActive due to a previous PowerAdjustRequest command that would now not be permitted due " + + "to the new Opt-out state (i.e. the Forecast attribute ForecastUpdateReason field currently contains " + + "a reason which is now opted out), the ESA shall behave as if it had received a " + + "CancelPowerAdjustRequest command." + + "\n" + + "If the ESA is in the LocalOptOut, GridOptOut, or NoOptOut states, the device is still permitted to " + + "optimize its own energy usage, for example, using tariff information it may obtain.", xref: { document: "cluster", section: "9.2.8.8" } }), @@ -465,9 +488,9 @@ export const DeviceEnergyManagement = Cluster( name: "EnergyUse", id: 0x2, type: "energy-mWh", conformance: "M", details: "This field shall indicate the approximate energy used by the ESA during the session." + "\n" + - "For example, if the ESA was on and was adjusted to be switched off, then this shall be 0W. If this " + - "was a battery inverter that was requested to charge it would have a negative energy use. If this " + - "was a normal load that was turned on, then it will have positive value.", + "For example, if the ESA was on and was adjusted to be switched off, then this shall be 0 mWh. If " + + "this was a battery inverter that was requested to discharge it would have a negative EnergyUse " + + "value. If this was a normal load that was turned on, then it will have positive value.", xref: { document: "cluster", section: "9.2.10.2.3" } }) ), @@ -558,7 +581,7 @@ export const DeviceEnergyManagement = Cluster( }), Field({ - name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", constraint: "desc", + name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", details: "This field shall indicate the cause of the request from the EMS.", xref: { document: "cluster", section: "9.2.9.3.2" } }) @@ -581,7 +604,7 @@ export const DeviceEnergyManagement = Cluster( }), Field({ - name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", constraint: "desc", + name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", details: "This field shall indicate the cause of the request from the EMS.", xref: { document: "cluster", section: "9.2.9.4.2" } }) @@ -604,7 +627,7 @@ export const DeviceEnergyManagement = Cluster( Field({ name: "ForecastId", id: 0x0, type: "uint32", conformance: "M", - details: "This field shall indicate the ForecastId that is to be modified.", + details: "This field shall indicate the ForecastID that is to be modified.", xref: { document: "cluster", section: "9.2.9.6.1" } }), @@ -612,7 +635,7 @@ export const DeviceEnergyManagement = Cluster( { name: "SlotAdjustments", id: 0x1, type: "list", conformance: "M", constraint: "max 10", details: "This field shall contain a list of SlotAdjustment parameters that should be modified in the " + - "corresponding Forecast with matching ForecastId.", + "corresponding Forecast with matching ForecastID.", xref: { document: "cluster", section: "9.2.9.6.2" } }, @@ -620,7 +643,7 @@ export const DeviceEnergyManagement = Cluster( ), Field({ - name: "Cause", id: 0x2, type: "AdjustmentCauseEnum", conformance: "M", constraint: "desc", + name: "Cause", id: 0x2, type: "AdjustmentCauseEnum", conformance: "M", details: "This field shall indicate the cause of the request from the EMS.", xref: { document: "cluster", section: "9.2.9.6.3" } }) @@ -639,7 +662,8 @@ export const DeviceEnergyManagement = Cluster( name: "Constraints", id: 0x0, type: "list", conformance: "M", constraint: "max 10", details: "This field shall indicate the series of turn up or turn down power requests that the ESA is being " + - "asked to constrain its operation within." + + "asked to constrain its operation within. These requests shall be in the future, shall be in " + + "chronological order, starting with the earliest start time, and shall NOT overlap in time." + "\n" + "For example, a grid event which requires devices to reduce power (turn down) between 4pm and 6pm " + "and due to excess power on the grid overnight, may request ESAs to increase their power demand " + @@ -648,8 +672,9 @@ export const DeviceEnergyManagement = Cluster( "If this ESA supports PFR this would have 2 entries in the list as follows:" + "\n" + "If this ESA supports SFR where it does not know the actual power, but has an understanding of the " + - "functions that use more energy, it could be requested to use more or less energy using the " + - "LoadControl field as follows:", + "functions that use more energy, it could be requested to use more or less energy using the LoadCon" + + "\n" + + "trol field as follows:", xref: { document: "cluster", section: "9.2.9.7.1" } }, @@ -658,7 +683,7 @@ export const DeviceEnergyManagement = Cluster( ), Field({ - name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", constraint: "desc", + name: "Cause", id: 0x1, type: "AdjustmentCauseEnum", conformance: "M", details: "This field shall indicate the cause of the request from the EMS.", xref: { document: "cluster", section: "9.2.9.7.2" } }) @@ -743,7 +768,7 @@ export const DeviceEnergyManagement = Cluster( description: "The ESA is in the middle of a power adjustment event" }), Field({ - name: "Paused", id: 0x4, conformance: "[FA]", + name: "Paused", id: 0x4, conformance: "PAU", description: "The ESA is currently paused by a client using the PauseRequest command" }) ), @@ -771,29 +796,29 @@ export const DeviceEnergyManagement = Cluster( Datatype( { name: "CauseEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.5" } }, Field({ - name: "NormalCompletion", id: 0x0, conformance: "O", + name: "NormalCompletion", id: 0x0, conformance: "M", description: "The ESA completed the power adjustment as requested" }), - Field({ name: "Offline", id: 0x1, conformance: "O", description: "The ESA was set to offline" }), + Field({ name: "Offline", id: 0x1, conformance: "M", description: "The ESA was set to offline" }), Field({ - name: "Fault", id: 0x2, conformance: "O", + name: "Fault", id: 0x2, conformance: "M", description: "The ESA has developed a fault could not complete the adjustment" }), Field({ - name: "UserOptOut", id: 0x3, conformance: "O", + name: "UserOptOut", id: 0x3, conformance: "M", description: "The user has disabled the ESA’s flexibility capability" }), - Field({ name: "Cancelled", id: 0x4, conformance: "O", description: "The adjustment was cancelled by a client" }) + Field({ name: "Cancelled", id: 0x4, conformance: "M", description: "The adjustment was cancelled by a client" }) ), Datatype( { name: "AdjustmentCauseEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.6" } }, Field({ - name: "LocalOptimization", id: 0x0, conformance: "O", + name: "LocalOptimization", id: 0x0, conformance: "M", description: "The adjustment is to optimize the local energy usage" }), Field({ - name: "GridOptimization", id: 0x1, conformance: "O", + name: "GridOptimization", id: 0x1, conformance: "M", description: "The adjustment is to optimize the grid energy usage" }) ), @@ -801,14 +826,27 @@ export const DeviceEnergyManagement = Cluster( Datatype( { name: "ForecastUpdateReasonEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.7" } }, Field({ - name: "InternalOptimization", id: 0x0, conformance: "O", + name: "InternalOptimization", id: 0x0, conformance: "M", description: "The update was due to internal ESA device optimization" }), Field({ - name: "LocalOptimization", id: 0x1, conformance: "O", + name: "LocalOptimization", id: 0x1, conformance: "M", description: "The update was due to local EMS optimization" }), - Field({ name: "GridOptimization", id: 0x2, conformance: "O", description: "The update was due to grid optimization" }) + Field({ name: "GridOptimization", id: 0x2, conformance: "M", description: "The update was due to grid optimization" }) + ), + + Datatype( + { name: "PowerAdjustReasonEnum", type: "enum8", xref: { document: "cluster", section: "9.2.7.8" } }, + Field({ name: "NoAdjustment", id: 0x0, conformance: "M", description: "There is no Power Adjustment active" }), + Field({ + name: "LocalOptimizationAdjustment", id: 0x1, conformance: "M", + description: "There is PowerAdjustment active due to local EMS optimization" + }), + Field({ + name: "GridOptimizationAdjustment", id: 0x2, conformance: "M", + description: "There is PowerAdjustment active due to local EMS optimization" + }) ), Datatype( @@ -816,13 +854,13 @@ export const DeviceEnergyManagement = Cluster( name: "CostStruct", type: "struct", details: "This indicates a generic mechanism for expressing cost to run an appliance, in terms of financial, " + "GHG emissions, comfort value etc.", - xref: { document: "cluster", section: "9.2.7.8" } + xref: { document: "cluster", section: "9.2.7.9" } }, Field({ name: "CostType", id: 0x0, type: "CostTypeEnum", conformance: "M", default: 0, details: "This field shall indicate the type of cost being represented (see CostTypeEnum).", - xref: { document: "cluster", section: "9.2.7.8.1" } + xref: { document: "cluster", section: "9.2.7.9.1" } }), Field({ @@ -832,7 +870,7 @@ export const DeviceEnergyManagement = Cluster( "\n" + "For example, if the Value was -302 and DecimalPoints was 2, then this would represent a benefit of " + "3.02.", - xref: { document: "cluster", section: "9.2.7.8.2" } + xref: { document: "cluster", section: "9.2.7.9.2" } }), Field({ @@ -840,7 +878,7 @@ export const DeviceEnergyManagement = Cluster( details: "This field shall indicate the number of digits to the right of the decimal point in the Value " + "field. For example, if the Value was 102 and DecimalPoints was 2, then this would represent a cost " + "of 1.02.", - xref: { document: "cluster", section: "9.2.7.8.3" } + xref: { document: "cluster", section: "9.2.7.9.3" } }), Field({ @@ -849,74 +887,96 @@ export const DeviceEnergyManagement = Cluster( "match the values defined by [ISO 4217]." + "\n" + "This is an optional field. It shall be included if CostType is Financial.", - xref: { document: "cluster", section: "9.2.7.8.4" } + xref: { document: "cluster", section: "9.2.7.9.4" } }) ), Datatype( - { name: "PowerAdjustStruct", type: "struct", xref: { document: "cluster", section: "9.2.7.9" } }, + { name: "PowerAdjustStruct", type: "struct", xref: { document: "cluster", section: "9.2.7.10" } }, Field({ name: "MinPower", id: 0x0, type: "power-mW", conformance: "M", default: 0, - details: "This field shall indicate the minimum power that the ESA can have its power adjusted to." + "\n" + - "Note that this is a signed value. Negative values indicate power flows away from loads (e.g. " + - "charging a battery inverter)." + - "\n" + - "MinPower shall be less than MaxPower.", - - xref: { document: "cluster", section: "9.2.7.9.1" } + "Note that this is a signed value. Negative values indicate power flows out of the node (e.g. " + + "discharging a battery).", + xref: { document: "cluster", section: "9.2.7.10.1" } }), Field({ - name: "MaxPower", id: 0x1, type: "power-mW", conformance: "M", default: 0, + name: "MaxPower", id: 0x1, type: "power-mW", conformance: "M", constraint: "min minPower", + default: 0, details: "This field shall indicate the maximum power that the ESA can have its power adjusted to." + "\n" + - "Note that this is a signed value. Negative values indicate power flows away from loads (e.g. " + - "charging a battery inverter)." + - "\n" + - "MinPower shall be less than MaxPower." + + "Note that this is a signed value. Negative values indicate power flows out of the node (e.g. " + + "discharging a battery)." + "\n" + "For example, if the charging current of an EVSE can be adjusted within the range of 6A to 32A on a " + "230V supply, then the power adjustment range is between 1380W and 7360W. Here the MinPower would be " + "1380W, and MaxPower would be 7360W." + "\n" + "For example, if a battery storage inverter can discharge between 0 to 3000W towards a load, then " + - "its MinPower would be 0W and its MaxPower would be 3000W." + + "power is flowing out of the node and is therefore negative. Its MinPower would be -3000W and its " + + "MaxPower would be 0W." + "\n" + "In another example, if a battery storage inverter can charge its internal battery, between 0W and " + - "2000W. Here power is flowing away from the home loads, so the power values need to be negative. As " + - "such the MinPower becomes -2000W and MaxPower becomes 0W.", + "2000W. Here power is flowing into the node when charging. As such the MinPower becomes 0W and " + + "MaxPower becomes 2000W.", - xref: { document: "cluster", section: "9.2.7.9.2" } + xref: { document: "cluster", section: "9.2.7.10.2" } }), Field({ name: "MinDuration", id: 0x2, type: "elapsed-s", conformance: "M", default: 0, details: "This field shall indicate the minimum duration, in seconds, that a controller may invoke an ESA " + "power adjustment. Manufacturers may use this to as an anti-cycling capability to avoid controllers " + - "from rapidly making power adjustments." + - "\n" + - "Note that MinDuration shall be less than MaxDuration.", - xref: { document: "cluster", section: "9.2.7.9.3" } + "from rapidly making power adjustments.", + xref: { document: "cluster", section: "9.2.7.10.3" } }), Field({ - name: "MaxDuration", id: 0x3, type: "elapsed-s", conformance: "M", - + name: "MaxDuration", id: 0x3, type: "elapsed-s", conformance: "M", constraint: "min minDuration", details: "This field shall indicate the maximum duration, in seconds, that a controller may invoke an ESA " + "power adjustment. Manufacturers may use this to protect the user experience, to avoid over heating " + "of the ESA, ensuring that there is sufficient headroom to use or store energy in the ESA or for any " + - "other reason." + - "\n" + - "Note that MinDuration shall be less than MaxDuration.", - - xref: { document: "cluster", section: "9.2.7.9.4" } + "other reason.", + xref: { document: "cluster", section: "9.2.7.10.4" } }) ), + Datatype( + { name: "PowerAdjustCapabilityStruct", type: "struct", xref: { document: "cluster", section: "9.2.7.11" } }, + + Field( + { + name: "PowerAdjustCapability", id: 0x0, type: "list", conformance: "M", constraint: "max 8", + default: null, quality: "X", + + details: "This field shall indicate how the ESA can be adjusted at the current time." + + "\n" + + "For example, a battery storage inverter may need to regulate its internal temperature, or the " + + "charging rate of the battery may be limited due to cold temperatures, or a change in the state of " + + "charge of the battery may mean that the maximum charging or discharging rate is limited." + + "\n" + + "An empty list shall indicate that no power adjustment is currently possible." + + "\n" + + "Multiple entries in the list allow indicating that permutations of scenarios may be possible." + + "\n" + + "For example, a 10kWh battery could be at 80% state of charge. If charging at 2kW, then it would be " + + "full in 1 hour. However, it could be discharged at 2kW for 4 hours." + + "\n" + + "In this example the list of PowerAdjustStructs allows multiple scenarios to be offered as follows:", + + xref: { document: "cluster", section: "9.2.7.12" } + }, + + Field({ name: "entry", type: "PowerAdjustStruct" }) + ), + + Field({ name: "Cause", id: 0x1, type: "PowerAdjustReasonEnum", conformance: "M", default: 0 }) + ), + Datatype( { name: "ForecastStruct", type: "struct", @@ -929,11 +989,11 @@ export const DeviceEnergyManagement = Cluster( "\n" + "feature and instead report its internal state.", - xref: { document: "cluster", section: "9.2.7.10" } + xref: { document: "cluster", section: "9.2.7.13" } }, Field({ - name: "ForecastId", id: 0x0, type: "uint16", conformance: "M", default: 0, + name: "ForecastId", id: 0x0, type: "uint32", conformance: "M", default: 0, details: "This field shall indicate the sequence number for the current forecast. If the ESA updates a " + "forecast, it shall monotonically increase this value." + @@ -942,36 +1002,34 @@ export const DeviceEnergyManagement = Cluster( "that any previous subscriptions are lost if a device reboots. The loss of a subscription and " + "subsequent re-subscription allows the EMS to learn about any new forecasts." + "\n" + - "The value of ForecastId is allowed to wrap.", + "The value of ForecastID is allowed to wrap.", - xref: { document: "cluster", section: "9.2.7.10.1" } + xref: { document: "cluster", section: "9.2.7.13.1" } }), Field({ name: "ActiveSlotNumber", id: 0x1, type: "uint16", conformance: "M", default: 0, quality: "X", details: "This field shall indicate which element of the Slots list is currently active in the Forecast " + "sequence. A null value indicates that the sequence has not yet started.", - xref: { document: "cluster", section: "9.2.7.10.2" } + xref: { document: "cluster", section: "9.2.7.13.2" } }), Field({ name: "StartTime", id: 0x2, type: "epoch-s", conformance: "M", details: "This field shall indicate the planned start time, in UTC, for the entire Forecast.", - xref: { document: "cluster", section: "9.2.7.10.3" } + xref: { document: "cluster", section: "9.2.7.13.3" } }), Field({ name: "EndTime", id: 0x3, type: "epoch-s", conformance: "M", details: "This field shall indicate the planned end time, in UTC, for the entire Forecast.", - xref: { document: "cluster", section: "9.2.7.10.4" } + xref: { document: "cluster", section: "9.2.7.13.4" } }), Field({ name: "EarliestStartTime", id: 0x4, type: "epoch-s", conformance: "STA", quality: "X", details: "This field shall indicate the earliest start time, in UTC, that the entire Forecast can be shifted " + - "to." + - "\n" + - "A null value indicates that it can be started immediately.", - xref: { document: "cluster", section: "9.2.7.10.5" } + "to. A null value indicates that it can be started immediately.", + xref: { document: "cluster", section: "9.2.7.13.5" } }), Field({ @@ -980,15 +1038,15 @@ export const DeviceEnergyManagement = Cluster( "\n" + "e.g. for an EVSE charging session, this may indicate the departure time for the vehicle, by which " + "time the charging session must end.", - xref: { document: "cluster", section: "9.2.7.10.6" } + xref: { document: "cluster", section: "9.2.7.13.6" } }), Field({ - name: "IsPauseable", id: 0x6, type: "bool", conformance: "M", + name: "IsPausable", id: 0x6, type: "bool", conformance: "M", details: "This field shall indicate that some part of the Forecast can be paused. It aims to allow a client " + "to read this flag and if it is false, then none of the slots contain SlotIsPausable set to true. " + "This can save a client from having to check each slot in the list.", - xref: { document: "cluster", section: "9.2.7.10.7" } + xref: { document: "cluster", section: "9.2.7.13.7" } }), Field( @@ -997,7 +1055,7 @@ export const DeviceEnergyManagement = Cluster( details: "This field shall contain a list of SlotStructs." + "\n" + "It shall contain at least 1 entry, and a maximum of 10.", - xref: { document: "cluster", section: "9.2.7.10.8" } + xref: { document: "cluster", section: "9.2.7.13.8" } }, Field({ name: "entry", type: "SlotStruct" }) @@ -1006,7 +1064,7 @@ export const DeviceEnergyManagement = Cluster( Field({ name: "ForecastUpdateReason", id: 0x8, type: "ForecastUpdateReasonEnum", conformance: "M", details: "This field shall contain the reason the current Forecast was generated.", - xref: { document: "cluster", section: "9.2.7.10.9" } + xref: { document: "cluster", section: "9.2.7.13.9" } }) ), @@ -1014,28 +1072,28 @@ export const DeviceEnergyManagement = Cluster( { name: "SlotStruct", type: "struct", details: "This indicates a specific stage of an ESA’s operation.", - xref: { document: "cluster", section: "9.2.7.11" } + xref: { document: "cluster", section: "9.2.7.14" } }, Field({ name: "MinDuration", id: 0x0, type: "elapsed-s", conformance: "M", details: "This field shall indicate the minimum time (in seconds) that the appliance expects to be in this " + "slot for.", - xref: { document: "cluster", section: "9.2.7.11.1" } + xref: { document: "cluster", section: "9.2.7.14.1" } }), Field({ name: "MaxDuration", id: 0x1, type: "elapsed-s", conformance: "M", details: "This field shall indicate the maximum time (in seconds) that the appliance expects to be in this " + "slot for.", - xref: { document: "cluster", section: "9.2.7.11.2" } + xref: { document: "cluster", section: "9.2.7.14.2" } }), Field({ name: "DefaultDuration", id: 0x2, type: "elapsed-s", conformance: "M", details: "This field shall indicate the expected time (in seconds) that the appliance expects to be in this " + "slot for.", - xref: { document: "cluster", section: "9.2.7.11.3" } + xref: { document: "cluster", section: "9.2.7.14.3" } }), Field({ @@ -1050,7 +1108,7 @@ export const DeviceEnergyManagement = Cluster( "\n" + "When the Forecast attribute is read, then this value shall be the most recent value.", - xref: { document: "cluster", section: "9.2.7.11.4" } + xref: { document: "cluster", section: "9.2.7.14.4" } }), Field({ @@ -1064,27 +1122,31 @@ export const DeviceEnergyManagement = Cluster( "When subscribed to, a change in this field value shall NOT cause the Forecast attribute to be " + "updated, since this value may change every 1 second." + "\n" + - "Note that if the ESA is currently paused, then this value shall not change." + + "Note that if the ESA is currently paused, then this value shall NOT change." + "\n" + "When the Forecast attribute is read, then this value shall be the most recent value.", - xref: { document: "cluster", section: "9.2.7.11.5" } + xref: { document: "cluster", section: "9.2.7.14.5" } }), - Field({ name: "SlotIsPauseable", id: 0x5, type: "bool", conformance: "PAU" }), + Field({ + name: "SlotIsPausable", id: 0x5, type: "bool", conformance: "PAU", + details: "This field shall indicate whether this slot can be paused.", + xref: { document: "cluster", section: "9.2.7.14.6" } + }), Field({ name: "MinPauseDuration", id: 0x6, type: "elapsed-s", conformance: "PAU", details: "This field shall indicate the shortest period that the slot can be paused for. This can be set to " + "avoid controllers trying to pause ESAs for short periods and then resuming operation in a cyclic " + "fashion which may damage or cause excess energy to be consumed with restarting of an operation.", - xref: { document: "cluster", section: "9.2.7.11.7" } + xref: { document: "cluster", section: "9.2.7.14.7" } }), Field({ name: "MaxPauseDuration", id: 0x7, type: "elapsed-s", conformance: "PAU", details: "This field shall indicate the longest period that the slot can be paused for.", - xref: { document: "cluster", section: "9.2.7.11.8" } + xref: { document: "cluster", section: "9.2.7.14.8" } }), Field({ @@ -1105,12 +1167,12 @@ export const DeviceEnergyManagement = Cluster( "NOTE An ESA shall always use the same value to represent the same operating state." + "\n" + "By providing this information a smart EMS may be able to learn the observed power draw when the ESA " + - "is put into a specific state. It can potentially then use the information in the " + - "PowerForecastReporting data to predict the power draw from the appliance and potentially ask it to " + - "modify its timing via one of the adjustment request commands, or adjust other ESAs power to " + - "compensate.", + "is put into a specific state. It can potentially then use the ManufacturerESAState field in the " + + "Forecast attribute along with observed power drawn to predict the power draw from the appliance and " + + "potentially ask it to modify its timing via one of the adjustment request commands, or adjust other " + + "ESAs power to compensate.", - xref: { document: "cluster", section: "9.2.7.11.9" } + xref: { document: "cluster", section: "9.2.7.14.9" } }), Field({ @@ -1118,7 +1180,7 @@ export const DeviceEnergyManagement = Cluster( details: "This field shall indicate the expected power that the appliance will use during this slot. It may " + "be considered the average value over the slot, and some variation from this would be expected (for " + "example, as it is ramping up).", - xref: { document: "cluster", section: "9.2.7.11.10" } + xref: { document: "cluster", section: "9.2.7.14.10" } }), Field({ @@ -1127,7 +1189,7 @@ export const DeviceEnergyManagement = Cluster( "(e.g. during a ramp up it may be 0W)." + "\n" + "Some appliances (e.g. battery inverters which can charge and discharge) may have a negative power.", - xref: { document: "cluster", section: "9.2.7.11.11" } + xref: { document: "cluster", section: "9.2.7.14.11" } }), Field({ @@ -1136,7 +1198,7 @@ export const DeviceEnergyManagement = Cluster( "(e.g. during a ramp up it may be 0W). This field ignores the effects of short-lived inrush currents." + "\n" + "Some appliances (e.g. battery inverters which can charge and discharge) may have a negative power.", - xref: { document: "cluster", section: "9.2.7.11.12" } + xref: { document: "cluster", section: "9.2.7.14.12" } }), Field({ @@ -1145,7 +1207,7 @@ export const DeviceEnergyManagement = Cluster( "this slot." + "\n" + "Some appliances (e.g. battery inverters which can charge and discharge) may have a negative energy.", - xref: { document: "cluster", section: "9.2.7.11.13" } + xref: { document: "cluster", section: "9.2.7.14.13" } }), Field( @@ -1173,7 +1235,7 @@ export const DeviceEnergyManagement = Cluster( "server) it may omit this field. This is treated as extra meta data that an EMS may use to optimize " + "a system.", - xref: { document: "cluster", section: "9.2.7.11.14" } + xref: { document: "cluster", section: "9.2.7.14.14" } }, Field({ name: "entry", type: "CostStruct" }) @@ -1189,7 +1251,7 @@ export const DeviceEnergyManagement = Cluster( "allows an ESA to indicate it could be switched on to charge, but this would be the minimum power " + "limit it can be set to.", - xref: { document: "cluster", section: "9.2.7.11.15" } + xref: { document: "cluster", section: "9.2.7.14.15" } }), Field({ @@ -1202,11 +1264,11 @@ export const DeviceEnergyManagement = Cluster( "allows an ESA to indicate it could be switched on to charge, but this would be the maximum power " + "limit it can be set to.", - xref: { document: "cluster", section: "9.2.7.11.16" } + xref: { document: "cluster", section: "9.2.7.14.16" } }), Field({ - name: "MinDurationAdjustment", id: 0x10, type: "elapsed-s", conformance: "FA & (PFR | SFR)", + name: "MinDurationAdjustment", id: 0x10, type: "elapsed-s", conformance: "FA", details: "This field shall indicate the minimum time, in seconds, that the slot can be requested to shortened " + "to." + @@ -1217,11 +1279,11 @@ export const DeviceEnergyManagement = Cluster( "\n" + "For example, a heat pump compressor may have a minimum cycle time of order a few minutes.", - xref: { document: "cluster", section: "9.2.7.11.17" } + xref: { document: "cluster", section: "9.2.7.14.17" } }), Field({ - name: "MaxDurationAdjustment", id: 0x11, type: "elapsed-s", conformance: "FA & (PFR | SFR)", + name: "MaxDurationAdjustment", id: 0x11, type: "elapsed-s", conformance: "FA", details: "This field shall indicate the maximum time, in seconds, that the slot can be requested to extended " + "to." + @@ -1232,26 +1294,29 @@ export const DeviceEnergyManagement = Cluster( "full. In the case of a battery inverter which can be discharged, it may equally indicate the " + "maximum time the battery could be discharged for (at the MaxPowerAdjustment power level).", - xref: { document: "cluster", section: "9.2.7.11.18" } + xref: { document: "cluster", section: "9.2.7.14.18" } }) ), Datatype( - { name: "SlotAdjustmentStruct", type: "struct", xref: { document: "cluster", section: "9.2.7.12" } }, + { name: "SlotAdjustmentStruct", type: "struct", xref: { document: "cluster", section: "9.2.7.15" } }, Field({ name: "SlotIndex", id: 0x0, type: "uint8", conformance: "M", constraint: "desc", details: "This field shall indicate the index into the Slots list within the Forecast that is to be modified. " + "It shall be less than the actual length of the Slots list (implicitly it must be in the range 0 to " + "9 based on the maximum length of the Slots list constraint).", - xref: { document: "cluster", section: "9.2.7.12.1" } + xref: { document: "cluster", section: "9.2.7.15.1" } }), Field({ - name: "NominalPower", id: 0x1, type: "power-mW", conformance: "M", constraint: "desc", + name: "NominalPower", id: 0x1, type: "power-mW", conformance: "PFR", constraint: "desc", details: "This field shall indicate the new requested power that the ESA shall operate at. It MUST be between " + - "the MinPowerAdjustment and MaxPowerAdjustment for the slot as advertised by the ESA.", - xref: { document: "cluster", section: "9.2.7.12.2" } + "the AbsMinPower and AbsMaxPower attributes as advertised by the ESA if it supports PFR." + + "\n" + + "This is a signed value and can be used to indicate charging or discharging. If the ESA does NOT " + + "support PFR this value shall be ignored by the ESA.", + xref: { document: "cluster", section: "9.2.7.15.2" } }), Field({ @@ -1259,7 +1324,7 @@ export const DeviceEnergyManagement = Cluster( details: "This field shall indicate the new requested duration, in seconds, that the ESA shall extend or " + "shorten the slot duration to. It MUST be between the MinDurationAdjustment and " + "MaxDurationAdjustment for the slot as advertised by the ESA.", - xref: { document: "cluster", section: "9.2.7.12.3" } + xref: { document: "cluster", section: "9.2.7.15.3" } }) ), @@ -1269,7 +1334,7 @@ export const DeviceEnergyManagement = Cluster( details: "The ConstraintsStruct allows a client to inform an ESA about a constraint period (such as a grid " + "event, or perhaps excess solar PV). The format allows the client to suggest that the ESA can either " + "turn up its energy consumption, or turn down its energy consumption during this period.", - xref: { document: "cluster", section: "9.2.7.13" } + xref: { document: "cluster", section: "9.2.7.16" } }, Field({ @@ -1278,26 +1343,23 @@ export const DeviceEnergyManagement = Cluster( "compute a new Forecast." + "\n" + "This value is in UTC and MUST be in the future.", - xref: { document: "cluster", section: "9.2.7.13.1" } + xref: { document: "cluster", section: "9.2.7.16.1" } }), Field({ - name: "Duration", id: 0x1, type: "elapsed-s", conformance: "M", constraint: "0 to 86400", + name: "Duration", id: 0x1, type: "elapsed-s", conformance: "M", constraint: "max 86400", details: "This field shall indicate the duration of the constraint in seconds.", - xref: { document: "cluster", section: "9.2.7.13.2" } + xref: { document: "cluster", section: "9.2.7.16.2" } }), Field({ name: "NominalPower", id: 0x2, type: "power-mW", conformance: "PFR", constraint: "desc", - details: "This field shall indicate the nominal power that client wishes the ESA to operate at during the " + "constrained period. It MUST be between the AbsMinPower and AbsMaxPower attributes as advertised by " + "the ESA if it supports PFR." + "\n" + - "This is a signed value and can be used to indicate charging or discharging. If the ESA does NOT " + - "support PFR this value shall be ignored by the ESA.", - - xref: { document: "cluster", section: "9.2.7.13.3" } + "This is a signed value and can be used to indicate charging or discharging.", + xref: { document: "cluster", section: "9.2.7.16.3" } }), Field({ @@ -1305,9 +1367,8 @@ export const DeviceEnergyManagement = Cluster( details: "This field shall indicate the maximum energy that can be transferred to or from the ESA during the " + "constraint period." + "\n" + - "This is a signed value and can be used to indicate charging or discharging. If the ESA does NOT " + - "support PFR this value may be ignored by the ESA.", - xref: { document: "cluster", section: "9.2.7.13.4" } + "This is a signed value and can be used to indicate charging or discharging.", + xref: { document: "cluster", section: "9.2.7.16.4" } }), Field({ @@ -1322,7 +1383,7 @@ export const DeviceEnergyManagement = Cluster( "\n" + "Note that the mapping between values and operation is manufacturer specific.", - xref: { document: "cluster", section: "9.2.7.13.5" } + xref: { document: "cluster", section: "9.2.7.16.5" } }) ) ); diff --git a/packages/model/src/standard/elements/DeviceEnergyManagementDT.ts b/packages/model/src/standard/elements/DeviceEnergyManagementDT.ts index 3e4afca31a..7725fb83cd 100644 --- a/packages/model/src/standard/elements/DeviceEnergyManagementDT.ts +++ b/packages/model/src/standard/elements/DeviceEnergyManagementDT.ts @@ -1,13 +1,17 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MatterDefinition } from "../MatterDefinition.js"; -import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; +import { + DeviceTypeElement as DeviceType, + RequirementElement as Requirement, + FieldElement as Field +} from "../../elements/index.js"; export const DeviceEnergyManagementDt = DeviceType( { @@ -19,16 +23,35 @@ export const DeviceEnergyManagementDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 1293, revision: 1 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 1293, revision: 2 } ], element: "attribute" }) ), + + Requirement( + { + name: "DeviceEnergyManagement", id: 0x98, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.7.4" } + }, + Requirement({ name: "POWERADJUSTMENT", conformance: "ControllableESA.a+", element: "feature" }), + Requirement({ name: "STARTTIMEADJUSTMENT", conformance: "ControllableESA.a+", element: "feature" }), + Requirement({ name: "PAUSABLE", conformance: "ControllableESA.a+", element: "feature" }), + Requirement({ name: "FORECASTADJUSTMENT", conformance: "ControllableESA.a+", element: "feature" }), + Requirement({ name: "CONSTRAINTBASEDADJUSTMENT", conformance: "ControllableESA.a+", element: "feature" }) + ), + Requirement({ - name: "DeviceEnergyManagement", id: 0x98, conformance: "P, M", element: "serverCluster", - xref: { document: "device", section: "2.7.3" } + name: "DeviceEnergyManagementMode", id: 0x9f, conformance: "ControllableESA, O", + element: "serverCluster", + xref: { document: "device", section: "2.7.4" } }), - Requirement({ - name: "DeviceEnergyManagementMode", id: 0x9f, conformance: "P, M", element: "serverCluster", - xref: { document: "device", section: "2.7.3" } - }) + + Field( + { name: "conditions", type: "enum8" }, + Field({ + name: "ControllableEsa", + description: "The DEM cluster on this endpoint accepts commands to adjust its energy operation.", + xref: { document: "device", section: "2.7.3" } + }) + ) ); MatterDefinition.children.push(DeviceEnergyManagementDt); diff --git a/packages/model/src/standard/elements/DeviceEnergyManagementMode.ts b/packages/model/src/standard/elements/DeviceEnergyManagementMode.ts index 01b38e4953..f11e02caf2 100644 --- a/packages/model/src/standard/elements/DeviceEnergyManagementMode.ts +++ b/packages/model/src/standard/elements/DeviceEnergyManagementMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,60 +10,97 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + DatatypeElement as Datatype } from "../../elements/index.js"; export const DeviceEnergyManagementMode = Cluster( { name: "DeviceEnergyManagementMode", id: 0x9f, type: "ModeBase", classification: "application", pics: "DEMM", - details: "This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced " + - "enumerated values for Device Energy Management devices." + - "\n" + - "NOTE Support for Device Energy Management Mode cluster is provisional.", - xref: { document: "cluster", section: "9.6" } + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for Device Energy Management devices.", + xref: { document: "cluster", section: "9.8" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.8.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + + details: "At least one entry in the SupportedModes attribute shall include the NoOptimization mode tag in the " + + "ModeTags field." + + "\n" + + "At least one entry in the SupportedModes attribute shall include the LocalOptimization mode tag in " + + "the ModeTags field list." + + "\n" + + "At least one entry in the SupportedModes attribute shall include the GridOptimization mode tag in " + + "the ModeTags field list." + + "\n" + + "An entry in the SupportedModes attribute that includes one of an DeviceOptimization, " + + "LocalOptimization, or GridOptimization tags shall NOT also include NoOptimization tag.", + + xref: { document: "cluster", section: "9.8.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "9.8.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "9.8.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "9.8.6" } }), Datatype({ name: "ModeOptionStruct", type: "ModeOptionStruct", details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + "ModeOptionStruct type. A blank field indicates no change.", - xref: { document: "cluster", section: "9.6.4.1" } + xref: { document: "cluster", section: "9.8.5.1" } }), Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "9.8.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "9.8.7.1" } }), Field({ name: "NoOptimization", id: 0x4000, details: "The device prohibits optimization of energy usage management: its energy usage is determined only " + - "by the user configuration and internal device needs. This tag cannot be included with any of the " + - "other tags defined below in a mode.", - xref: { document: "cluster", section: "9.6.5.1.1" } + "by the user configuration and internal device needs.", + xref: { document: "cluster", section: "9.8.7.1.1" } }), Field({ name: "DeviceOptimization", id: 0x4001, details: "The device is permitted to manage its own energy usage. For example, using tariff information it " + "may obtain.", - xref: { document: "cluster", section: "9.6.5.1.2" } + xref: { document: "cluster", section: "9.8.7.1.2" } }), Field({ name: "LocalOptimization", id: 0x4002, details: "The device permits management of energy usage by an energy manager to optimize the local energy " + "usage.", - xref: { document: "cluster", section: "9.6.5.1.3" } + xref: { document: "cluster", section: "9.8.7.1.3" } }), Field({ name: "GridOptimization", id: 0x4003, details: "The device permits management of energy usage by an energy manager to optimize the grid energy " + "usage.", - xref: { document: "cluster", section: "9.6.5.1.4" } + xref: { document: "cluster", section: "9.8.7.1.4" } }) ) ); diff --git a/packages/model/src/standard/elements/DiagnosticLogs.ts b/packages/model/src/standard/elements/DiagnosticLogs.ts index 406233f002..e589d86c54 100644 --- a/packages/model/src/standard/elements/DiagnosticLogs.ts +++ b/packages/model/src/standard/elements/DiagnosticLogs.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/DimmableLightDT.ts b/packages/model/src/standard/elements/DimmableLightDT.ts index 1f4cd3eb90..3482d5f41a 100644 --- a/packages/model/src/standard/elements/DimmableLightDT.ts +++ b/packages/model/src/standard/elements/DimmableLightDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/DimmablePlugInUnitDT.ts b/packages/model/src/standard/elements/DimmablePlugInUnitDT.ts index f14b40e409..c8b162448c 100644 --- a/packages/model/src/standard/elements/DimmablePlugInUnitDT.ts +++ b/packages/model/src/standard/elements/DimmablePlugInUnitDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/DimmerSwitchDT.ts b/packages/model/src/standard/elements/DimmerSwitchDT.ts index fcde530888..0e0d356c5a 100644 --- a/packages/model/src/standard/elements/DimmerSwitchDT.ts +++ b/packages/model/src/standard/elements/DimmerSwitchDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/DirectionNS.ts b/packages/model/src/standard/elements/DirectionNS.ts index 9f0f935510..69b0dbbf85 100644 --- a/packages/model/src/standard/elements/DirectionNS.ts +++ b/packages/model/src/standard/elements/DirectionNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/DishwasherAlarm.ts b/packages/model/src/standard/elements/DishwasherAlarm.ts index 30a702879f..af913e459f 100644 --- a/packages/model/src/standard/elements/DishwasherAlarm.ts +++ b/packages/model/src/standard/elements/DishwasherAlarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,8 @@ export const DishwasherAlarm = Cluster( { name: "DishwasherAlarm", id: 0x5d, type: "AlarmBase", classification: "application", pics: "DISHALM", - details: "This cluster is a derived cluster of the Alarm Base cluster.", + details: "This cluster is a derived cluster of the Alarm Base cluster and provides the alarm definition " + + "related to dishwasher devices.", xref: { document: "cluster", section: "8.4" } }, diff --git a/packages/model/src/standard/elements/DishwasherDT.ts b/packages/model/src/standard/elements/DishwasherDT.ts index 80b6eedc5b..475ba58663 100644 --- a/packages/model/src/standard/elements/DishwasherDT.ts +++ b/packages/model/src/standard/elements/DishwasherDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/DishwasherMode.ts b/packages/model/src/standard/elements/DishwasherMode.ts index 7d4191d410..f2ea0abce8 100644 --- a/packages/model/src/standard/elements/DishwasherMode.ts +++ b/packages/model/src/standard/elements/DishwasherMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,58 +10,72 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + DatatypeElement as Datatype } from "../../elements/index.js"; export const DishwasherMode = Cluster( { name: "DishwasherMode", id: 0x59, type: "ModeBase", classification: "application", pics: "DISHM", - details: "This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced " + + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + "enumerated values for dishwasher devices.", xref: { document: "cluster", section: "8.3" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), - Attribute({ name: "SupportedModes", id: 0x0, conformance: "M", xref: { document: "cluster", section: "8.3.5" } }), - Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.3.5" } }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.3.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), Attribute({ - name: "StartUpMode", id: 0x2, conformance: "P", - details: "If this attribute is supported, the device SHOULD initially set this to one of the supported modes " + - "that has the Normal tag associated with it. See the Mode Base cluster specification for full " + - "details about the StartUpMode attribute.", - xref: { document: "cluster", section: "8.3.5.1" } + name: "SupportedModes", id: 0x0, conformance: "M", + details: "At least one entry in the SupportedModes attribute shall include the Normal mode tag in the " + + "ModeTags field list.", + xref: { document: "cluster", section: "8.3.6.1" } }), - Attribute({ name: "OnMode", id: 0x3, conformance: "P", xref: { document: "cluster", section: "8.3.5" } }), + Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.3.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.3.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.3.6" } }), Datatype({ name: "ModeOptionStruct", type: "ModeOptionStruct", details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + - "ModeOptionStruct type. A blank field indicates no change." + - "\n" + - "At least one entry in the SupportedModes attribute shall include the Normal mode tag in the " + - "ModeTags field list.", - xref: { document: "cluster", section: "8.3.4.1" } + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "8.3.5.1" } }), Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.3.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.3.7.1" } }), Field({ name: "Normal", id: 0x4000, details: "The normal regime of operation.", - xref: { document: "cluster", section: "8.3.6.1.1" } + xref: { document: "cluster", section: "8.3.7.1.1" } }), Field({ name: "Heavy", id: 0x4001, details: "Mode optimized for washing heavily-soiled dishes.", - xref: { document: "cluster", section: "8.3.6.1.2" } + xref: { document: "cluster", section: "8.3.7.1.2" } }), Field({ name: "Light", id: 0x4002, details: "Mode optimized for light washing.", - xref: { document: "cluster", section: "8.3.6.1.3" } + xref: { document: "cluster", section: "8.3.7.1.3" } }) ) ); diff --git a/packages/model/src/standard/elements/DoorLock.ts b/packages/model/src/standard/elements/DoorLock.ts index f3972b2dce..100f60bf7d 100644 --- a/packages/model/src/standard/elements/DoorLock.ts +++ b/packages/model/src/standard/elements/DoorLock.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -21,11 +21,13 @@ export const DoorLock = Cluster( name: "DoorLock", id: 0x101, classification: "application", pics: "DRLK", details: "The door lock cluster provides an interface to a generic way to secure a door. The physical object " + "that provides the locking functionality is abstracted from the cluster. The cluster has a small " + - "list of mandatory attributes and functions and a list of optional features.", + "list of mandatory attributes and functions and a list of optional features." + + "\n" + + "Figure 16. Typical Usage of the Door Lock Cluster", xref: { document: "cluster", section: "5.2" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 7 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 8 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "5.2.4" } }, @@ -51,9 +53,7 @@ export const DoorLock = Cluster( "\n" + "A lock may support multiple credential types so if the User feature is supported the UserType, " + "UserStatus and Schedules are all associated with a User index and not directly with a RFID index. A " + - "User" + - "\n" + - "Index may have several credentials associated with it.", + "User Index may have several credentials associated with it.", xref: { document: "cluster", section: "5.2.4.2" } }), @@ -73,31 +73,27 @@ export const DoorLock = Cluster( xref: { document: "cluster", section: "5.2.4.3" } }), - Field({ - name: "LOG", conformance: "O", constraint: "3", description: "Logging", - details: "If Events are not supported the logging feature shall replace the Event reporting structure. If " + - "Events are supported the logging feature shall NOT be supported.", - xref: { document: "cluster", section: "5.2.4.4" } - }), - Field({ name: "WDSCH", conformance: "O", constraint: "4", description: "WeekDayAccessSchedules", details: "If the User feature is supported then Week Day Schedules are applied to a User and not a credential." + "\n" + "Week Day Schedules are used to restrict access to a specified time window on certain days of the " + - "week. The schedule is repeated each week. When a schedule is cleared this clears the access " + - "restrictions and grants unrestricted access to the user. The lock may automatically adjust the " + - "UserType when a schedule is created or cleared.", + "week. The schedule is repeated each week." + + "\n" + + "The lock may automatically adjust the UserType when a schedule is created or cleared." + + "\n" + + "Support for WeekDayAccessSchedules requires that the lock has the capability of keeping track of " + + "local time.", - xref: { document: "cluster", section: "5.2.4.5" } + xref: { document: "cluster", section: "5.2.4.4" } }), Field({ name: "DPS", conformance: "O", constraint: "5", description: "DoorPositionSensor", details: "If this feature is supported this indicates that the lock has the ability to determine the position " + "of the door which is separate from the state of the lock.", - xref: { document: "cluster", section: "5.2.4.6" } + xref: { document: "cluster", section: "5.2.4.5" } }), Field({ @@ -112,48 +108,49 @@ export const DoorLock = Cluster( "A lock may support multiple credential types so if the User feature is supported the UserType, " + "UserStatus and Schedules are all associated with a User and not directly with a credential.", - xref: { document: "cluster", section: "5.2.4.7" } + xref: { document: "cluster", section: "5.2.4.6" } }), Field({ name: "COTA", conformance: "O", constraint: "7", description: "CredentialOverTheAirAccess", - details: "If this feature is supported then the lock supports the ability to verify a credential provided in " + - "a lock/unlock command. Currently the cluster only supports providing the PIN credential to the " + + details: "If this feature is supported then the lock supports the ability to verify a credential provided in a" + + "\n" + + "lock/unlock command. Currently the cluster only supports providing the PIN credential to the " + "lock/unlock commands. If this feature is supported then the PIN Credential feature shall also be " + "supported.", - xref: { document: "cluster", section: "5.2.4.8" } + xref: { document: "cluster", section: "5.2.4.7" } }), Field({ - name: "USR", conformance: "[PIN | RID | FGP | FACE]", constraint: "8", description: "User", + name: "USR", conformance: "ALIRO, [PIN | RID | FGP | FACE]", constraint: "8", description: "User", details: "If the User Feature is supported then a lock employs a User database. A User within the User " + "database is used to associate credentials and schedules to single user record within the lock. This " + "also means the UserType and UserStatus fields are associated with a User and not a credential.", - xref: { document: "cluster", section: "5.2.4.9" } - }), - - Field({ - name: "NOT", conformance: "O", constraint: "9", description: "Notification", - details: "This is a feature used before support of events. This feature supports notification commands and " + - "masks used to filter these notifications.", - xref: { document: "cluster", section: "5.2.4.10" } + xref: { document: "cluster", section: "5.2.4.8" } }), Field({ name: "YDSCH", conformance: "O", constraint: "10", description: "YearDayAccessSchedules", - details: "If the User feature is supported then Year Day Schedules are applied to a User and not a credential." + + + details: "If the User feature is supported then Year Day Schedules are applied to a User and not a " + + "credential. Year Day Schedules are used to restrict access to a specified date and time window." + "\n" + - "Year Day Schedules are used to restrict access to a specified date and time window. When a schedule " + - "is cleared this clears the access restrictions and grants unrestricted access to the user. The lock " + - "may automatically adjust the UserType when a schedule is created or cleared.", - xref: { document: "cluster", section: "5.2.4.11" } + "The lock may automatically adjust the UserType when a schedule is created or cleared." + + "\n" + + "Support for YearDayAccessSchedules requires that the lock has the capability of keeping track of " + + "local time.", + + xref: { document: "cluster", section: "5.2.4.9" } }), Field({ name: "HDSCH", conformance: "O", constraint: "11", description: "HolidaySchedules", details: "This feature is used to setup Holiday Schedule in the lock device. A Holiday Schedule sets a start " + - "and stop end date/time for the lock to use the specified operating mode set by the Holiday Schedule.", - xref: { document: "cluster", section: "5.2.4.12" } + "and stop end date/time for the lock to use the specified operating mode set by the Holiday Schedule." + + "\n" + + "Support for HolidaySchedules requires that the lock has the capability of keeping track of local " + + "time.", + xref: { document: "cluster", section: "5.2.4.10" } }), Field({ @@ -163,13 +160,27 @@ export const DoorLock = Cluster( "by retracting the bolt and briefly pulling the latch. While the latch is pulled, the lock state " + "changes to Unlatched. Locks without unbolting support don’t differentiate between unbolting and " + "unlocking and perform the same operation for both commands.", + xref: { document: "cluster", section: "5.2.4.11" } + }), + + Field({ + name: "ALIRO", conformance: "O", constraint: "13", description: "AliroProvisioning", + details: "Locks that support this feature implement the Aliro specification as defined in [Aliro] and support " + + "Matter as a method for provisioning Aliro credentials.", + xref: { document: "cluster", section: "5.2.4.12" } + }), + + Field({ + name: "ALBU", conformance: "[ALIRO]", constraint: "14", description: "AliroBleuwb", + details: "Locks that support this feature implement the Bluetooth LE + UWB Access Control Flow as defined in " + + "[Aliro].", xref: { document: "cluster", section: "5.2.4.13" } }) ), Attribute({ name: "LockState", id: 0x0, type: "LockStateEnum", access: "R V", conformance: "M", - constraint: "desc", quality: "X S P", + constraint: "desc", quality: "X P", details: "This attribute may be NULL if the lock hardware does not currently know the status of the locking " + "mechanism. For example, a lock may not know the LockState status after a power cycle until the " + @@ -179,21 +190,21 @@ export const DoorLock = Cluster( "between Locked and Unlocked so it is only partially secured. For example, a deadbolt could be " + "partially extended and not in a dead latched state.", - xref: { document: "cluster", section: "5.2.9.2" } + xref: { document: "cluster", section: "5.2.9.1" } }), Attribute({ name: "LockType", id: 0x1, type: "LockTypeEnum", access: "R V", conformance: "M", constraint: "desc", details: "Indicates the type of door lock as defined in LockTypeEnum.", - xref: { document: "cluster", section: "5.2.9.3" } + xref: { document: "cluster", section: "5.2.9.2" } }), Attribute({ name: "ActuatorEnabled", id: 0x2, type: "bool", access: "R V", conformance: "M", details: "Indicates if the lock is currently able to (Enabled) or not able to (Disabled) process remote Lock, " + "Unlock, or Unlock with Timeout commands.", - xref: { document: "cluster", section: "5.2.9.4" } + xref: { document: "cluster", section: "5.2.9.3" } }), Attribute({ @@ -202,88 +213,81 @@ export const DoorLock = Cluster( details: "Indicates the current door state as defined in DoorStateEnum." + "\n" + "Null only if an internal error prevents the retrieval of the current door state.", - xref: { document: "cluster", section: "5.2.9.5" } + xref: { document: "cluster", section: "5.2.9.4" } }), Attribute({ name: "DoorOpenEvents", id: 0x4, type: "uint32", access: "RW VM", conformance: "[DPS]", details: "This attribute shall hold the number of door open events that have occurred since it was last " + "zeroed.", - xref: { document: "cluster", section: "5.2.9.6" } + xref: { document: "cluster", section: "5.2.9.5" } }), Attribute({ name: "DoorClosedEvents", id: 0x5, type: "uint32", access: "RW VM", conformance: "[DPS]", details: "This attribute shall hold the number of door closed events that have occurred since it was last " + "zeroed.", - xref: { document: "cluster", section: "5.2.9.7" } + xref: { document: "cluster", section: "5.2.9.6" } }), Attribute({ name: "OpenPeriod", id: 0x6, type: "uint16", access: "RW VM", conformance: "[DPS]", details: "This attribute shall hold the number of minutes the door has been open since the last time it " + "transitioned from closed to open.", - xref: { document: "cluster", section: "5.2.9.8" } - }), - - Attribute({ - name: "NumberOfLogRecordsSupported", id: 0x10, type: "uint16", access: "R V", conformance: "LOG", - default: 0, quality: "F", - details: "Indicates the number of available log records.", - xref: { document: "cluster", section: "5.2.9.9" } + xref: { document: "cluster", section: "5.2.9.7" } }), Attribute({ name: "NumberOfTotalUsersSupported", id: 0x11, type: "uint16", access: "R V", conformance: "USR", default: 0, quality: "F", details: "Indicates the number of total users supported by the lock.", - xref: { document: "cluster", section: "5.2.9.10" } + xref: { document: "cluster", section: "5.2.9.8" } }), Attribute({ name: "NumberOfPinUsersSupported", id: 0x12, type: "uint16", access: "R V", conformance: "PIN", default: 0, quality: "F", details: "Indicates the number of PIN users supported.", - xref: { document: "cluster", section: "5.2.9.11" } + xref: { document: "cluster", section: "5.2.9.9" } }), Attribute({ name: "NumberOfRfidUsersSupported", id: 0x13, type: "uint16", access: "R V", conformance: "RID", default: 0, quality: "F", details: "Indicates the number of RFID users supported.", - xref: { document: "cluster", section: "5.2.9.12" } + xref: { document: "cluster", section: "5.2.9.10" } }), Attribute({ name: "NumberOfWeekDaySchedulesSupportedPerUser", id: 0x14, type: "uint8", access: "R V", - conformance: "WDSCH", default: 0, quality: "F", + conformance: "WDSCH", constraint: "max 253", default: 0, quality: "F", details: "Indicates the number of configurable week day schedule supported per user.", - xref: { document: "cluster", section: "5.2.9.13" } + xref: { document: "cluster", section: "5.2.9.11" } }), Attribute({ name: "NumberOfYearDaySchedulesSupportedPerUser", id: 0x15, type: "uint8", access: "R V", - conformance: "YDSCH", default: 0, quality: "F", + conformance: "YDSCH", constraint: "max 253", default: 0, quality: "F", details: "Indicates the number of configurable year day schedule supported per user.", - xref: { document: "cluster", section: "5.2.9.14" } + xref: { document: "cluster", section: "5.2.9.12" } }), Attribute({ name: "NumberOfHolidaySchedulesSupported", id: 0x16, type: "uint8", access: "R V", - conformance: "HDSCH", default: 0, quality: "F", + conformance: "HDSCH", constraint: "max 253", default: 0, quality: "F", details: "Indicates the number of holiday schedules supported for the entire door lock device.", - xref: { document: "cluster", section: "5.2.9.15" } + xref: { document: "cluster", section: "5.2.9.13" } }), Attribute({ name: "MaxPinCodeLength", id: 0x17, type: "uint8", access: "R V", conformance: "PIN", quality: "F", details: "Indicates the maximum length in bytes of a PIN Code on this device.", - xref: { document: "cluster", section: "5.2.9.16" } + xref: { document: "cluster", section: "5.2.9.14" } }), Attribute({ name: "MinPinCodeLength", id: 0x18, type: "uint8", access: "R V", conformance: "PIN", quality: "F", details: "Indicates the minimum length in bytes of a PIN Code on this device.", - xref: { document: "cluster", section: "5.2.9.17" } + xref: { document: "cluster", section: "5.2.9.15" } }), Attribute({ @@ -291,7 +295,7 @@ export const DoorLock = Cluster( details: "Indicates the maximum length in bytes of a RFID Code on this device. The value depends on the RFID " + "code range specified by the manufacturer, if media anti-collision identifiers (UID) are used as " + "RFID code, a value of 20 (equals 10 Byte ISO 14443A UID) is recommended.", - xref: { document: "cluster", section: "5.2.9.18" } + xref: { document: "cluster", section: "5.2.9.16" } }), Attribute({ @@ -299,7 +303,7 @@ export const DoorLock = Cluster( details: "Indicates the minimum length in bytes of a RFID Code on this device. The value depends on the RFID " + "code range specified by the manufacturer, if media anti-collision identifiers (UID) are used as " + "RFID code, a value of 8 (equals 4 Byte ISO 14443A UID) is recommended.", - xref: { document: "cluster", section: "5.2.9.19" } + xref: { document: "cluster", section: "5.2.9.17" } }), Attribute({ @@ -307,7 +311,7 @@ export const DoorLock = Cluster( conformance: "USR", default: 1, quality: "F", details: "This attribute shall contain a bitmap with the bits set for the values of CredentialRuleEnum " + "supported on this device.", - xref: { document: "cluster", section: "5.2.9.20" } + xref: { document: "cluster", section: "5.2.9.18" } }), Attribute({ @@ -324,21 +328,7 @@ export const DoorLock = Cluster( "NumberOfRFIDUsersSupported is set to 3, it will not be possible to actually assign 10 credentials " + "for a user because maximum number of credentials in the database is 8.", - xref: { document: "cluster", section: "5.2.9.21" } - }), - - Attribute({ - name: "EnableLogging", id: 0x20, type: "bool", access: "R[W] VA", conformance: "LOG", default: true, - quality: "P", - - details: "This attribute shall enable/disable event logging." + - "\n" + - "When event logging is enabled, all event messages are stored on the lock for retrieval. Logging " + - "events can be, but are not limited to, Tamper Alarm, Lock, Unlock, AutoRelock, User Code Added, " + - "User Code Cleared, Schedule Added, and Schedule Cleared. For a full detail of all the possible " + - "alarms and events, please refer to the full list in the Alarm and Event Masks Attribute Set.", - - xref: { document: "cluster", section: "5.2.9.22" } + xref: { document: "cluster", section: "5.2.9.19" } }), Attribute({ @@ -346,14 +336,14 @@ export const DoorLock = Cluster( constraint: "max 3", quality: "P", details: "Indicates the language for the on-screen or audible user interface using a 2- byte language code " + "from ISO-639-1.", - xref: { document: "cluster", section: "5.2.9.23" } + xref: { document: "cluster", section: "5.2.9.20" } }), Attribute({ name: "LedSettings", id: 0x22, type: "LEDSettingEnum", access: "R[W] VM", conformance: "O", default: 0, quality: "P", details: "Indicates the settings for the LED support, as defined by LEDSettingEnum.", - xref: { document: "cluster", section: "5.2.9.24" } + xref: { document: "cluster", section: "5.2.9.21" } }), Attribute({ @@ -361,21 +351,21 @@ export const DoorLock = Cluster( details: "Indicates the number of seconds to wait after unlocking a lock before it automatically locks again. " + "0=disabled. If set, unlock operations from any source will be timed. For one time unlock with " + "timeout use the specific command.", - xref: { document: "cluster", section: "5.2.9.25" } + xref: { document: "cluster", section: "5.2.9.22" } }), Attribute({ name: "SoundVolume", id: 0x24, type: "SoundVolumeEnum", access: "R[W] VM", conformance: "O", default: 0, quality: "P", details: "Indicates the sound volume on a door lock as defined by SoundVolumeEnum.", - xref: { document: "cluster", section: "5.2.9.26" } + xref: { document: "cluster", section: "5.2.9.23" } }), Attribute({ name: "OperatingMode", id: 0x25, type: "OperatingModeEnum", access: "R[W] VM", conformance: "M", constraint: "desc", default: 0, quality: "P", details: "Indicates the current operating mode of the lock as defined in OperatingModeEnum.", - xref: { document: "cluster", section: "5.2.9.27" } + xref: { document: "cluster", section: "5.2.9.24" } }), Attribute({ @@ -384,7 +374,7 @@ export const DoorLock = Cluster( details: "This attribute shall contain a bitmap with all operating bits of the OperatingMode attribute " + "supported by the lock. All operating modes NOT supported by a lock shall be set to one. The value " + "of the OperatingMode enumeration defines the related bit to be set.", - xref: { document: "cluster", section: "5.2.9.28" } + xref: { document: "cluster", section: "5.2.9.25" } }), Attribute({ @@ -392,8 +382,10 @@ export const DoorLock = Cluster( conformance: "O", default: 0, quality: "P", details: "Indicates the default configurations as they are physically set on the device (example: hardware " + - "dip switch setting, etc…) and represents the default setting for some of the attributes within this " + - "cluster (for example: LED, Auto Lock, Sound Volume, and Operating Mode attributes)." + + "dip switch setting, etc…) and represents the default setting for some of the" + + "\n" + + "attributes within this cluster (for example: LED, Auto Lock, Sound Volume, and Operating Mode " + + "attributes)." + "\n" + "This is a read-only attribute and is intended to allow clients to determine what changes may need " + "to be made without having to query all the included attributes. It may be beneficial for the " + @@ -407,7 +399,7 @@ export const DoorLock = Cluster( "the current Sound Volume is High Volume. Therefore, if the client wants to query/modify the current " + "Sound Volume setting on the server, the client SHOULD read/write to the Sound Volume attribute.", - xref: { document: "cluster", section: "5.2.9.29" } + xref: { document: "cluster", section: "5.2.9.26" } }), Attribute({ @@ -418,7 +410,7 @@ export const DoorLock = Cluster( "on the door lock for all features. If it is set to FALSE then local programming is disabled on the " + "door lock for those features whose bit is set to 0 in the LocalProgrammingFeatures attribute. Local " + "programming shall be enabled by default.", - xref: { document: "cluster", section: "5.2.9.30" } + xref: { document: "cluster", section: "5.2.9.27" } }), Attribute({ @@ -426,7 +418,7 @@ export const DoorLock = Cluster( default: true, quality: "P", details: "This attribute shall enable/disable the ability to lock the door lock with a single touch on the " + "door lock.", - xref: { document: "cluster", section: "5.2.9.31" } + xref: { document: "cluster", section: "5.2.9.28" } }), Attribute({ @@ -434,7 +426,7 @@ export const DoorLock = Cluster( default: true, quality: "P", details: "This attribute shall enable/disable an inside LED that allows the user to see at a glance if the " + "door is locked.", - xref: { document: "cluster", section: "5.2.9.32" } + xref: { document: "cluster", section: "5.2.9.29" } }), Attribute({ @@ -442,7 +434,7 @@ export const DoorLock = Cluster( default: true, quality: "P", details: "This attribute shall enable/disable a button inside the door that is used to put the lock into " + "privacy mode. When the lock is in privacy mode it cannot be manipulated from the outside.", - xref: { document: "cluster", section: "5.2.9.33" } + xref: { document: "cluster", section: "5.2.9.30" } }), Attribute({ @@ -458,7 +450,7 @@ export const DoorLock = Cluster( "The features that can be disabled from local programming are defined in " + "LocalProgrammingFeaturesBitmap.", - xref: { document: "cluster", section: "5.2.9.34" } + xref: { document: "cluster", section: "5.2.9.31" } }), Attribute({ @@ -476,7 +468,7 @@ export const DoorLock = Cluster( "internal logic, environmental events, or other reasons. The lock shall reset the counter if a valid " + "credential is presented.", - xref: { document: "cluster", section: "5.2.9.35" } + xref: { document: "cluster", section: "5.2.9.32" } }), Attribute({ @@ -486,7 +478,7 @@ export const DoorLock = Cluster( "1-255 seconds. Device can shut down to lock user out for specified amount of time. (Makes it " + "difficult to try and guess a PIN for the device.) If the attribute accepts writes and an attempt to " + "write the attribute to 0 is made, the device shall respond with CONSTRAINT_ERROR.", - xref: { document: "cluster", section: "5.2.9.36" } + xref: { document: "cluster", section: "5.2.9.33" } }), Attribute({ @@ -498,12 +490,13 @@ export const DoorLock = Cluster( "server’s TX operation. If it is false, then it is not ok for the device to send PIN in any messages " + "over the air." + "\n" + - "The PIN field within any door lock cluster message shall keep the first octet unchanged and masks " + - "the actual code by replacing with 0xFF. For example (PIN \"1234\" ): If the attribute value is True, " + - "0x04 0x31 0x32 0x33 0x34 shall be used in the PIN field in any door lock cluster message payload. " + - "If the attribute value is False, 0x04 0xFF 0xFF 0xFF 0xFF shall be used.", + "The PIN field within any door lock cluster message shall keep the first octet unchanged and" + + "\n" + + "masks the actual code by replacing with 0xFF. For example (PIN \"1234\" ): If the attribute value is " + + "True, 0x04 0x31 0x32 0x33 0x34 shall be used in the PIN field in any door lock cluster message " + + "payload. If the attribute value is False, 0x04 0xFF 0xFF 0xFF 0xFF shall be used.", - xref: { document: "cluster", section: "5.2.9.37" } + xref: { document: "cluster", section: "5.2.9.34" } }), Attribute({ @@ -512,11 +505,11 @@ export const DoorLock = Cluster( details: "Indicates if the door lock requires an optional PIN. If this attribute is set to True, the door " + "lock server requires that an optional PINs be included in the payload of remote lock operation " + "events like Lock, Unlock, Unlock with Timeout and Toggle in order to function.", - xref: { document: "cluster", section: "5.2.9.38" } + xref: { document: "cluster", section: "5.2.9.35" } }), Attribute({ - name: "SecurityLevel", id: 0x34, conformance: "D", default: "0", + name: "SecurityLevel", id: 0x34, access: "R V", conformance: "D", default: "0", xref: { document: "cluster", section: "5.2.9" } }), @@ -527,7 +520,7 @@ export const DoorLock = Cluster( "user of type ExpiringUser shall remain valid after its first use before expiring. When the " + "credential expires the UserStatus for the corresponding user record shall be set to " + "OccupiedDisabled.", - xref: { document: "cluster", section: "5.2.9.39" } + xref: { document: "cluster", section: "5.2.9.36" } }), Attribute({ @@ -541,109 +534,100 @@ export const DoorLock = Cluster( "\n" + "This mask DOES NOT apply to the Events mechanism of this cluster.", - xref: { document: "cluster", section: "5.2.9.40" } - }), - - Attribute({ - name: "KeypadOperationEventMask", id: 0x41, type: "EventMaskBitmap", access: "RW VA", - conformance: "[NOT & PIN]", default: 65535, quality: "P", - details: "Event mask used to turn on and off the transmission of keypad operation events. This mask DOES NOT " + - "apply to the storing of events in the event log. This mask only applies to the Operation Event " + - "Notification Command." + - "\n" + - "This mask DOES NOT apply to the Events mechanism of this cluster.", - xref: { document: "cluster", section: "5.2.9.41" } + xref: { document: "cluster", section: "5.2.9.37" } }), Attribute({ - name: "RemoteOperationEventMask", id: 0x42, type: "EventMaskBitmap", access: "RW VA", - conformance: "[NOT]", default: 65535, quality: "P", - details: "Event mask used to turn on and off the transmission of remote operation events. This mask DOES NOT " + - "apply to the storing of events in the event log. This mask only applies to the Operation Event " + - "Notification Command." + + name: "AliroReaderVerificationKey", id: 0x80, type: "octstr", access: "R A", conformance: "ALIRO", + constraint: "65", default: null, quality: "X", + details: "Indicates the verification key component of the Reader’s key pair as defined in [Aliro]. The value, " + + "if not null, shall be an uncompressed elliptic curve public key as defined in section 2.3.3 of SEC " + + "1." + "\n" + - "This mask DOES NOT apply to the Events mechanism of this cluster.", - xref: { document: "cluster", section: "5.2.9.42" } + "Null if no Reader key pair has been configured on the lock. See SetAliroReaderConfig.", + xref: { document: "cluster", section: "5.2.9.38" } }), Attribute({ - name: "ManualOperationEventMask", id: 0x43, type: "EventMaskBitmap", access: "RW VA", - conformance: "[NOT]", default: 65535, quality: "P", - details: "Event mask used to turn on and off manual operation events. This mask DOES NOT apply to the storing " + - "of events in the event log. This mask only applies to the Operation Event Notification Command." + + name: "AliroReaderGroupIdentifier", id: 0x81, type: "octstr", access: "R A", conformance: "ALIRO", + constraint: "16", default: null, quality: "X", + details: "Indicates the reader_group_identifier as defined in [Aliro]." + "\n" + - "This mask DOES NOT apply to the Events mechanism of this cluster.", - xref: { document: "cluster", section: "5.2.9.43" } + "Null if no reader_group_identifier has been configured on the lock. See SetAliroReaderConfig.", + xref: { document: "cluster", section: "5.2.9.39" } }), Attribute({ - name: "RfidOperationEventMask", id: 0x44, type: "EventMaskBitmap", access: "RW VA", - conformance: "[NOT & RID]", default: 65535, quality: "P", - details: "Event mask used to turn on and off RFID operation events. This mask DOES NOT apply to the storing " + - "of events in the event log. This mask only applies to the Operation Event Notification Command." + - "\n" + - "This mask DOES NOT apply to the Events mechanism of this cluster.", - xref: { document: "cluster", section: "5.2.9.44" } + name: "AliroReaderGroupSubIdentifier", id: 0x82, type: "octstr", access: "R A", + conformance: "ALIRO", constraint: "16", quality: "F", + details: "Indicates the reader_group_sub_identifier as defined in [Aliro].", + xref: { document: "cluster", section: "5.2.9.40" } }), Attribute( { - name: "KeypadProgrammingEventMask", id: 0x45, type: "EventMaskBitmap", access: "RW VA", - conformance: "[NOT & PIN]", default: 65535, quality: "P", - details: "Event mask used to turn on and off keypad programming events. This mask DOES NOT apply to the " + - "storing of events in the event log. This mask only applies to the Programming Event Notification " + - "Command." + - "\n" + - "This mask DOES NOT apply to the Events mechanism of this cluster.", - xref: { document: "cluster", section: "5.2.9.45" } + name: "AliroExpeditedTransactionSupportedProtocolVersions", id: 0x83, type: "list", access: "R A", + conformance: "ALIRO", constraint: "max 16[2]", default: [], quality: "F", + details: "Indicates the list of protocol versions supported for expedited transactions as defined in [Aliro].", + xref: { document: "cluster", section: "5.2.9.41" } }, - Field({ name: "Unknown", constraint: "0" }), - Field({ name: "PinCodeChanged", constraint: "1" }), - Field({ name: "PinAdded", constraint: "2" }), - Field({ name: "PinCleared", constraint: "3" }), - Field({ name: "PinChanged", constraint: "4" }) + Field({ name: "entry", type: "octstr" }) ), + Attribute({ + name: "AliroGroupResolvingKey", id: 0x84, type: "octstr", access: "R A", conformance: "ALBU", + constraint: "16", default: null, quality: "X", + details: "Indicates the Group Resolving Key as defined in [Aliro]." + + "\n" + + "Null if no group resolving key has been configured on the lock. See SetAliroReaderConfig.", + xref: { document: "cluster", section: "5.2.9.42" } + }), + Attribute( { - name: "RemoteProgrammingEventMask", id: 0x46, type: "EventMaskBitmap", access: "RW VA", - conformance: "[NOT]", default: 65535, quality: "P", - details: "Event mask used to turn on and off remote programming events. This mask DOES NOT apply to the " + - "storing of events in the event log. This mask only applies to the Programming Event Notification " + - "Command." + - "\n" + - "This mask DOES NOT apply to the Events mechanism of this cluster.", - xref: { document: "cluster", section: "5.2.9.46" } + name: "AliroSupportedBleuwbProtocolVersions", id: 0x85, type: "list", access: "R A", + conformance: "ALBU", constraint: "max 16[2]", default: [], quality: "F", + details: "Indicates the list of protocol versions supported for the Bluetooth LE + UWB Access Control Flow as " + + "defined in [Aliro].", + xref: { document: "cluster", section: "5.2.9.43" } }, - Field({ name: "Unknown", constraint: "0" }), - Field({ name: "PinAdded", constraint: "2" }), - Field({ name: "PinCleared", constraint: "3" }), - Field({ name: "PinChanged", constraint: "4" }), - Field({ name: "RfidCodeAdded", constraint: "5" }), - Field({ name: "RfidCodeCleared", constraint: "6" }) + Field({ name: "entry", type: "octstr" }) ), - Attribute( - { - name: "RfidProgrammingEventMask", id: 0x47, type: "EventMaskBitmap", access: "RW VA", - conformance: "[NOT & RID]", default: 65535, quality: "P", + Attribute({ + name: "AliroBleAdvertisingVersion", id: 0x86, type: "uint8", access: "R A", conformance: "ALBU", + default: 0, quality: "F", + details: "Indicates the version of the Bluetooth LE advertisement as defined in [Aliro].", + xref: { document: "cluster", section: "5.2.9.44" } + }), - details: "Event mask used to turn on and off RFID programming events. This mask DOES NOT apply to the storing " + - "of events in the event log. This mask only applies to the Programming Event Notification Command." + - "\n" + - "This mask DOES NOT apply to the Events mechanism of this cluster." + - "\n" + - "This mask DOES NOT apply to the Events mechanism of this cluster.", + Attribute({ + name: "NumberOfAliroCredentialIssuerKeysSupported", id: 0x87, type: "uint16", access: "R V", + conformance: "ALIRO", default: 0, quality: "F", + details: "Indicates the maximum number of AliroCredentialIssuerKey credentials that can be stored on the lock.", + xref: { document: "cluster", section: "5.2.9.45" } + }), - xref: { document: "cluster", section: "5.2.9.47" } - }, + Attribute({ + name: "NumberOfAliroEndpointKeysSupported", id: 0x88, type: "uint16", access: "R V", + conformance: "ALIRO", default: 0, quality: "F", - Field({ name: "Unknown", constraint: "0" }), - Field({ name: "IdAdded", constraint: "5" }), - Field({ name: "IdCleared", constraint: "6" }) - ), + details: "Indicates the maximum number of endpoint key credentials that can be stored on the lock. This limit " + + "applies to the sum of the number of AliroEvictableEndpointKey credentials and the number of " + + "AliroNonEvictableEndpointKey credentials." + + "\n" + + "NOTE" + + "\n" + + "The credential indices used for these two credential types are independent of each other, similar " + + "to all other credential types. As long as NumberOfAliroEndpointKeysSupported is at least 2 a client " + + "could add a credential of type AliroEvictableEndpointKey at any index from 1 to " + + "NumberOfAliroEndpointKeysSupported and also add a credential of type AliroNonEvictableEndpointKey " + + "at the same index, and both credentials would exist on the server.", + + xref: { document: "cluster", section: "5.2.9.46" } + }), Event( { @@ -701,8 +685,9 @@ export const DoorLock = Cluster( " ◦ shall generate a LockOperation event of LockOperationType Unlatch when it is actuated from " + " the outside." + "\n" + - " ◦ may generate a LockOperation event of LockOperationType Unlatch when it is actuated from the " + - " inside.", + " ◦ may generate a LockOperation event of LockOperationType Unlatch when it is actuated" + + "\n" + + "from the inside.", xref: { document: "cluster", section: "5.2.11.3" } }, @@ -837,7 +822,7 @@ export const DoorLock = Cluster( Field({ name: "OperationSource", id: 0x2, type: "OperationSourceEnum", conformance: "M", - constraint: "unspecified, keypad, remote", + constraint: "aliro, unspecified, keypad, remote", details: "This field shall indicate the source of the user data change.", xref: { document: "cluster", section: "5.2.11.5.3" } }), @@ -883,9 +868,7 @@ export const DoorLock = Cluster( response: "status", details: "This command causes the lock device to lock the door. This command includes an optional code for " + "the lock. The door lock may require a PIN depending on the value of the " + - "RequirePINForRemoteOperation attribute." + - "\n" + - "† The PIN/RFID Code is an obsolete field name, use PINCode instead.", + "RequirePINForRemoteOperation attribute.", xref: { document: "cluster", section: "5.2.10.1" } }, @@ -918,9 +901,7 @@ export const DoorLock = Cluster( "NOTE" + "\n" + "If the attribute AutoRelockTime is supported the lock will transition to the locked state when the " + - "auto relock time has expired." + - "\n" + - "† The PIN/RFID Code is an obsolete field name, use PINCode instead.", + "auto relock time has expired.", xref: { document: "cluster", section: "5.2.10.2" } }, @@ -941,17 +922,11 @@ export const DoorLock = Cluster( { name: "UnlockWithTimeout", id: 0x3, access: "O T", conformance: "O", direction: "request", response: "status", - details: "This command causes the lock device to unlock the door with a timeout parameter. After the time in " + "seconds specified in the timeout field, the lock device will relock itself automatically. This " + "timeout parameter is only temporary for this message transition and overrides the default relock " + - "time" + - "\n" + - "as specified in the AutoRelockTime attribute. If the door lock device is not capable of or does not " + - "want to support temporary Relock Timeout, it SHOULD NOT support this optional command." + - "\n" + - "† The PIN/RFID Code is an obsolete field name, use PINCode instead.", - + "time as specified in the AutoRelockTime attribute. If the door lock device is not capable of or " + + "does not want to support temporary Relock Timeout, it SHOULD NOT support this optional command.", xref: { document: "cluster", section: "5.2.10.3" } }, @@ -969,81 +944,6 @@ export const DoorLock = Cluster( }) ), - Command( - { - name: "GetLogRecord", id: 0x4, access: "M", conformance: "LOG", direction: "request", - response: "GetLogRecordResponse", - details: "Request a log record. Log number is between 1 – [Number of Log Records Supported attribute]. If log " + - "number 0 is requested then the most recent log entry is returned." + - "\n" + - "Log record format: The log record format is defined in the description of the GetLogRecordResponse " + - "command.", - xref: { document: "cluster", section: "5.2.10.4" } - }, - - Field({ name: "LogIndex", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }) - ), - - Command( - { - name: "GetLogRecordResponse", id: 0x4, conformance: "LOG", direction: "response", - details: "Returns the specified log record. If an invalid log entry ID was requested, it is set to 0 and the " + - "most recent log entry will be returned.", - xref: { document: "cluster", section: "5.2.10.5" } - }, - - Field({ - name: "LogEntryId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", - details: "This field shall indicate the index into the log table where this log entry is stored. If the log " + - "entry requested is 0, the most recent log is returned with the appropriate log entry ID.", - xref: { document: "cluster", section: "5.2.10.5.1" } - }), - - Field({ - name: "Timestamp", id: 0x1, type: "epoch-s", conformance: "M", - details: "This field shall indicate the timestamp for all events and alarms on the door lock in Epoch Time in " + - "Seconds with local time offset based on the local timezone and DST offset on the day of the event.", - xref: { document: "cluster", section: "5.2.10.5.2" } - }), - - Field({ - name: "EventType", id: 0x2, type: "EventTypeEnum", conformance: "M", - details: "This field shall indicate the type of event that took place on the door lock, as defined in " + - "EventTypeEnum.", - xref: { document: "cluster", section: "5.2.10.5.3" } - }), - - Field({ - name: "Source", id: 0x3, type: "EventSourceEnum", conformance: "M", - details: "This field shall indicate the source value as defined in EventSourceEnum." + - "\n" + - "If the EventType is 2 (Alarm) then the source SHOULD be, but does not have to be 255 " + - "(Indeterminate).", - xref: { document: "cluster", section: "5.2.10.5.4" } - }), - - Field({ - name: "EventId", id: 0x4, type: "uint8", conformance: "M", constraint: "desc", - details: "This field shall indicate the type of event that took place on the door lock depending on the event " + - "code table provided for a given event type and source. See Operation Event Codes.", - xref: { document: "cluster", section: "5.2.10.5.5" } - }), - - Field({ - name: "UserId", id: 0x5, type: "uint16", conformance: "M", constraint: "desc", - details: "This field shall indicate the ID of the user who generated the event on the door lock if one is " + - "available. Otherwise, the value is 0xFFFF.", - xref: { document: "cluster", section: "5.2.10.5.6" } - }), - - Field({ - name: "Pin", id: 0x6, type: "octstr", conformance: "M", - details: "This field shall indicate the PIN code or RFID code that was used to create the event on the door " + - "lock if one is available.", - xref: { document: "cluster", section: "5.2.10.5.7" } - }) - ), - Command( { name: "SetPinCode", id: 0x5, access: "A T", conformance: "!USR & PIN", direction: "request", @@ -1052,14 +952,14 @@ export const DoorLock = Cluster( "\n" + "Return status is a global status code or a cluster-specific status code from the Status Codes table " + "and shall be one of the following values:", - xref: { document: "cluster", section: "5.2.10.6" } + xref: { document: "cluster", section: "5.2.10.4" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", details: "This field shall indicate the user ID. The value of the UserID field shall be between 0 and the " + "value of the NumberOfPINUsersSupported attribute.", - xref: { document: "cluster", section: "5.2.10.6.1" } + xref: { document: "cluster", section: "5.2.10.4.1" } }), Field({ @@ -1067,7 +967,7 @@ export const DoorLock = Cluster( default: 1, quality: "X", details: "This field shall indicate the user status. Only the values 1 (Occupied/Enabled) and 3 " + "(Occupied/Disabled) are allowed for UserStatus.", - xref: { document: "cluster", section: "5.2.10.6.2" } + xref: { document: "cluster", section: "5.2.10.4.2" } }), Field({ name: "UserType", id: 0x2, type: "UserTypeEnum", conformance: "M", default: 0, quality: "X" }), @@ -1079,14 +979,14 @@ export const DoorLock = Cluster( name: "GetPinCode", id: 0x6, access: "A", conformance: "!USR & PIN", direction: "request", response: "GetPinCodeResponse", details: "Retrieve a PIN Code.", - xref: { document: "cluster", section: "5.2.10.7" } + xref: { document: "cluster", section: "5.2.10.5" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", details: "This field shall indicate the user ID. The value of the UserID field shall be between 0 and the " + "value of the NumberOfPINUsersSupported attribute.", - xref: { document: "cluster", section: "5.2.10.7.1" } + xref: { document: "cluster", section: "5.2.10.5.1" } }) ), @@ -1106,7 +1006,7 @@ export const DoorLock = Cluster( "shall be equal to CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and " + "NOT_FOUND if greater than or equal to the max number of users supported.", - xref: { document: "cluster", section: "5.2.10.8" } + xref: { document: "cluster", section: "5.2.10.6" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }), @@ -1122,16 +1022,12 @@ export const DoorLock = Cluster( { name: "ClearPinCode", id: 0x7, access: "A T", conformance: "!USR & PIN", direction: "request", response: "status", - details: "Clear a PIN code or all PIN codes." + - "\n" + - "† The User ID is an obsolete field name, use PINSlotIndex instead." + "\n" + "For each PIN Code cleared whose user doesn’t have a RFID Code or other credential type, then " + "corresponding user record’s UserStatus value shall be set to Available, and UserType value shall be " + "set to UnrestrictedUser and all schedules shall be cleared.", - - xref: { document: "cluster", section: "5.2.10.9" } + xref: { document: "cluster", section: "5.2.10.7" } }, Field({ @@ -1139,7 +1035,7 @@ export const DoorLock = Cluster( constraint: "1 to numberOfPinUsersSupported, 65534", details: "This field shall specify a valid PIN code slot index or 0xFFFE to indicate all PIN code slots shall " + "be cleared.", - xref: { document: "cluster", section: "5.2.10.9.1" } + xref: { document: "cluster", section: "5.2.10.7.1" } }) ), @@ -1154,7 +1050,7 @@ export const DoorLock = Cluster( "On the server, the clear all PIN codes command SHOULD have the same effect as the ClearPINCode " + "command with respect to the setting of user status, user type and schedules.", - xref: { document: "cluster", section: "5.2.10.10" } + xref: { document: "cluster", section: "5.2.10.8" } }), Command( @@ -1162,21 +1058,21 @@ export const DoorLock = Cluster( name: "SetUserStatus", id: 0x9, access: "A", conformance: "!USR & (PIN | RID | FGP)", direction: "request", response: "status", details: "Set the status of a user ID.", - xref: { document: "cluster", section: "5.2.10.11" } + xref: { document: "cluster", section: "5.2.10.9" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", details: "This field shall indicate the user ID. The value of the UserID field shall be between 0 and the " + "value of the NumberOfPINUsersSupported attribute.", - xref: { document: "cluster", section: "5.2.10.11.1" } + xref: { document: "cluster", section: "5.2.10.9.1" } }), Field({ name: "UserStatus", id: 0x1, type: "UserStatusEnum", conformance: "M", constraint: "desc", details: "UserStatus value of Available is not allowed. In order to clear a user id, the ClearUser Command " + "shall be used. For user status value please refer to UserStatusEnum.", - xref: { document: "cluster", section: "5.2.10.11.2" } + xref: { document: "cluster", section: "5.2.10.9.2" } }) ), @@ -1185,14 +1081,14 @@ export const DoorLock = Cluster( name: "GetUserStatus", id: 0xa, access: "A", conformance: "!USR & (PIN | RID | FGP)", direction: "request", response: "GetUserStatusResponse", details: "Get the status of a user.", - xref: { document: "cluster", section: "5.2.10.12" } + xref: { document: "cluster", section: "5.2.10.10" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", details: "This field shall indicate the user ID. The value of the UserID field shall be between 0 and the " + "value of the NumberOfPINUsersSupported attribute.", - xref: { document: "cluster", section: "5.2.10.12.1" } + xref: { document: "cluster", section: "5.2.10.10.1" } }) ), @@ -1200,17 +1096,17 @@ export const DoorLock = Cluster( { name: "GetUserStatusResponse", id: 0xa, conformance: "!USR", direction: "response", details: "Returns the user status for the specified user ID.", - xref: { document: "cluster", section: "5.2.10.13" } + xref: { document: "cluster", section: "5.2.10.11" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", details: "This field shall indicate the user ID provided in the request.", - xref: { document: "cluster", section: "5.2.10.13.1" } + xref: { document: "cluster", section: "5.2.10.11.1" } }), Field({ name: "UserStatus", id: 0x1, type: "UserStatusEnum", conformance: "M", details: "This field shall indicate the current status of the requested user ID.", - xref: { document: "cluster", section: "5.2.10.13.2" } + xref: { document: "cluster", section: "5.2.10.11.2" } }) ), @@ -1220,60 +1116,60 @@ export const DoorLock = Cluster( response: "status", details: "Set a weekly repeating schedule for a specified user." + - "\n" + - "† The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, " + - "respectively." + "\n" + "The associated UserType may be changed to ScheduleRestrictedUser by the lock when a Week Day " + "schedule is set." + "\n" + "Return status shall be one of the following values:", - xref: { document: "cluster", section: "5.2.10.14" } + xref: { document: "cluster", section: "5.2.10.12" } }, Field({ name: "WeekDayIndex", id: 0x0, type: "uint8", conformance: "M", constraint: "1 to numberOfWeekDaySchedulesSupportedPerUser", details: "This field shall indicate the index of the Week Day schedule.", - xref: { document: "cluster", section: "5.2.10.14.1" } + xref: { document: "cluster", section: "5.2.10.12.1" } }), Field({ - name: "UserIndexUserId", id: 0x1, type: "uint16", conformance: "M", - constraint: "1 to numberOfTotalUsersSupported" + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.12.2" } }), + Field({ name: "DaysMask", id: 0x2, type: "DaysMaskBitmap", conformance: "M", details: "This field shall indicate which week days the schedule is active.", - xref: { document: "cluster", section: "5.2.10.14.3" } + xref: { document: "cluster", section: "5.2.10.12.3" } }), Field({ - name: "StartHour", id: 0x3, type: "uint8", conformance: "M", constraint: "0 to 23", + name: "StartHour", id: 0x3, type: "uint8", conformance: "M", constraint: "max 23", details: "This field shall indicate the starting hour for the Week Day schedule.", - xref: { document: "cluster", section: "5.2.10.14.4" } + xref: { document: "cluster", section: "5.2.10.12.4" } }), Field({ - name: "StartMinute", id: 0x4, type: "uint8", conformance: "M", constraint: "0 to 59", + name: "StartMinute", id: 0x4, type: "uint8", conformance: "M", constraint: "max 59", details: "This field shall indicate the starting minute for the Week Day schedule.", - xref: { document: "cluster", section: "5.2.10.14.5" } + xref: { document: "cluster", section: "5.2.10.12.5" } }), Field({ - name: "EndHour", id: 0x5, type: "uint8", conformance: "M", constraint: "0 to 23", + name: "EndHour", id: 0x5, type: "uint8", conformance: "M", constraint: "max 23", details: "This field shall indicate the ending hour for the Week Day schedule. EndHour shall be equal to or " + "greater than StartHour.", - xref: { document: "cluster", section: "5.2.10.14.6" } + xref: { document: "cluster", section: "5.2.10.12.6" } }), Field({ - name: "EndMinute", id: 0x6, type: "uint8", conformance: "M", constraint: "0 to 59", + name: "EndMinute", id: 0x6, type: "uint8", conformance: "M", constraint: "max 59", details: "This field shall indicate the ending minute for the Week Day schedule. If EndHour is equal to " + "StartHour then EndMinute shall be greater than StartMinute." + "\n" + "If the EndHour is equal to 23 and the EndMinute is equal to 59 the Lock shall grant access to the " + "user up until 23:59:59.", - xref: { document: "cluster", section: "5.2.10.14.7" } + xref: { document: "cluster", section: "5.2.10.12.7" } }) ), @@ -1281,11 +1177,8 @@ export const DoorLock = Cluster( { name: "GetWeekDaySchedule", id: 0xc, access: "A", conformance: "WDSCH", direction: "request", response: "GetWeekDayScheduleResponse", - details: "Retrieve the specific weekly schedule for the specific user." + - "\n" + - "† The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, " + - "respectively.", - xref: { document: "cluster", section: "5.2.10.15" } + details: "Retrieve the specific weekly schedule for the specific user.", + xref: { document: "cluster", section: "5.2.10.13" } }, Field({ @@ -1293,7 +1186,7 @@ export const DoorLock = Cluster( constraint: "1 to numberOfWeekDaySchedulesSupportedPerUser" }), Field({ - name: "UserIndexUserId", id: 0x1, type: "uint16", conformance: "M", + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", constraint: "1 to numberOfTotalUsersSupported" }) ), @@ -1301,23 +1194,22 @@ export const DoorLock = Cluster( Command( { name: "GetWeekDayScheduleResponse", id: 0xc, conformance: "WDSCH", direction: "response", - details: "Returns the weekly repeating schedule data for the specified schedule index." + - "\n" + - "† The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, " + - "respectively.", - xref: { document: "cluster", section: "5.2.10.16" } + details: "Returns the weekly repeating schedule data for the specified schedule index.", + xref: { document: "cluster", section: "5.2.10.14" } }, Field({ name: "WeekDayIndex", id: 0x0, type: "uint8", conformance: "M", constraint: "1 to numberOfWeekDaySchedulesSupportedPerUser", details: "This field shall indicate the index of the Week Day schedule.", - xref: { document: "cluster", section: "5.2.10.16.1" } + xref: { document: "cluster", section: "5.2.10.14.1" } }), Field({ - name: "UserIndexUserId", id: 0x1, type: "uint16", conformance: "M", - constraint: "1 to numberOfTotalUsersSupported" + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.14.2" } }), Field({ @@ -1337,33 +1229,33 @@ export const DoorLock = Cluster( "If this field is SUCCESS, the optional fields for this command shall be present. For other (error) " + "status values, only the fields up to the status field shall be present.", - xref: { document: "cluster", section: "5.2.10.16.3" } + xref: { document: "cluster", section: "5.2.10.14.3" } }), Field({ name: "DaysMask", id: 0x3, type: "DaysMaskBitmap", conformance: "O" }), Field({ - name: "StartHour", id: 0x4, type: "uint8", conformance: "O", constraint: "0 to 23", + name: "StartHour", id: 0x4, type: "uint8", conformance: "O", constraint: "max 23", details: "This field shall indicate the starting hour for the Week Day schedule.", - xref: { document: "cluster", section: "5.2.10.16.4" } + xref: { document: "cluster", section: "5.2.10.14.4" } }), Field({ - name: "StartMinute", id: 0x5, type: "uint8", conformance: "O", constraint: "0 to 59", + name: "StartMinute", id: 0x5, type: "uint8", conformance: "O", constraint: "max 59", details: "This field shall indicate the starting minute for the Week Day schedule.", - xref: { document: "cluster", section: "5.2.10.16.5" } + xref: { document: "cluster", section: "5.2.10.14.5" } }), Field({ - name: "EndHour", id: 0x6, type: "uint8", conformance: "O", constraint: "0 to 23", + name: "EndHour", id: 0x6, type: "uint8", conformance: "O", constraint: "max 23", details: "This field shall indicate the ending hour for the Week Day schedule. EndHour shall be equal to or " + "greater than StartHour.", - xref: { document: "cluster", section: "5.2.10.16.6" } + xref: { document: "cluster", section: "5.2.10.14.6" } }), Field({ - name: "EndMinute", id: 0x7, type: "uint8", conformance: "O", constraint: "0 to 59", + name: "EndMinute", id: 0x7, type: "uint8", conformance: "O", constraint: "max 59", details: "This field shall indicate the ending minute for the Week Day schedule. If EndHour is equal to " + "StartHour then EndMinute shall be greater than StartMinute.", - xref: { document: "cluster", section: "5.2.10.16.7" } + xref: { document: "cluster", section: "5.2.10.14.7" } }) ), @@ -1371,15 +1263,10 @@ export const DoorLock = Cluster( { name: "ClearWeekDaySchedule", id: 0xd, access: "A", conformance: "WDSCH", direction: "request", response: "status", - details: "Clear the specific weekly schedule or all weekly schedules for the specific user." + - "\n" + - "† The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, " + - "respectively." + "\n" + "Return status shall be one of the following values:", - - xref: { document: "cluster", section: "5.2.10.17" } + xref: { document: "cluster", section: "5.2.10.15" } }, Field({ @@ -1387,12 +1274,14 @@ export const DoorLock = Cluster( constraint: "1 to numberOfWeekDaySchedulesSupportedPerUser, 254", details: "This field shall indicate the Week Day schedule index to clear or 0xFE to clear all Week Day " + "schedules for the specified user.", - xref: { document: "cluster", section: "5.2.10.17.1" } + xref: { document: "cluster", section: "5.2.10.15.1" } }), Field({ - name: "UserIndexUserId", id: 0x1, type: "uint16", conformance: "M", - constraint: "1 to numberOfTotalUsersSupported" + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.15.2" } }) ), @@ -1402,35 +1291,34 @@ export const DoorLock = Cluster( response: "status", details: "Set a time-specific schedule ID for a specified user." + - "\n" + - "† The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, " + - "respectively." + "\n" + "The associated UserType may be changed to ScheduleRestrictedUser by the lock when a Year Day " + "schedule is set." + "\n" + "Return status shall be one of the following values:", - xref: { document: "cluster", section: "5.2.10.18" } + xref: { document: "cluster", section: "5.2.10.16" } }, Field({ name: "YearDayIndex", id: 0x0, type: "uint8", conformance: "M", constraint: "1 to numberOfYearDaySchedulesSupportedPerUser", details: "This field shall indicate the index of the Year Day schedule.", - xref: { document: "cluster", section: "5.2.10.18.1" } + xref: { document: "cluster", section: "5.2.10.16.1" } }), Field({ - name: "UserIndexUserId", id: 0x1, type: "uint16", conformance: "M", - constraint: "1 to numberOfTotalUsersSupported" + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.16.2" } }), Field({ name: "LocalStartTime", id: 0x2, type: "epoch-s", conformance: "M", details: "This field shall indicate the starting time for the Year Day schedule in Epoch Time in Seconds with " + "local time offset based on the local timezone and DST offset on the day represented by the value.", - xref: { document: "cluster", section: "5.2.10.18.3" } + xref: { document: "cluster", section: "5.2.10.16.3" } }), Field({ @@ -1438,7 +1326,7 @@ export const DoorLock = Cluster( details: "This field shall indicate the ending time for the Year Day schedule in Epoch Time in Seconds with " + "local time offset based on the local timezone and DST offset on the day represented by the value. " + "LocalEndTime shall be greater than LocalStartTime.", - xref: { document: "cluster", section: "5.2.10.18.4" } + xref: { document: "cluster", section: "5.2.10.16.4" } }) ), @@ -1446,11 +1334,8 @@ export const DoorLock = Cluster( { name: "GetYearDaySchedule", id: 0xf, access: "A", conformance: "YDSCH", direction: "request", response: "GetYearDayScheduleResponse", - details: "Retrieve the specific year day schedule for the specific schedule and user indexes." + - "\n" + - "† The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, " + - "respectively.", - xref: { document: "cluster", section: "5.2.10.19" } + details: "Retrieve the specific year day schedule for the specific schedule and user indexes.", + xref: { document: "cluster", section: "5.2.10.17" } }, Field({ @@ -1458,7 +1343,7 @@ export const DoorLock = Cluster( constraint: "1 to numberOfYearDaySchedulesSupportedPerUser" }), Field({ - name: "UserIndexUserId", id: 0x1, type: "uint16", conformance: "M", + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", constraint: "1 to numberOfTotalUsersSupported" }) ), @@ -1466,23 +1351,22 @@ export const DoorLock = Cluster( Command( { name: "GetYearDayScheduleResponse", id: 0xf, conformance: "YDSCH", direction: "response", - details: "Returns the year day schedule data for the specified schedule and user indexes." + - "\n" + - "† The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, " + - "respectively.", - xref: { document: "cluster", section: "5.2.10.20" } + details: "Returns the year day schedule data for the specified schedule and user indexes.", + xref: { document: "cluster", section: "5.2.10.18" } }, Field({ name: "YearDayIndex", id: 0x0, type: "uint8", conformance: "M", constraint: "1 to numberOfYearDaySchedulesSupportedPerUser", details: "This field shall indicate the index of the Year Day schedule.", - xref: { document: "cluster", section: "5.2.10.20.1" } + xref: { document: "cluster", section: "5.2.10.18.1" } }), Field({ - name: "UserIndexUserId", id: 0x1, type: "uint16", conformance: "M", - constraint: "1 to numberOfTotalUsersSupported" + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.18.2" } }), Field({ @@ -1502,7 +1386,7 @@ export const DoorLock = Cluster( "If this field is SUCCESS, the optional fields for this command shall be present. For other (error) " + "status values, only the fields up to the status field shall be present.", - xref: { document: "cluster", section: "5.2.10.20.3" } + xref: { document: "cluster", section: "5.2.10.18.3" } }), Field({ @@ -1510,7 +1394,7 @@ export const DoorLock = Cluster( details: "This field shall indicate the starting time for the Year Day schedule in Epoch Time in Seconds with " + "local time offset based on the local timezone and DST offset on the day represented by the value. " + "This shall be null if the schedule is not set for the YearDayIndex and UserIndex provided.", - xref: { document: "cluster", section: "5.2.10.20.4" } + xref: { document: "cluster", section: "5.2.10.18.4" } }), Field({ @@ -1519,7 +1403,7 @@ export const DoorLock = Cluster( "local time offset based on the local timezone and DST offset on the day represented by the value. " + "LocalEndTime shall be greater than LocalStartTime. This shall be null if the schedule is not set " + "for the YearDayIndex and UserIndex provided.", - xref: { document: "cluster", section: "5.2.10.20.5" } + xref: { document: "cluster", section: "5.2.10.18.5" } }) ), @@ -1527,15 +1411,10 @@ export const DoorLock = Cluster( { name: "ClearYearDaySchedule", id: 0x10, access: "A", conformance: "YDSCH", direction: "request", response: "status", - details: "Clears the specific year day schedule or all year day schedules for the specific user." + - "\n" + - "† The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, " + - "respectively." + "\n" + "Return status shall be one of the following values:", - - xref: { document: "cluster", section: "5.2.10.21" } + xref: { document: "cluster", section: "5.2.10.19" } }, Field({ @@ -1543,12 +1422,14 @@ export const DoorLock = Cluster( constraint: "1 to numberOfYearDaySchedulesSupportedPerUser, 254", details: "This field shall indicate the Year Day schedule index to clear or 0xFE to clear all Year Day " + "schedules for the specified user.", - xref: { document: "cluster", section: "5.2.10.21.1" } + xref: { document: "cluster", section: "5.2.10.19.1" } }), Field({ - name: "UserIndexUserId", id: 0x1, type: "uint16", conformance: "M", - constraint: "1 to numberOfTotalUsersSupported" + name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", + constraint: "1 to numberOfTotalUsersSupported", + details: "This field shall indicate the user ID.", + xref: { document: "cluster", section: "5.2.10.19.2" } }) ), @@ -1559,16 +1440,15 @@ export const DoorLock = Cluster( details: "Set the holiday Schedule by specifying local start time and local end time with respect to any Lock " + "Operating Mode." + "\n" + - "† The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. Return status shall " + - "be one of the following values:", - xref: { document: "cluster", section: "5.2.10.22" } + "Return status shall be one of the following values:", + xref: { document: "cluster", section: "5.2.10.20" } }, Field({ name: "HolidayIndex", id: 0x0, type: "uint8", conformance: "M", constraint: "1 to numberOfHolidaySchedulesSupported", details: "This field shall indicate the index of the Holiday schedule.", - xref: { document: "cluster", section: "5.2.10.22.1" } + xref: { document: "cluster", section: "5.2.10.20.1" } }), Field({ @@ -1576,7 +1456,7 @@ export const DoorLock = Cluster( details: "This field shall indicate the starting time for the Holiday Day schedule in Epoch Time in Seconds " + "with local time offset based on the local timezone and DST offset on the day represented by the " + "value.", - xref: { document: "cluster", section: "5.2.10.22.2" } + xref: { document: "cluster", section: "5.2.10.20.2" } }), Field({ @@ -1584,13 +1464,13 @@ export const DoorLock = Cluster( details: "This field shall indicate the ending time for the Holiday Day schedule in Epoch Time in Seconds " + "with local time offset based on the local timezone and DST offset on the day represented by the " + "value. LocalEndTime shall be greater than LocalStartTime.", - xref: { document: "cluster", section: "5.2.10.22.3" } + xref: { document: "cluster", section: "5.2.10.20.3" } }), Field({ name: "OperatingMode", id: 0x3, type: "OperatingModeEnum", conformance: "M", details: "This field shall indicate the operating mode to use during this Holiday schedule start/end time.", - xref: { document: "cluster", section: "5.2.10.22.4" } + xref: { document: "cluster", section: "5.2.10.20.4" } }) ), @@ -1598,10 +1478,8 @@ export const DoorLock = Cluster( { name: "GetHolidaySchedule", id: 0x12, access: "A", conformance: "HDSCH", direction: "request", response: "GetHolidayScheduleResponse", - details: "Get the holiday schedule for the specified index." + - "\n" + - "† The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead.", - xref: { document: "cluster", section: "5.2.10.23" } + details: "Get the holiday schedule for the specified index.", + xref: { document: "cluster", section: "5.2.10.21" } }, Field({ @@ -1613,17 +1491,15 @@ export const DoorLock = Cluster( Command( { name: "GetHolidayScheduleResponse", id: 0x12, conformance: "HDSCH", direction: "response", - details: "Returns the Holiday Schedule Entry for the specified Holiday ID." + - "\n" + - "† The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead.", - xref: { document: "cluster", section: "5.2.10.24" } + details: "Returns the Holiday Schedule Entry for the specified Holiday ID.", + xref: { document: "cluster", section: "5.2.10.22" } }, Field({ name: "HolidayIndex", id: 0x0, type: "uint8", conformance: "M", constraint: "1 to numberOfHolidaySchedulesSupported", details: "This field shall indicate the index of the Holiday schedule.", - xref: { document: "cluster", section: "5.2.10.24.1" } + xref: { document: "cluster", section: "5.2.10.22.1" } }), Field({ @@ -1643,7 +1519,7 @@ export const DoorLock = Cluster( "If this field is SUCCESS, the optional fields for this command shall be present. For other (error) " + "status values, only the fields up to the status field shall be present.", - xref: { document: "cluster", section: "5.2.10.24.2" } + xref: { document: "cluster", section: "5.2.10.22.2" } }), Field({ @@ -1651,7 +1527,7 @@ export const DoorLock = Cluster( details: "This field shall indicate the starting time for the Holiday schedule in Epoch Time in Seconds with " + "local time offset based on the local timezone and DST offset on the day represented by the value. " + "This shall be null if the schedule is not set for the HolidayIndex provided.", - xref: { document: "cluster", section: "5.2.10.24.3" } + xref: { document: "cluster", section: "5.2.10.22.3" } }), Field({ @@ -1660,14 +1536,14 @@ export const DoorLock = Cluster( "local time offset based on the local timezone and DST offset on the day represented by the value. " + "LocalEndTime shall be greater than LocalStartTime. This shall be null if the schedule is not set " + "for the HolidayIndex provided.", - xref: { document: "cluster", section: "5.2.10.24.4" } + xref: { document: "cluster", section: "5.2.10.22.4" } }), Field({ name: "OperatingMode", id: 0x4, type: "OperatingModeEnum", conformance: "O", quality: "X", details: "This field shall indicate the operating mode to use during this Holiday schedule start/end time. " + "This shall be null if the schedule is not set for the HolidayIndex provided.", - xref: { document: "cluster", section: "5.2.10.24.5" } + xref: { document: "cluster", section: "5.2.10.22.5" } }) ), @@ -1675,10 +1551,8 @@ export const DoorLock = Cluster( { name: "ClearHolidaySchedule", id: 0x13, access: "A", conformance: "HDSCH", direction: "request", response: "status", - details: "Clears the holiday schedule or all holiday schedules." + - "\n" + - "† The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead.", - xref: { document: "cluster", section: "5.2.10.25" } + details: "Clears the holiday schedule or all holiday schedules.", + xref: { document: "cluster", section: "5.2.10.23" } }, Field({ @@ -1686,7 +1560,7 @@ export const DoorLock = Cluster( constraint: "1 to numberOfHolidaySchedulesSupported, 254", details: "This field shall indicate the Holiday schedule index to clear or 0xFE to clear all Holiday " + "schedules.", - xref: { document: "cluster", section: "5.2.10.25.1" } + xref: { document: "cluster", section: "5.2.10.23.1" } }) ), @@ -1699,27 +1573,18 @@ export const DoorLock = Cluster( "For user type value please refer to User Type Value." + "\n" + "Return status shall be one of the following values:", - xref: { document: "cluster", section: "5.2.10.26" } + xref: { document: "cluster", section: "5.2.10.24" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc", details: "This field shall indicate the user ID.", - xref: { document: "cluster", section: "5.2.10.26.1" } + xref: { document: "cluster", section: "5.2.10.24.1" } }), - Field({ name: "UserType", id: 0x1, type: "UserTypeEnum", conformance: "M", - - details: "This field shall indicate the user type." + - "\n" + - "If UserType is currently YearDayScheduleUser, WeekDayScheduleUser, or ScheduleRestrictedUser and " + - "the new UserType is UnrestrictedUser then all existing Year Day and/or Week Day schedules shall be " + - "ignored or disabled (if this transition is supported by the door lock). If UserType is " + - "ScheduleRestrictedUser and the new UserType is ScheduleRestrictedUser then all existing Year Day " + - "and/or Week Day schedules shall be applied or enabled.", - - xref: { document: "cluster", section: "5.2.10.26.2" } + details: "This field shall indicate the user type.", + xref: { document: "cluster", section: "5.2.10.24.2" } }) ), @@ -1728,7 +1593,7 @@ export const DoorLock = Cluster( name: "GetUserType", id: 0x15, access: "A", conformance: "!USR & (PIN | RID | FGP)", direction: "request", response: "GetUserTypeResponse", details: "Retrieve the user type for a specific user.", - xref: { document: "cluster", section: "5.2.10.27" } + xref: { document: "cluster", section: "5.2.10.25" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }) @@ -1739,7 +1604,7 @@ export const DoorLock = Cluster( name: "GetUserTypeResponse", id: 0x15, conformance: "!USR", direction: "response", details: "Returns the user type for the specified user ID. If the requested User ID is invalid, send Default " + "Response with an error status equal to FAILURE.", - xref: { document: "cluster", section: "5.2.10.28" } + xref: { document: "cluster", section: "5.2.10.26" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }), @@ -1754,7 +1619,7 @@ export const DoorLock = Cluster( "\n" + "Return status is a global status code or a cluster-specific status code from the Status Codes table " + "and shall be one of the following values:", - xref: { document: "cluster", section: "5.2.10.29" } + xref: { document: "cluster", section: "5.2.10.27" } }, Field({ @@ -1763,7 +1628,7 @@ export const DoorLock = Cluster( "\n" + "The value of the UserID field shall be between 0 and the value of the NumberOfRFIDUsersSupported " + "attribute.", - xref: { document: "cluster", section: "5.2.10.29.1" } + xref: { document: "cluster", section: "5.2.10.27.1" } }), Field({ @@ -1773,14 +1638,14 @@ export const DoorLock = Cluster( "“Set PIN” while not all are supported." + "\n" + "Only the values 1 (Occupied/Enabled) and 3 (Occupied/Disabled) are allowed for UserStatus.", - xref: { document: "cluster", section: "5.2.10.29.2" } + xref: { document: "cluster", section: "5.2.10.27.2" } }), Field({ name: "UserType", id: 0x2, type: "UserTypeEnum", conformance: "M", constraint: "desc", default: 0, quality: "X", details: "The values are the same as used for SetPINCode command.", - xref: { document: "cluster", section: "5.2.10.29.3" } + xref: { document: "cluster", section: "5.2.10.27.3" } }), Field({ name: "RfidCode", id: 0x3, type: "octstr", conformance: "M" }) @@ -1791,7 +1656,7 @@ export const DoorLock = Cluster( name: "GetRfidCode", id: 0x17, access: "A", conformance: "!USR & RID", direction: "request", response: "GetRfidCodeResponse", details: "Retrieve an RFID code.", - xref: { document: "cluster", section: "5.2.10.30" } + xref: { document: "cluster", section: "5.2.10.28" } }, Field({ @@ -1800,7 +1665,7 @@ export const DoorLock = Cluster( "\n" + "The value of the UserID field shall be between 0 and the value of the NumberOfRFIDUsersSupported " + "attribute.", - xref: { document: "cluster", section: "5.2.10.30.1" } + xref: { document: "cluster", section: "5.2.10.28.1" } }) ), @@ -1820,7 +1685,7 @@ export const DoorLock = Cluster( "be equal to CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and " + "NOT_FOUND if greater than or equal to the max number of users supported.", - xref: { document: "cluster", section: "5.2.10.31" } + xref: { document: "cluster", section: "5.2.10.29" } }, Field({ name: "UserId", id: 0x0, type: "uint16", conformance: "M", constraint: "desc" }), @@ -1836,16 +1701,12 @@ export const DoorLock = Cluster( { name: "ClearRfidCode", id: 0x18, access: "A T", conformance: "!USR & RID", direction: "request", response: "status", - details: "Clear an RFID code or all RFID codes." + - "\n" + - "† The User ID is an obsolete field name, use RFIDSlotIndex instead." + "\n" + "For each RFID Code cleared whose user doesn’t have a PIN Code or other credential type, then the " + "corresponding user record’s UserStatus value shall be set to Available, and UserType value shall be " + "set to UnrestrictedUser and all schedules shall be cleared.", - - xref: { document: "cluster", section: "5.2.10.32" } + xref: { document: "cluster", section: "5.2.10.30" } }, Field({ @@ -1853,7 +1714,7 @@ export const DoorLock = Cluster( constraint: "1 to numberOfRfidUsersSupported, 65534", details: "This field shall indicate a valid RFID code slot index or 0xFFFE to indicate all RFID code slots " + "shall be cleared.", - xref: { document: "cluster", section: "5.2.10.32.1" } + xref: { document: "cluster", section: "5.2.10.30.1" } }) ), @@ -1863,7 +1724,7 @@ export const DoorLock = Cluster( details: "Clear out all RFIDs on the lock. If you clear all RFID codes and this user didn’t have a PIN code, " + "the user status has to be set to \"0 Available\", the user type has to be set to the default value, " + "and all schedules which are supported have to be set to the default values.", - xref: { document: "cluster", section: "5.2.10.33" } + xref: { document: "cluster", section: "5.2.10.31" } }), Command( @@ -1889,21 +1750,21 @@ export const DoorLock = Cluster( " • INVALID_COMMAND, if one or more fields violate constraints or are invalid or if OperationType " + " is Modify and UserIndex points to an available slot.", - xref: { document: "cluster", section: "5.2.10.34" } + xref: { document: "cluster", section: "5.2.10.32" } }, Field({ name: "OperationType", id: 0x0, type: "DataOperationTypeEnum", conformance: "M", constraint: "add, modify", details: "This field shall indicate the type of operation.", - xref: { document: "cluster", section: "5.2.10.34.1" } + xref: { document: "cluster", section: "5.2.10.32.1" } }), Field({ name: "UserIndex", id: 0x1, type: "uint16", conformance: "M", constraint: "1 to numberOfTotalUsersSupported", details: "This field shall indicate the user ID.", - xref: { document: "cluster", section: "5.2.10.34.2" } + xref: { document: "cluster", section: "5.2.10.32.2" } }), Field({ @@ -1920,7 +1781,7 @@ export const DoorLock = Cluster( "\n" + "If UserName is not null, the UserName in the user record shall be set to the provided value.", - xref: { document: "cluster", section: "5.2.10.34.3" } + xref: { document: "cluster", section: "5.2.10.32.3" } }), Field({ @@ -1939,7 +1800,7 @@ export const DoorLock = Cluster( "\n" + "If UserUniqueID is not null, the UserUniqueID in the user record shall be set to the provided value.", - xref: { document: "cluster", section: "5.2.10.34.4" } + xref: { document: "cluster", section: "5.2.10.32.4" } }), Field({ @@ -1957,7 +1818,7 @@ export const DoorLock = Cluster( "\n" + "If UserStatus is not null, the UserStatus in the user record shall be set to the provided value.", - xref: { document: "cluster", section: "5.2.10.34.5" } + xref: { document: "cluster", section: "5.2.10.32.5" } }), Field({ @@ -1976,7 +1837,7 @@ export const DoorLock = Cluster( "\n" + "If UserType is not null, the UserType in the user record shall be set to the provided value.", - xref: { document: "cluster", section: "5.2.10.34.6" } + xref: { document: "cluster", section: "5.2.10.32.6" } }), Field({ @@ -1999,7 +1860,7 @@ export const DoorLock = Cluster( "If CredentialRule is not null, the CredentialRule in the user record shall be set to the provided " + "value.", - xref: { document: "cluster", section: "5.2.10.34.7" } + xref: { document: "cluster", section: "5.2.10.32.7" } }) ), @@ -2015,7 +1876,7 @@ export const DoorLock = Cluster( "COMMAND, etc.) as needed otherwise the GetUserResponse Command shall be sent implying a status of " + "SUCCESS.", - xref: { document: "cluster", section: "5.2.10.35" } + xref: { document: "cluster", section: "5.2.10.33" } }, Field({ @@ -2032,42 +1893,42 @@ export const DoorLock = Cluster( "If the requested UserIndex is valid and the UserStatus is Available for the requested UserIndex " + "then UserName, UserUniqueID, UserStatus, UserType, CredentialRule, Credentials, CreatorFabricIndex, " + "and LastModifiedFabricIndex shall all be null in the response.", - xref: { document: "cluster", section: "5.2.10.36" } + xref: { document: "cluster", section: "5.2.10.34" } }, Field({ name: "UserIndex", id: 0x0, type: "uint16", conformance: "M", constraint: "1 to numberOfTotalUsersSupported", details: "This field shall indicate the user ID.", - xref: { document: "cluster", section: "5.2.10.36.1" } + xref: { document: "cluster", section: "5.2.10.34.1" } }), Field({ name: "UserName", id: 0x1, type: "string", conformance: "M", constraint: "max 10", quality: "X", details: "This field shall contain a string to use as a human readable identifier for the user.", - xref: { document: "cluster", section: "5.2.10.36.2" } + xref: { document: "cluster", section: "5.2.10.34.2" } }), Field({ name: "UserUniqueId", id: 0x2, type: "uint32", conformance: "M", default: 0, quality: "X", details: "See UserUniqueID field.", - xref: { document: "cluster", section: "5.2.10.36.3" } + xref: { document: "cluster", section: "5.2.10.34.3" } }), Field({ name: "UserStatus", id: 0x3, type: "UserStatusEnum", conformance: "M", default: 0, quality: "X", details: "This field shall indicate the UserStatus assigned to the user when created or modified.", - xref: { document: "cluster", section: "5.2.10.36.4" } + xref: { document: "cluster", section: "5.2.10.34.4" } }), Field({ name: "UserType", id: 0x4, type: "UserTypeEnum", conformance: "M", default: 0, quality: "X", details: "This field shall indicate the UserType assigned to this user when created or modified.", - xref: { document: "cluster", section: "5.2.10.36.5" } + xref: { document: "cluster", section: "5.2.10.34.5" } }), Field({ name: "CredentialRule", id: 0x5, type: "CredentialRuleEnum", conformance: "M", constraint: "desc", default: 0, quality: "X", details: "This field shall indicate the CredentialRule set for this user.", - xref: { document: "cluster", section: "5.2.10.36.6" } + xref: { document: "cluster", section: "5.2.10.34.6" } }), Field( @@ -2075,7 +1936,7 @@ export const DoorLock = Cluster( name: "Credentials", id: 0x6, type: "list", conformance: "M", constraint: "0 to numberOfCredentialsSupportedPerUser", quality: "X", details: "This field shall contain a list of credentials for this user.", - xref: { document: "cluster", section: "5.2.10.36.7" } + xref: { document: "cluster", section: "5.2.10.34.7" } }, Field({ name: "entry", type: "CredentialStruct" }) @@ -2087,7 +1948,7 @@ export const DoorLock = Cluster( "UserStatus is set to Available or when the creator fabric cannot be determined (for example, when " + "user was created outside the Interaction Model) and shall NOT be null otherwise. This value shall " + "be set to 0 if the original creator fabric was deleted.", - xref: { document: "cluster", section: "5.2.10.36.8" } + xref: { document: "cluster", section: "5.2.10.34.8" } }), Field({ @@ -2096,7 +1957,7 @@ export const DoorLock = Cluster( "null if UserStatus is set to Available or when the modifier fabric cannot be determined (for " + "example, when user was modified outside the Interaction Model) and shall NOT be null otherwise. " + "This value shall be set to 0 if the last modifier fabric was deleted.", - xref: { document: "cluster", section: "5.2.10.36.9" } + xref: { document: "cluster", section: "5.2.10.34.9" } }), Field({ @@ -2106,7 +1967,7 @@ export const DoorLock = Cluster( "identifying occupied user slots in the database. This shall NOT be null if there is at least one " + "occupied entry after the requested UserIndex in the User database and shall be null if there are no " + "more occupied entries.", - xref: { document: "cluster", section: "5.2.10.36.10" } + xref: { document: "cluster", section: "5.2.10.34.10" } }) ), @@ -2124,79 +1985,14 @@ export const DoorLock = Cluster( "A LockUserChange event with the provided UserIndex shall be generated after successfully clearing " + "users.", - xref: { document: "cluster", section: "5.2.10.37" } + xref: { document: "cluster", section: "5.2.10.35" } }, Field({ name: "UserIndex", id: 0x0, type: "uint16", conformance: "M", constraint: "1 to numberOfTotalUsersSupported, 65534", details: "This field shall specify a valid User index or 0xFFFE to indicate all user slots shall be cleared.", - xref: { document: "cluster", section: "5.2.10.37.1" } - }) - ), - - Command({ - name: "OperatingEventNotification", id: 0x20, conformance: "[NOT]", direction: "response", - xref: { document: "cluster", section: "5.2.10" } - }), - - Command( - { - name: "ProgrammingEventNotification", id: 0x21, conformance: "[NOT]", direction: "response", - - details: "The door lock server sends out a programming event notification whenever a programming event takes " + - "place on the door lock." + - "\n" + - "As with operational events, all programming events can be turned on and off by flipping bits in the " + - "associated event mask." + - "\n" + - "The programming event notification command includes an optional string of data that can be used by " + - "the manufacturer to pass some manufacturer-specific information if that is required.", - - xref: { document: "cluster", section: "5.2.10.39" } - }, - - Field({ - name: "ProgramEventSource", id: 0x0, type: "EventSourceEnum", conformance: "M", constraint: "desc", - details: "This field shall indicate where the event was triggered from.", - xref: { document: "cluster", section: "5.2.10.39.1" } - }), - Field({ name: "ProgramEventCode", id: 0x1, type: "ProgrammingEventCodeEnum", conformance: "M", constraint: "desc" }), - Field({ - name: "UserId", id: 0x2, type: "uint16", conformance: "M", constraint: "desc", - details: "This field shall indicate the UserID who performed the event", - xref: { document: "cluster", section: "5.2.10.39.6" } - }), - Field({ - name: "Pin", id: 0x3, type: "octstr", conformance: "M", - details: "This field shall indicate the PIN that is associated with the UserID who performed the event", - xref: { document: "cluster", section: "5.2.10.39.7" } - }), - Field({ - name: "UserType", id: 0x4, type: "UserTypeEnum", conformance: "M", constraint: "desc", - details: "This field shall indicate the UserType that is associated with the UserID who performed the event", - xref: { document: "cluster", section: "5.2.10.39.8" } - }), - Field({ - name: "UserStatus", id: 0x5, type: "UserStatusEnum", conformance: "M", constraint: "desc", - details: "This field shall indicate the UserStatus that is associated with the UserID who performed the event", - xref: { document: "cluster", section: "5.2.10.39.9" } - }), - - Field({ - name: "LocalTime", id: 0x6, type: "epoch-s", conformance: "M", - details: "This field shall indicate the time when the event was triggered in Epoch Time in Seconds with local " + - "time offset based on the local timezone and DST offset on the day represented by the value. If time " + - "is not supported, the field shall be populated with default not used value 0xFFFFFFFF.", - xref: { document: "cluster", section: "5.2.10.39.10" } - }), - - Field({ - name: "Data", id: 0x7, type: "string", conformance: "O", - details: "This field may contain a variable string, which can be used to pass data associated with a " + - "particular event. Generally this field will be left empty. However, manufacturer can choose to use " + - "this field to store/display manufacturer-specific information.", - xref: { document: "cluster", section: "5.2.10.39.11" } + xref: { document: "cluster", section: "5.2.10.35.1" } }) ), @@ -2208,21 +2004,21 @@ export const DoorLock = Cluster( "or ProgrammingUser." + "\n" + "Fields used for different use cases:", - xref: { document: "cluster", section: "5.2.10.40" } + xref: { document: "cluster", section: "5.2.10.36" } }, Field({ name: "OperationType", id: 0x0, type: "DataOperationTypeEnum", conformance: "M", constraint: "add, modify", details: "This field shall indicate the set credential operation type requested.", - xref: { document: "cluster", section: "5.2.10.40.1" } + xref: { document: "cluster", section: "5.2.10.36.1" } }), Field({ name: "Credential", id: 0x1, type: "CredentialStruct", conformance: "M", details: "This field shall contain a credential structure that contains the CredentialTypeEnum and the " + "credential index (if applicable or 0 if not) to set.", - xref: { document: "cluster", section: "5.2.10.40.2" } + xref: { document: "cluster", section: "5.2.10.36.2" } }), Field({ @@ -2231,7 +2027,7 @@ export const DoorLock = Cluster( "The length of the credential data shall conform to the limits of the CredentialType specified in " + "the Credential structure otherwise an INVALID_COMMAND status shall be returned in the " + "SetCredentialResponse command.", - xref: { document: "cluster", section: "5.2.10.40.3" } + xref: { document: "cluster", section: "5.2.10.36.3" } }), Field({ @@ -2240,7 +2036,7 @@ export const DoorLock = Cluster( details: "This field shall indicate the user index to the user record that corresponds to the credential " + "being added or modified. This shall be null if OperationType is add and a new credential and user " + "is being added at the same time.", - xref: { document: "cluster", section: "5.2.10.40.4" } + xref: { document: "cluster", section: "5.2.10.36.4" } }), Field({ @@ -2249,7 +2045,7 @@ export const DoorLock = Cluster( details: "This field shall indicate the user status to use in the new user record if a new user is being " + "created. This shall be null if OperationType is Modify. This may be null when adding a new " + "credential and user.", - xref: { document: "cluster", section: "5.2.10.40.5" } + xref: { document: "cluster", section: "5.2.10.36.5" } }), Field({ @@ -2259,7 +2055,7 @@ export const DoorLock = Cluster( details: "This field shall indicate the user type to use in the new user record if a new user is being " + "created. This shall be null if OperationType is Modify. This may be null when adding a new " + "credential and user.", - xref: { document: "cluster", section: "5.2.10.40.6" } + xref: { document: "cluster", section: "5.2.10.36.6" } }) ), @@ -2267,7 +2063,7 @@ export const DoorLock = Cluster( { name: "SetCredentialResponse", id: 0x23, conformance: "USR", direction: "response", details: "Returns the status for setting the specified credential.", - xref: { document: "cluster", section: "5.2.10.41" } + xref: { document: "cluster", section: "5.2.10.37" } }, Field({ @@ -2288,8 +2084,15 @@ export const DoorLock = Cluster( " • DUPLICATE, if CredentialData provided is a duplicate of another credential with the same " + " CredentialType (e.g. duplicate PIN code)." + "\n" + - " • RESOURCE_EXHAUSTED, if OperationType is Add and the user referred to by UserIndex already has " + - " NumberOfCredentialsSupportedPerUser credentials associated." + + " • RESOURCE_EXHAUSTED, if OperationType is Add and the new credential cannot be added due to " + + " resource constraints such as:" + + "\n" + + " ◦ The user referred to by UserIndex already has NumberOfCredentialsSupportedPerUser credentials " + + " associated." + + "\n" + + " ◦ The credential is of type AliroEvictableEndpointKey or AliroNonEvictableEndpointKey, and " + + " adding it would cause the total number of credentials of those two types to exceed " + + " NumberOfAliroEndpointKeysSupported." + "\n" + " • INVALID_COMMAND, if one or more fields violate constraints or are invalid." + "\n" + @@ -2298,7 +2101,7 @@ export const DoorLock = Cluster( "\n" + " • INVALID_COMMAND, if OperationType is Modify and UserIndex points to an available slot.", - xref: { document: "cluster", section: "5.2.10.41.1" } + xref: { document: "cluster", section: "5.2.10.37.1" } }), Field({ @@ -2309,7 +2112,7 @@ export const DoorLock = Cluster( "Modify; if the OperationType was Add and a new User was created this shall NOT be null and shall " + "provide the UserIndex created. If the OperationType was Add and an existing User was associated " + "with the new credential then this shall be null.", - xref: { document: "cluster", section: "5.2.10.41.2" } + xref: { document: "cluster", section: "5.2.10.37.2" } }), Field({ @@ -2323,7 +2126,7 @@ export const DoorLock = Cluster( "NextCredentialIndex reported shall NOT exceed the maximum number of credentials for a particular " + "credential type.", - xref: { document: "cluster", section: "5.2.10.41.3" } + xref: { document: "cluster", section: "5.2.10.37.3" } }) ), @@ -2336,14 +2139,14 @@ export const DoorLock = Cluster( "An InvokeResponse command shall be sent with an appropriate error (e.g. FAILURE, INVALID_COMMAND, " + "etc.) as needed otherwise the GetCredentialStatusResponse command shall be sent implying a status " + "of SUCCESS.", - xref: { document: "cluster", section: "5.2.10.42" } + xref: { document: "cluster", section: "5.2.10.38" } }, Field({ name: "Credential", id: 0x0, type: "CredentialStruct", conformance: "M", details: "This field shall contain a credential structure that contains the CredentialTypeEnum and the " + "credential index (if applicable or 0 if not) to retrieve the status for.", - xref: { document: "cluster", section: "5.2.10.42.1" } + xref: { document: "cluster", section: "5.2.10.38.1" } }) ), @@ -2351,14 +2154,14 @@ export const DoorLock = Cluster( { name: "GetCredentialStatusResponse", id: 0x25, conformance: "USR", direction: "response", details: "Returns the status for the specified credential.", - xref: { document: "cluster", section: "5.2.10.43" } + xref: { document: "cluster", section: "5.2.10.39" } }, Field({ name: "CredentialExists", id: 0x0, type: "bool", conformance: "M", details: "This field shall indicate if the requested credential type and index exists and is populated for " + "the requested user index.", - xref: { document: "cluster", section: "5.2.10.43.1" } + xref: { document: "cluster", section: "5.2.10.39.1" } }), Field({ @@ -2368,7 +2171,7 @@ export const DoorLock = Cluster( "If CredentialType requested was ProgrammingPIN then UserIndex shall be null; otherwise, UserIndex " + "shall be null if CredentialExists is set to False and shall NOT be null if CredentialExists is set " + "to True.", - xref: { document: "cluster", section: "5.2.10.43.2" } + xref: { document: "cluster", section: "5.2.10.39.2" } }), Field({ @@ -2377,7 +2180,7 @@ export const DoorLock = Cluster( "if CredentialExists is set to False or when the creator fabric cannot be determined (for example, " + "when credential was created outside the Interaction Model) and shall NOT be null otherwise. This " + "value shall be set to 0 if the original creator fabric was deleted.", - xref: { document: "cluster", section: "5.2.10.43.3" } + xref: { document: "cluster", section: "5.2.10.39.3" } }), Field({ @@ -2386,7 +2189,7 @@ export const DoorLock = Cluster( "shall be null if CredentialExists is set to False or when the modifier fabric cannot be determined " + "(for example, when credential was modified outside the Interaction Model) and shall NOT be null " + "otherwise. This value shall be set to 0 if the last modifier fabric was deleted.", - xref: { document: "cluster", section: "5.2.10.43.4" } + xref: { document: "cluster", section: "5.2.10.39.4" } }), Field({ @@ -2396,11 +2199,34 @@ export const DoorLock = Cluster( details: "This field shall indicate the next occupied index in the database for the credential type " + "requested, which is useful for quickly identifying occupied credential slots in the database. This " + "shall NOT be null if there is at least one occupied entry after the requested credential index in " + - "the corresponding database and shall be null if there are no more occupied entries. The " + - "NextCredentialIndex reported shall NOT exceed the maximum number of credentials for a particular " + - "credential type.", + "the corresponding" + + "\n" + + "database and shall be null if there are no more occupied entries. The NextCredentialIndex reported " + + "shall NOT exceed the maximum number of credentials for a particular credential type.", + + xref: { document: "cluster", section: "5.2.10.39.5" } + }), + + Field({ + name: "CredentialData", id: 0x5, type: "octstr", conformance: "[ALIRO]", constraint: "desc", + quality: "X", + + details: "This field shall indicate the credential data for the requested user index." + + "\n" + + "If the CredentialType in the GetCredentialStatus command was not AliroCredentialIssuerKey, " + + "AliroEvictableEndpointKey, or AliroNonEvictableEndpointKey, this field shall NOT be included." + + "\n" + + "Otherwise, if CredentialExists is false this field shall be null." + + "\n" + + "Otherwise, the value of this field shall be the value of the relevant credential, as a 65-byte " + + "uncompressed elliptic curve public key as defined in section 2.3.3 of SEC 1." + + "\n" + + "NOTE" + + "\n" + + "Since the Aliro credentials are public keys, there is no security risk in allowing them to be read. " + + "Possession of the credential octet string does not allow operating the lock.", - xref: { document: "cluster", section: "5.2.10.43.5" } + xref: { document: "cluster", section: "5.2.10.39.6" } }) ), @@ -2415,12 +2241,12 @@ export const DoorLock = Cluster( "\n" + "For each credential cleared whose user doesn’t have another valid credential, the corresponding " + "user record shall be reset back to default values and its UserStatus value shall be set to " + - "Available and UserType value shall be set to UnrestrictedUser and all schedules shall be cleared. In" + + "Available and UserType value shall be set to UnrestrictedUser and all schedules shall be cleared. " + + "In this case a LockUserChange event shall be generated for the user being cleared." + "\n" + - "this case a LockUserChange event shall be generated for the user being cleared. Return status shall " + - "be one of the following values:", + "Return status shall be one of the following values:", - xref: { document: "cluster", section: "5.2.10.44" } + xref: { document: "cluster", section: "5.2.10.40" } }, Field({ @@ -2429,7 +2255,7 @@ export const DoorLock = Cluster( details: "This field shall contain a credential structure that contains the CredentialTypeEnum and the " + "credential index (0xFFFE for all credentials or 0 if not applicable) to clear. This shall be null " + "if clearing all credential types otherwise it shall NOT be null.", - xref: { document: "cluster", section: "5.2.10.44.1" } + xref: { document: "cluster", section: "5.2.10.40.1" } }) ), @@ -2447,16 +2273,65 @@ export const DoorLock = Cluster( "If the attribute AutoRelockTime is supported, the lock will transition to the locked state when the " + "auto relock time has expired.", - xref: { document: "cluster", section: "5.2.10.45" } + xref: { document: "cluster", section: "5.2.10.41" } }, Field({ name: "PinCode", id: 0x0, type: "octstr", conformance: "[COTA & PIN]", details: "See PINCode field.", - xref: { document: "cluster", section: "5.2.10.45.1" } + xref: { document: "cluster", section: "5.2.10.41.1" } + }) + ), + + Command( + { + name: "SetAliroReaderConfig", id: 0x28, access: "A T", conformance: "ALIRO", direction: "request", + response: "status", + details: "This command allows communicating an Aliro Reader configuration, as defined in [Aliro], to the lock.", + xref: { document: "cluster", section: "5.2.10.42" } + }, + + Field({ + name: "SigningKey", id: 0x0, type: "octstr", conformance: "M", constraint: "32", + details: "This field shall indicate the signing key component of the Reader’s key pair.", + xref: { document: "cluster", section: "5.2.10.42.1" } + }), + + Field({ + name: "VerificationKey", id: 0x1, type: "octstr", conformance: "M", constraint: "65", + details: "This field shall indicate the verification key component of the Reader’s key pair. This shall be an " + + "uncompressed elliptic curve public key as defined in section 2.3.3 of SEC 1.", + xref: { document: "cluster", section: "5.2.10.42.2" } + }), + + Field({ + name: "GroupIdentifier", id: 0x2, type: "octstr", conformance: "M", constraint: "16", + details: "This field shall indicate the reader group identifier for the lock.", + xref: { document: "cluster", section: "5.2.10.42.3" } + }), + Field({ + name: "GroupResolvingKey", id: 0x3, type: "octstr", conformance: "ALBU", constraint: "16", + details: "This field shall indicate the group resolving key for the lock.", + xref: { document: "cluster", section: "5.2.10.42.4" } }) ), + Command({ + name: "ClearAliroReaderConfig", id: 0x29, access: "A T", conformance: "ALIRO", direction: "request", + response: "status", + + details: "This command allows clearing an existing Aliro Reader configuration for the lock. Administrators " + + "shall NOT clear an Aliro Reader configuration without explicit user permission." + + "\n" + + "NOTE" + + "\n" + + "Using this command will revoke the ability of all existing Aliro user devices that have the old " + + "verification key to interact with the lock. This effect is not restricted to a single fabric or " + + "otherwise scoped in any way.", + + xref: { document: "cluster", section: "5.2.10.43" } + }), + Datatype( { name: "DaysMaskBitmap", type: "map8", @@ -2625,7 +2500,6 @@ export const DoorLock = Cluster( { name: "AlarmMaskBitmap", type: "map16", xref: { document: "cluster", section: "5.2.6.6" } }, Field({ name: "LockJammed", constraint: "0", description: "Locking Mechanism Jammed" }), Field({ name: "LockFactoryReset", constraint: "1", description: "Lock Reset to Factory Defaults" }), - Field({ name: "NA", constraint: "2", description: "Reserved" }), Field({ name: "LockRadioPowerCycled", constraint: "3", description: "RF Module Power Cycled" }), Field({ name: "WrongCodeEntryLimit", constraint: "4", description: "Tamper Alarm - wrong code entry limit" }), Field({ @@ -2635,31 +2509,11 @@ export const DoorLock = Cluster( Field({ name: "DoorForcedOpen", constraint: "6", description: "Forced Door Open under Door Locked Condition" }) ), - Datatype( - { name: "EventMaskBitmap", type: "map16", xref: { document: "cluster", section: "5.2.6.7" } }, - Field({ name: "Bit0", constraint: "0", description: "State of bit 0" }), - Field({ name: "Bit1", constraint: "1", description: "State of bit 1" }), - Field({ name: "Bit2", constraint: "2", description: "State of bit 2" }), - Field({ name: "Bit3", constraint: "3", description: "State of bit 3" }), - Field({ name: "Bit4", constraint: "4", description: "State of bit 4" }), - Field({ name: "Bit5", constraint: "5", description: "State of bit 5" }), - Field({ name: "Bit6", constraint: "6", description: "State of bit 6" }), - Field({ name: "Bit7", constraint: "7", description: "State of bit 7" }), - Field({ name: "Bit8", constraint: "8", description: "State of bit 8" }), - Field({ name: "Bit9", constraint: "9", description: "State of bit 9" }), - Field({ name: "Bit10", constraint: "10", description: "State of bit 10" }), - Field({ name: "Bit11", constraint: "11", description: "State of bit 11" }), - Field({ name: "Bit12", constraint: "12", description: "State of bit 12" }), - Field({ name: "Bit13", constraint: "13", description: "State of bit 13" }), - Field({ name: "Bit14", constraint: "14", description: "State of bit 14" }), - Field({ name: "Bit15", constraint: "15", description: "State of bit 15" }) - ), - Datatype( { name: "AlarmCodeEnum", type: "enum8", details: "This enumeration shall indicate the alarm type.", - xref: { document: "cluster", section: "5.2.6.8" } + xref: { document: "cluster", section: "5.2.6.7" } }, Field({ name: "LockJammed", id: 0x0, conformance: "M", description: "Locking Mechanism Jammed" }), Field({ name: "LockFactoryReset", id: 0x1, conformance: "O", description: "Lock Reset to Factory Defaults" }), @@ -2684,7 +2538,7 @@ export const DoorLock = Cluster( { name: "CredentialRuleEnum", type: "enum8", details: "This enumeration shall indicate the credential rule that can be applied to a particular user.", - xref: { document: "cluster", section: "5.2.6.9" } + xref: { document: "cluster", section: "5.2.6.8" } }, Field({ name: "Single", id: 0x0, conformance: "USR", @@ -2704,21 +2558,80 @@ export const DoorLock = Cluster( { name: "CredentialTypeEnum", type: "enum8", details: "This enumeration shall indicate the credential type.", - xref: { document: "cluster", section: "5.2.6.10" } + xref: { document: "cluster", section: "5.2.6.9" } }, Field({ name: "ProgrammingPin", id: 0x0, conformance: "O", description: "Programming PIN code credential type" }), Field({ name: "Pin", id: 0x1, conformance: "PIN", description: "PIN code credential type" }), Field({ name: "Rfid", id: 0x2, conformance: "RID", description: "RFID identifier credential type" }), Field({ name: "Fingerprint", id: 0x3, conformance: "FGP", description: "Fingerprint identifier credential type" }), Field({ name: "FingerVein", id: 0x4, conformance: "FGP", description: "Finger vein identifier credential type" }), - Field({ name: "Face", id: 0x5, conformance: "FACE", description: "Face identifier credential type" }) + Field({ name: "Face", id: 0x5, conformance: "FACE", description: "Face identifier credential type" }), + + Field({ + name: "AliroCredentialIssuerKey", id: 0x6, conformance: "ALIRO", + description: "A Credential Issuer public key as defined in [Aliro]", + + details: "Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in " + + "section 2.3.3 of SEC 1." + + "\n" + + "Credentials of this type shall NOT be used to allow operating the lock. They shall be used, as " + + "defined in [Aliro], to create new credentials of type AliroEvictableEndpointKey via a step-up " + + "transaction." + + "\n" + + "When performing the step-up transaction, the lock shall request the data element with identifier " + + "\"matter1\", and shall attempt to create a new credential of type AliroEvictableEndpointKey if and " + + "only if the data element is returned and the Access Credential can be validated using the " + + "AliroCredentialIssuerKey." + + "\n" + + "When a new credential of type AliroEvictableEndpointKey is added in this manner, it shall be " + + "associated with the same user record as the AliroCredentialIssuerKey credential that allowed the " + + "new credential to be added." + + "\n" + + "If there are no available credential slots to add a new AliroEvictableEndpointKey credential (i.e. " + + "either the NumberOfCredentialsSupportedPerUser or the NumberOfAliroEndpointKeysSupported limit has " + + "been reached) but there exist credentials of type AliroEvictableEndpointKey associated with the " + + "user record, the server shall remove one of those credentials using the same procedure it would " + + "follow for the ClearCredential command before adding the new credential." + + "\n" + + "If there are no available credential slots to add a new AliroEvictableEndpointKey credential (i.e. " + + "either the NumberOfCredentialsSupportedPerUser or the NumberOfAliroEndpointKeysSupported limit has " + + "been reached) and there do not exist credentials of type AliroEvictableEndpointKey associated with " + + "the user record, a new AliroEvictableEndpointKey credential shall NOT be created." + + "\n" + + "If the step-up process results in addition of new credentials, the corresponding LockUserChange " + + "event shall have OperationSource set to Aliro." + + "\n" + + "If the step-up process results in the lock state changing (e.g. locking or unlocking), the " + + "credential associated with those changes in the LockOperation events shall be the newly provisioned " + + "AliroEvictableEndpointKey credential if one was created. If no new AliroEvictableEndpointKey " + + "credential was created, the credential associated with the changes in the LockOperation events " + + "shall be the AliroCredentialIssuerKey credential used for the step-up.", + + xref: { document: "cluster", section: "5.2.6.9.1" } + }), + + Field({ + name: "AliroEvictableEndpointKey", id: 0x7, conformance: "ALIRO", + description: "An Endpoint public key as defined in [Aliro] which can be evicted if space is needed for another endpoint key", + details: "Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in " + + "section 2.3.3 of SEC 1.", + xref: { document: "cluster", section: "5.2.6.9.2" } + }), + + Field({ + name: "AliroNonEvictableEndpointKey", id: 0x8, conformance: "ALIRO", + description: "An Endpoint public key as defined in [Aliro] which cannot be evicted if space is needed for another endpoint key", + details: "Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in " + + "section 2.3.3 of SEC 1.", + xref: { document: "cluster", section: "5.2.6.9.3" } + }) ), Datatype( { name: "DataOperationTypeEnum", type: "enum8", details: "This enumeration shall indicate the data operation performed.", - xref: { document: "cluster", section: "5.2.6.11" } + xref: { document: "cluster", section: "5.2.6.10" } }, Field({ name: "Add", id: 0x0, conformance: "M", description: "Data is being added or was added" }), Field({ name: "Clear", id: 0x1, conformance: "M", description: "Data is being cleared or was cleared" }), @@ -2729,7 +2642,7 @@ export const DoorLock = Cluster( { name: "DoorStateEnum", type: "enum8", details: "This enumeration shall indicate the current door state.", - xref: { document: "cluster", section: "5.2.6.12" } + xref: { document: "cluster", section: "5.2.6.11" } }, Field({ name: "DoorOpen", id: 0x0, conformance: "DPS", description: "Door state is open" }), Field({ name: "DoorClosed", id: 0x1, conformance: "DPS", description: "Door state is closed" }), @@ -2746,7 +2659,7 @@ export const DoorLock = Cluster( { name: "LockDataTypeEnum", type: "enum8", details: "This enumeration shall indicate the data type that is being or has changed.", - xref: { document: "cluster", section: "5.2.6.13" } + xref: { document: "cluster", section: "5.2.6.12" } }, Field({ name: "Unspecified", id: 0x0, conformance: "O", @@ -2791,6 +2704,18 @@ export const DoorLock = Cluster( Field({ name: "Face", id: 0xa, conformance: "FACE", description: "Lock user face information was added, cleared, or modified." + }), + Field({ + name: "AliroCredentialIssuerKey", id: 0xb, conformance: "ALIRO", + description: "An Aliro credential issuer key credential was added, cleared, or modified." + }), + Field({ + name: "AliroEvictableEndpointKey", id: 0xc, conformance: "ALIRO", + description: "An Aliro endpoint key credential which can be evicted credential was added, cleared, or modified." + }), + Field({ + name: "AliroNonEvictableEndpointKey", id: 0xd, conformance: "ALIRO", + description: "An Aliro endpoint key credential which cannot be evicted was added, cleared, or modified." }) ), @@ -2798,7 +2723,7 @@ export const DoorLock = Cluster( { name: "LockOperationTypeEnum", type: "enum8", details: "This enumeration shall indicate the type of Lock operation performed.", - xref: { document: "cluster", section: "5.2.6.14" } + xref: { document: "cluster", section: "5.2.6.13" } }, Field({ name: "Lock", id: 0x0, conformance: "M", description: "Lock operation" }), Field({ name: "Unlock", id: 0x1, conformance: "M", description: "Unlock operation" }), @@ -2817,7 +2742,7 @@ export const DoorLock = Cluster( { name: "OperationErrorEnum", type: "enum8", details: "This enumeration shall indicate the error cause of the Lock/Unlock operation performed.", - xref: { document: "cluster", section: "5.2.6.15" } + xref: { document: "cluster", section: "5.2.6.14" } }, Field({ name: "Unspecified", id: 0x0, conformance: "O", @@ -2859,18 +2784,18 @@ export const DoorLock = Cluster( "by those commands. The door lock shall NOT disable the radio or otherwise unbind or leave the " + "network. It shall still respond to all other commands and requests.", - xref: { document: "cluster", section: "5.2.6.16" } + xref: { document: "cluster", section: "5.2.6.15" } }, Field({ name: "Normal", id: 0x0, conformance: "M", details: "The lock operates normally. All interfaces are enabled.", - xref: { document: "cluster", section: "5.2.6.16.1" } + xref: { document: "cluster", section: "5.2.6.15.1" } }), Field({ name: "Vacation", id: 0x1, conformance: "O", details: "Only remote interaction is enabled. The keypad shall only be operable by the master user.", - xref: { document: "cluster", section: "5.2.6.16.2" } + xref: { document: "cluster", section: "5.2.6.15.2" } }), Field({ @@ -2878,7 +2803,7 @@ export const DoorLock = Cluster( details: "This mode is only possible if the door is locked. Manual unlocking changes the mode to Normal " + "operating mode. All external interaction with the door lock is disabled. This mode is intended to " + "be used so that users, presumably inside the property, will have control over the entrance.", - xref: { document: "cluster", section: "5.2.6.16.3" } + xref: { document: "cluster", section: "5.2.6.15.3" } }), Field({ @@ -2886,14 +2811,14 @@ export const DoorLock = Cluster( details: "This mode only disables remote interaction with the lock. This does not apply to any remote " + "proprietary means of communication. It specifically applies to the Lock, Unlock, Toggle, and Unlock " + "with Timeout Commands.", - xref: { document: "cluster", section: "5.2.6.16.4" } + xref: { document: "cluster", section: "5.2.6.15.4" } }), Field({ name: "Passage", id: 0x4, conformance: "O", details: "The lock is open or can be opened or closed at will without the use of a Keypad or other means of " + "user validation (e.g. a lock for a business during work hours).", - xref: { document: "cluster", section: "5.2.6.16.5" } + xref: { document: "cluster", section: "5.2.6.15.5" } }) ), @@ -2901,7 +2826,7 @@ export const DoorLock = Cluster( { name: "OperationSourceEnum", type: "enum8", details: "This enumeration shall indicate the source of the Lock/Unlock or user change operation performed.", - xref: { document: "cluster", section: "5.2.6.17" } + xref: { document: "cluster", section: "5.2.6.16" } }, Field({ name: "Unspecified", id: 0x0, conformance: "O", @@ -2933,6 +2858,10 @@ export const DoorLock = Cluster( Field({ name: "Biometric", id: 0x9, conformance: "[USR]", description: "Lock/unlock operation came from biometric source (e.g. face, fingerprint/fingervein)" + }), + Field({ + name: "Aliro", id: 0xa, conformance: "ALIRO", + description: "Lock/unlock operation came from an interaction defined in [Aliro], or user change operation was a step-up credential provisioning as defined in [Aliro]" }) ), @@ -2940,7 +2869,7 @@ export const DoorLock = Cluster( { name: "UserStatusEnum", type: "enum8", details: "This enumeration shall indicate what the status is for a specific user ID.", - xref: { document: "cluster", section: "5.2.6.18" } + xref: { document: "cluster", section: "5.2.6.17" } }, Field({ name: "Available", id: 0x0, conformance: "M", description: "The user ID is available" }), Field({ name: "OccupiedEnabled", id: 0x1, conformance: "M", description: "The user ID is occupied and enabled" }), @@ -2951,7 +2880,7 @@ export const DoorLock = Cluster( { name: "UserTypeEnum", type: "enum8", details: "This enumeration shall indicate what the type is for a specific user ID.", - xref: { document: "cluster", section: "5.2.6.19" } + xref: { document: "cluster", section: "5.2.6.18" } }, Field({ @@ -2959,21 +2888,41 @@ export const DoorLock = Cluster( description: "The user ID type is unrestricted", details: "This value shall indicate the user has access 24/7 provided proper PIN or RFID is supplied (e.g., " + "owner).", - xref: { document: "cluster", section: "5.2.6.19.1" } + xref: { document: "cluster", section: "5.2.6.18.1" } }), Field({ name: "YearDayScheduleUser", id: 0x1, conformance: "O", description: "The user ID type is schedule", + details: "This value shall indicate the user has the ability to open lock within a specific time period " + - "(e.g., guest).", - xref: { document: "cluster", section: "5.2.6.19.2" } + "(e.g., guest)." + + "\n" + + "When UserType is set to YearDayScheduleUser, user access shall be restricted as follows:" + + "\n" + + " • If no YearDaySchedules are set for the user, then access shall be denied" + + "\n" + + " • If one or more YearDaySchedules are set, user access shall be granted if and only if the " + + " current time falls within at least one of the YearDaySchedules. If current time is not known, " + + " user access shall NOT be granted.", + + xref: { document: "cluster", section: "5.2.6.18.2" } }), Field({ name: "WeekDayScheduleUser", id: 0x2, conformance: "O", description: "The user ID type is schedule", + details: "This value shall indicate the user has the ability to open lock based on specific time period " + - "within a reoccurring weekly schedule (e.g., cleaning worker).", - xref: { document: "cluster", section: "5.2.6.19.3" } + "within a reoccurring weekly schedule (e.g., cleaning worker)." + + "\n" + + "When UserType is set to WeekDayScheduleUser, user access shall be restricted as follows:" + + "\n" + + " • If no WeekDaySchedules are set for the user, then access shall be denied" + + "\n" + + " • If one or more WeekDaySchedules are set, user access shall be granted if and only if the " + + " current time falls within at least one of the WeekDaySchedules. If current time is not known, " + + " user access shall NOT be granted.", + + xref: { document: "cluster", section: "5.2.6.18.3" } }), Field({ @@ -2982,7 +2931,7 @@ export const DoorLock = Cluster( "user can manage the users and user schedules. In all other respects this user matches the " + "unrestricted (default) user. ProgrammingUser is the only user that can disable the user interface " + "(keypad, remote, etc…).", - xref: { document: "cluster", section: "5.2.6.19.4" } + xref: { document: "cluster", section: "5.2.6.18.4" } }), Field({ @@ -2990,7 +2939,7 @@ export const DoorLock = Cluster( details: "This value shall indicate the user is recognized by the lock but does not have the ability to open " + "the lock. This user will only cause the lock to generate the appropriate event notification to any " + "bound devices.", - xref: { document: "cluster", section: "5.2.6.19.5" } + xref: { document: "cluster", section: "5.2.6.18.5" } }), Field({ @@ -2998,7 +2947,7 @@ export const DoorLock = Cluster( details: "This value shall indicate the user has the ability to open lock but a ForcedUser LockOperationType " + "and ForcedUser silent alarm will be emitted to allow a notified Node to alert emergency services or " + "contacts on the user account when used.", - xref: { document: "cluster", section: "5.2.6.19.6" } + xref: { document: "cluster", section: "5.2.6.18.6" } }), Field({ @@ -3006,7 +2955,7 @@ export const DoorLock = Cluster( description: "The user ID type is disposable", details: "This value shall indicate the user has the ability to open lock once after which the lock shall " + "change the corresponding user record UserStatus value to OccupiedDisabled automatically.", - xref: { document: "cluster", section: "5.2.6.19.7" } + xref: { document: "cluster", section: "5.2.6.18.7" } }), Field({ @@ -3016,14 +2965,29 @@ export const DoorLock = Cluster( "ExpiringUserTimeout minutes the corresponding user record UserStatus value shall be set to " + "OccupiedDisabled automatically by the lock. The lock shall persist the timeout across reboots such " + "that the ExpiringUserTimeout is honored.", - xref: { document: "cluster", section: "5.2.6.19.8" } + xref: { document: "cluster", section: "5.2.6.18.8" } }), Field({ name: "ScheduleRestrictedUser", id: 0x8, conformance: "WDSCH | YDSCH", description: "The user ID type is schedule restricted", - details: "This value shall indicate the user access is restricted by Week Day and/or Year Day schedule.", - xref: { document: "cluster", section: "5.2.6.19.9" } + + details: "This value shall indicate the user access is restricted by Week Day and/or Year Day schedule. When " + + "UserType is set to ScheduleRestrictedUser, user access shall be restricted as follows:" + + "\n" + + " • If no WeekDaySchedules and no YearDaySchedules are set for the user, then access shall be denied" + + "\n" + + " • If one or more WeekDaySchedules are set, but no YearDaySchedules are set for the user, then " + + " user access shall be equivalent to the WeekDayScheduleUser UserType" + + "\n" + + " • If one or more YearDaySchedules are set, but no WeekDaySchedules are set for the user, then " + + " user access shall be equivalent to the YearDayScheduleUser UserType" + + "\n" + + " • If one or WeekDaySchedules are set AND one or more YearDaySchedules are set, then user access " + + " shall be granted if and only if the current time falls within at least one of the " + + " WeekDaySchedules AND the current time falls within at least one of the YearDaySchedules.", + + xref: { document: "cluster", section: "5.2.6.18.9" } }), Field({ @@ -3033,12 +2997,12 @@ export const DoorLock = Cluster( "only. This type of user might be useful for regular delivery services or voice assistant unlocking " + "operations to prevent a PIN code credential created for them from being used at the keypad. The PIN " + "code credential would only be provided over-the-air for the lock/unlock commands.", - xref: { document: "cluster", section: "5.2.6.19.10" } + xref: { document: "cluster", section: "5.2.6.18.10" } }) ), Datatype( - { name: "LockStateEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.20" } }, + { name: "LockStateEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.19" } }, Field({ name: "NotFullyLocked", id: 0x0, conformance: "M", description: "Lock state is not fully locked" }), Field({ name: "Locked", id: 0x1, conformance: "M", description: "Lock state is fully locked" }), Field({ name: "Unlocked", id: 0x2, conformance: "M", description: "Lock state is fully unlocked" }), @@ -3049,7 +3013,7 @@ export const DoorLock = Cluster( ), Datatype( - { name: "LockTypeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.21" } }, + { name: "LockTypeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.20" } }, Field({ name: "DeadBolt", id: 0x0, conformance: "M", description: "Physical lock type is dead bolt" }), Field({ name: "Magnetic", id: 0x1, conformance: "M", description: "Physical lock type is magnetic" }), Field({ name: "Other", id: 0x2, conformance: "M", description: "Physical lock type is other" }), @@ -3068,7 +3032,7 @@ export const DoorLock = Cluster( ), Datatype( - { name: "LEDSettingEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.22" } }, + { name: "LEDSettingEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.21" } }, Field({ name: "NoLedSignal", id: 0x0, conformance: "M", description: "Never use LED for signalization" }), Field({ name: "NoLedSignalAccessAllowed", id: 0x1, conformance: "M", @@ -3078,7 +3042,7 @@ export const DoorLock = Cluster( ), Datatype( - { name: "SoundVolumeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.23" } }, + { name: "SoundVolumeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.22" } }, Field({ name: "Silent", id: 0x0, conformance: "M", description: "Silent Mode" }), Field({ name: "Low", id: 0x1, conformance: "M", description: "Low Volume" }), Field({ name: "High", id: 0x2, conformance: "M", description: "High Volume" }), @@ -3086,82 +3050,24 @@ export const DoorLock = Cluster( ), Datatype( - { name: "EventTypeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.24" } }, + { name: "EventTypeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.23" } }, Field({ name: "Operation", id: 0x0, conformance: "M", description: "Event type is operation" }), Field({ name: "Programming", id: 0x1, conformance: "M", description: "Event type is programming" }), Field({ name: "Alarm", id: 0x2, conformance: "M", description: "Event type is alarm" }) ), - Datatype( - { name: "EventSourceEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.25" } }, - Field({ name: "Keypad", id: 0x0, conformance: "M", description: "Event source is keypad" }), - Field({ name: "Remote", id: 0x1, conformance: "M", description: "Event source is remote" }), - Field({ name: "Manual", id: 0x2, conformance: "M", description: "Event source is manual" }), - Field({ name: "Rfid", id: 0x3, conformance: "M", description: "Event source is RFID" }), - Field({ name: "Indeterminate", id: 0xff, conformance: "M", description: "Event source is unknown" }) - ), - - Datatype( - { name: "OperationEventCodeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.25.1" } }, - Field({ name: "UnknownOrMfgSpecific", id: 0x0, conformance: "O", description: "Event code is unknown" }), - Field({ name: "Lock", id: 0x1, conformance: "O", description: "Event code is lock" }), - Field({ name: "Unlock", id: 0x2, conformance: "O", description: "Event code is unlock" }), - Field({ - name: "LockFailureInvalidPiNorRfid", id: 0x3, conformance: "O", - description: "Event code is lock failure due to invalid PIN or RFID" - }), - Field({ - name: "LockFailureInvalidSchedule", id: 0x4, conformance: "O", - description: "Event code is lock failure due to invalid schedule" - }), - Field({ - name: "UnlockFailureInvalidPiNorRfid", id: 0x5, conformance: "O", - description: "Event code is unlock failure due to invalid PIN or RFID" - }), - Field({ - name: "UnlockFailureInvalidSchedule", id: 0x6, conformance: "O", - description: "Event code is unlock failure due to invalid schedule" - }), - Field({ name: "OneTouchLock", id: 0x7, conformance: "O", description: "Event code is one touch lock" }), - Field({ name: "KeyLock", id: 0x8, conformance: "O", description: "Event code is key lock" }), - Field({ name: "KeyUnlock", id: 0x9, conformance: "O", description: "Event code is key unlock" }), - Field({ name: "AutoLock", id: 0xa, conformance: "O", description: "Event code is auto lock" }), - Field({ name: "ScheduleLock", id: 0xb, conformance: "WDSCH | YDSCH", description: "Event code is schedule lock" }), - Field({ name: "ScheduleUnlock", id: 0xc, conformance: "WDSCH | YDSCH", description: "Event code is schedule unlock" }), - Field({ name: "ManualLock", id: 0xd, conformance: "O", description: "Event code is manual lock (Key or Thumbturn)" }), - Field({ - name: "ManualUnlock", id: 0xe, conformance: "O", - description: "Event code is manual unlock (Key or Thumbturn)" - }), - Field({ - name: "NonAccessUserOperationEvent", id: 0xf, conformance: "O", - description: "Event code is non access user operation" - }) - ), - - Datatype( - { name: "ProgrammingEventCodeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.6.25.2" } }, - Field({ name: "UnknownOrMfgSpecific", id: 0x0, conformance: "O", description: "Event code is unknown" }), - Field({ name: "ProgrammingCodeChanged", id: 0x1, conformance: "O", description: "Event code is code changed" }), - Field({ name: "PinCodeAdded", id: 0x2, conformance: "O", description: "Event code is PIN added" }), - Field({ name: "PinCodeCleared", id: 0x3, conformance: "O", description: "Event code is PIN cleared" }), - Field({ name: "PinCodeChanged", id: 0x4, conformance: "O", description: "Event code is PIN changed" }), - Field({ name: "RfidCodeAdded", id: 0x5, conformance: "O", description: "Event code is RFID added" }), - Field({ name: "RfidCodeCleared", id: 0x6, conformance: "O", description: "Event code is RFID cleared" }) - ), - Datatype( { name: "CredentialStruct", type: "struct", details: "This struct shall indicate the credential types and their corresponding indices (if any) for the " + "event or user record.", - xref: { document: "cluster", section: "5.2.6.26" } + xref: { document: "cluster", section: "5.2.6.24" } }, Field({ name: "CredentialType", id: 0x0, type: "CredentialTypeEnum", conformance: "M", details: "This field shall indicate the credential field used to authorize the lock operation.", - xref: { document: "cluster", section: "5.2.6.26.1" } + xref: { document: "cluster", section: "5.2.6.24.1" } }), Field({ @@ -3170,14 +3076,14 @@ export const DoorLock = Cluster( "in the list of credentials identified by CredentialType (e.g. PIN, RFID, etc.). This field shall be " + "set to 0 if CredentialType is ProgrammingPIN or does not correspond to a list that can be indexed " + "into.", - xref: { document: "cluster", section: "5.2.6.26.2" } + xref: { document: "cluster", section: "5.2.6.24.2" } }) ), Datatype( { name: "StatusCodeEnum", type: "enum8", xref: { document: "cluster", section: "5.2.7.1" } }, - Field({ name: "Duplicate", id: 0x2, description: "Entry would cause a duplicate credential/ID." }), - Field({ name: "Occupied", id: 0x3, description: "Entry would replace an occupied slot." }) + Field({ name: "Duplicate", id: 0x2, conformance: "M", description: "Entry would cause a duplicate credential/ID." }), + Field({ name: "Occupied", id: 0x3, conformance: "M", description: "Entry would replace an occupied slot." }) ) ); diff --git a/packages/model/src/standard/elements/DoorLockControllerDT.ts b/packages/model/src/standard/elements/DoorLockControllerDT.ts index a3e3d0bdeb..30d8aeb40f 100644 --- a/packages/model/src/standard/elements/DoorLockControllerDT.ts +++ b/packages/model/src/standard/elements/DoorLockControllerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,7 @@ export const DoorLockControllerDt = DeviceType( xref: { document: "device", section: "8.2.4" } }), Requirement({ - name: "ScenesManagement", id: 0x5, conformance: "P, O", element: "clientCluster", + name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "clientCluster", xref: { document: "device", section: "8.2.4" } }), Requirement({ diff --git a/packages/model/src/standard/elements/DoorLockDT.ts b/packages/model/src/standard/elements/DoorLockDT.ts index d95b7e61ab..ff2d74221b 100644 --- a/packages/model/src/standard/elements/DoorLockDT.ts +++ b/packages/model/src/standard/elements/DoorLockDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -30,7 +30,7 @@ export const DoorLockDt = DeviceType( xref: { document: "device", section: "8.1.4" } }), Requirement({ - name: "ScenesManagement", id: 0x5, conformance: "X", element: "serverCluster", + name: "ScenesManagement", id: 0x62, conformance: "X", element: "serverCluster", xref: { document: "device", section: "8.1.4" } }), @@ -39,7 +39,7 @@ export const DoorLockDt = DeviceType( name: "DoorLock", id: 0x101, conformance: "M", element: "serverCluster", xref: { document: "device", section: "8.1.4" } }, - Requirement({ name: "USER", conformance: "Matter & (PIN | RID | FPG | FACE)", element: "feature" }), + Requirement({ name: "USER", conformance: "Matter & (PIN | RID | FPG | FACE | ALIRO)", element: "feature" }), Requirement({ name: "RFIDCREDENTIAL", conformance: "P, O", element: "feature" }), Requirement({ name: "AlarmMask", conformance: "[Alarms]", element: "attribute" }) ) diff --git a/packages/model/src/standard/elements/EcosystemInformation.ts b/packages/model/src/standard/elements/EcosystemInformation.ts new file mode 100644 index 0000000000..2d2faf6510 --- /dev/null +++ b/packages/model/src/standard/elements/EcosystemInformation.ts @@ -0,0 +1,191 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + DatatypeElement as Datatype, + FieldElement as Field +} from "../../elements/index.js"; + +export const EcosystemInformation = Cluster( + { + name: "EcosystemInformation", id: 0x750, classification: "endpoint", pics: "ECOINFO", + + details: "The Ecosystem Information Cluster provides extended device information for all the logical devices " + + "represented by a Bridged Node. The Ecosystem Information Cluster presents the view of device name " + + "and location metadata for presentation by a client of the cluster to a user. This cluster is " + + "intended to support Fabric Synchronization and be present on an endpoint with the BridgedNode " + + "device type listed in the DeviceTypeList of the endpoint’s Descriptor cluster." + + "\n" + + "This augments the Bridged Device Basic Information Cluster in the following ways:" + + "\n" + + " • The Ecosystem Information Cluster adds support for providing a name and location for individual " + + " endpoints. (The endpoints do not need to be present on the Bridge for their name and location " + + " information to be present.)" + + "\n" + + " • The Ecosystem Information Cluster adds metadata to support conflict resolution between multiple " + + " sources of the name and location data." + + "\n" + + " • The Ecosystem Information Cluster supports user control for the presence of the name and " + + " location information by specifying more restricted access." + + "\n" + + "A client SHOULD use the information provided by the Ecosystem Information Cluster to help the user " + + "organize and interact with their devices. Some examples may include:" + + "\n" + + " • Directly organizing and labeling the devices in a client’s user interface." + + "\n" + + " • Providing hints in the user interface, which can assist the user in organizing and labeling " + + " their devices." + + "\n" + + "For the purposes of the Ecosystem Information Cluster section, an instance of the Ecosystem " + + "Information Cluster will be referred to as an \"instance\".", + + xref: { document: "core", section: "9.18" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Datatype( + { name: "EcosystemDeviceStruct", type: "struct", xref: { document: "core", section: "9.18.4.1" } }, + + Field({ + name: "DeviceName", id: 0x0, type: "string", access: "S", conformance: "O", constraint: "max 64", + details: "This field shall indicate the device’s name, which is provided externally if the user consents. " + + "(For example, provided by the user in an ecosystem specific interface.)", + xref: { document: "core", section: "9.18.4.1.1" } + }), + + Field({ + name: "DeviceNameLastEdit", id: 0x1, type: "epoch-us", access: "S", conformance: "desc", default: 0, + details: "This field shall be present and set if the DeviceName field is present." + + "\n" + + "This field shall indicate the timestamp of when the DeviceName was last modified.", + xref: { document: "core", section: "9.18.4.1.2" } + }), + + Field({ + name: "BridgedEndpoint", id: 0x2, type: "endpoint-no", access: "S", conformance: "desc", + constraint: "desc", + details: "This field shall indicate the endpoint this EcosystemDeviceStruct is associated with on this Bridge." + + "\n" + + "This field shall be present and set to a valid endpoint if the device is accessible through the " + + "bridge.", + xref: { document: "core", section: "9.18.4.1.3" } + }), + + Field({ + name: "OriginalEndpoint", id: 0x3, type: "endpoint-no", access: "S", conformance: "desc", + constraint: "desc", + details: "This field shall indicate the endpoint this EcosystemDeviceStruct is associated with on the " + + "original device represented by this bridge’s Bridged Node. If this bridge is receiving the device " + + "from another bridge, then the OriginalEndpoint field value would be the same on both bridges. This " + + "field shall be present and set to a valid endpoint on the original device if that device is a " + + "Matter device.", + xref: { document: "core", section: "9.18.4.1.4" } + }), + + Field( + { + name: "DeviceTypes", id: 0x4, type: "list", access: "S", conformance: "M", constraint: "desc", + details: "This field shall indicate all of the DeviceTypes within the DeviceTypeList in the Descriptor " + + "Cluster associated with this EcosystemDeviceStruct entry." + + "\n" + + "This field shall contain a list of valid device type ids.", + xref: { document: "core", section: "9.18.4.1.5" } + }, + + Field({ name: "entry", type: "Descriptor.DeviceTypeStruct" }) + ), + + Field( + { + name: "UniqueLocationIDs", id: 0x5, type: "list", access: "S", conformance: "M", + constraint: "max 64[max 64]", + details: "This field shall specify the EcosystemLocationStruct entries in the LocationDirectory attribute " + + "associated with this EcosystemDeviceStruct.", + xref: { document: "core", section: "9.18.4.1.6" } + }, + + Field({ name: "entry", type: "string" }) + ), + + Field({ + name: "UniqueLocationIDsLastEdit", id: 0x6, type: "epoch-us", access: "S", conformance: "M", + default: 0, + + details: "This field shall indicate the timestamp of when the UniqueLocationIDs was last modified." + + "\n" + + "NOTE" + + "\n" + + "If multiple server instances update the UniqueLocationIDs field at the same time, it is possible " + + "one of the updates will be missed. This is considered an acceptable limitation to reduce the " + + "complexity of the design. Since this is meant to be provided from user input, it is unlikely these " + + "signals would be happening at one time.", + + xref: { document: "core", section: "9.18.4.1.7" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "EcosystemLocationStruct", type: "struct", xref: { document: "core", section: "9.18.4.2" } }, + + Field({ + name: "UniqueLocationId", id: 0x0, type: "string", access: "S", conformance: "M", + constraint: "max 64", + + details: "This field shall indicate a unique identifier for a specific Ecosystem Information Cluster server " + + "instance representing the location independent of its LocationDescriptor field." + + "\n" + + "UniqueLocationID can be used by the client to determine if the change is a relocation of the device " + + "or just a renaming of the location." + + "\n" + + "No guarantees are given for consistency of the ID between server instances. The same location may " + + "be represented by different IDs on different Ecosystem Information Cluster server instances, so " + + "only the history from a single server instance should be considered when evaluating a change." + + "\n" + + "UniqueLocationID shall be changed when the LocationDescriptor changes from one existing location to " + + "another location as a result of an external interaction. (For example, the user changes the " + + "location assignment.)" + + "\n" + + "UniqueLocationID shall NOT be changed when the LocationDescriptor changes name, but still " + + "represents the same location. (For example, the user renames a room.)" + + "\n" + + "UniqueLocationID shall be changed when LocationDescriptor changes as a result of another Ecosystem " + + "Information Cluster server instance changing and the UniqueLocationID on the remote server instance " + + "also changes." + + "\n" + + "UniqueLocationID shall NOT be changed when LocationDescriptor changes as a result of another " + + "Ecosystem Information Cluster server instance changing and the UniqueLocationID on the remote " + + "server instance does not change.", + + xref: { document: "core", section: "9.18.4.2.1" } + }), + + Field({ + name: "LocationDescriptor", id: 0x1, type: "locationdesc", access: "S", conformance: "M", + + details: "This field shall indicate the location (e.g. living room, driveway) and associated metadata that is " + + "provided externally if the user consents. (For example, provided by the user in an ecosystem " + + "specific interface.)" + + "\n" + + "\"Location\" in this context is typically used by the user’s grouping into rooms, areas or other " + + "logical groupings of how devices are used. So a device might be part of multiple such \"Locations\"s.", + + xref: { document: "core", section: "9.18.4.2.2" } + }), + + Field({ name: "LocationDescriptorLastEdit", id: 0x2, type: "epoch-us", access: "S", conformance: "M", default: 0 }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) +); + +MatterDefinition.children.push(EcosystemInformation); diff --git a/packages/model/src/standard/elements/ElectricalEnergyMeasurement.ts b/packages/model/src/standard/elements/ElectricalEnergyMeasurement.ts index b474ec2cff..7d27188e34 100644 --- a/packages/model/src/standard/elements/ElectricalEnergyMeasurement.ts +++ b/packages/model/src/standard/elements/ElectricalEnergyMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -157,7 +157,7 @@ export const ElectricalEnergyMeasurement = Cluster( Event( { - name: "CumulativeEnergyMeasured", id: 0x0, access: "R V", conformance: "CUME", priority: "info", + name: "CumulativeEnergyMeasured", id: 0x0, access: "V", conformance: "CUME", priority: "info", details: "This event shall be generated when the server takes a snapshot of the cumulative energy imported by " + "the server, exported from the server, or both, but not more frequently than the rate mentioned in " + "the description above of the related attribute.", @@ -181,7 +181,7 @@ export const ElectricalEnergyMeasurement = Cluster( Event( { - name: "PeriodicEnergyMeasured", id: 0x1, access: "R V", conformance: "PERE", priority: "info", + name: "PeriodicEnergyMeasured", id: 0x1, access: "V", conformance: "PERE", priority: "info", details: "This event shall be generated when the server reaches the end of a reporting period for imported " + "energy, exported energy, or both.", xref: { document: "cluster", section: "2.12.7.2" } @@ -220,7 +220,7 @@ export const ElectricalEnergyMeasurement = Cluster( }, Field({ - name: "Energy", id: 0x0, type: "energy-mWh", access: "R V", conformance: "M", constraint: "min 0", + name: "Energy", id: 0x0, type: "energy-mWh", conformance: "M", constraint: "min 0", details: "This field shall be the reported energy." + "\n" + @@ -236,7 +236,7 @@ export const ElectricalEnergyMeasurement = Cluster( }), Field({ - name: "StartTimestamp", id: 0x1, type: "epoch-s", access: "R V", conformance: "desc", + name: "StartTimestamp", id: 0x1, type: "epoch-s", conformance: "desc", details: "This field shall indicate the timestamp in UTC of the beginning of the period during which the " + "value of the Energy field was measured." + @@ -254,8 +254,8 @@ export const ElectricalEnergyMeasurement = Cluster( }), Field({ - name: "EndTimestamp", id: 0x2, type: "epoch-s", access: "R V", conformance: "desc", - constraint: "min startTimestamp1", + name: "EndTimestamp", id: 0x2, type: "epoch-s", conformance: "desc", + constraint: "min startTimestamp + 1", details: "This field shall indicate the timestamp in UTC of the end of the period during which the value of " + "the Energy field was measured." + @@ -270,37 +270,37 @@ export const ElectricalEnergyMeasurement = Cluster( }), Field({ - name: "StartSystime", id: 0x3, type: "systime-ms", access: "R V", conformance: "desc", + name: "StartSystime", id: 0x3, type: "systime-ms", conformance: "desc", - details: "This field shall indicate the seconds since boot at the beginning of the period during which the " + - "value of the Energy field was measured." + + details: "This field shall indicate the time elapsed since boot at the beginning of the period during which " + + "the value of the Energy field was measured." + "\n" + - "If this EnergyMeasurementStruct represents cumulative energy, this field shall be omitted." + + "If this EnergyMeasurementStruct represents cumulative energy, this field shall be omitted. " + + "Otherwise, if the server had not yet determined the time in UTC at the start of the measurement" + "\n" + - "Otherwise, if the server had not yet determined the time in UTC at the start of the measurement " + "period, or does not have the capability of determining the time in UTC, this field shall be " + "indicated." + "\n" + "Otherwise, if the server had determined the time in UTC at or before the beginning of the " + - "measurement period, this field may be omitted; if it is indicated, its value shall be the seconds " + - "since boot at the UTC time indicated in StartTimestamp.", + "measurement period, this field may be omitted; if it is indicated, its value shall be the time " + + "elapsed since boot at the UTC time indicated in StartTimestamp.", xref: { document: "cluster", section: "2.12.5.1.4" } }), Field({ - name: "EndSystime", id: 0x4, type: "systime-ms", access: "R V", conformance: "desc", - constraint: "min startSystime1", + name: "EndSystime", id: 0x4, type: "systime-ms", conformance: "desc", + constraint: "min startSystime + 1", - details: "This field shall indicate the seconds since boot at the end of the period during which the value of " + - "the Energy field was measured." + + details: "This field shall indicate the time elapsed since boot at the end of the period during which the " + + "value of the Energy field was measured." + "\n" + "If the server had not yet determined the time in UTC by the end of the measurement period, or does " + "not have the capability of determining the time in UTC, this field shall be indicated." + "\n" + "Otherwise, if the server had determined the time in UTC by the end of the measurement period, this " + - "field may be omitted; if it is indicated, its value shall be the seconds since boot at the UTC time " + - "indicated in EndTimestamp.", + "field may be omitted; if it is indicated, its value shall be the time elapsed since boot at the UTC " + + "time indicated in EndTimestamp.", xref: { document: "cluster", section: "2.12.5.1.5" } }) @@ -315,8 +315,8 @@ export const ElectricalEnergyMeasurement = Cluster( }, Field({ - name: "ImportedResetTimestamp", id: 0x0, type: "epoch-s", access: "R V", conformance: "[IMPE]", - default: null, quality: "X", + name: "ImportedResetTimestamp", id: 0x0, type: "epoch-s", conformance: "[IMPE]", default: null, + quality: "X", details: "This field shall indicate the timestamp in UTC when the value of the Energy field on the " + "CumulativeEnergyImported attribute was most recently zero." + @@ -335,15 +335,14 @@ export const ElectricalEnergyMeasurement = Cluster( }), Field({ - name: "ExportedResetTimestamp", id: 0x1, type: "epoch-s", access: "R V", conformance: "[EXPE]", - default: null, quality: "X", + name: "ExportedResetTimestamp", id: 0x1, type: "epoch-s", conformance: "[EXPE]", default: null, + quality: "X", details: "This field shall indicate the timestamp in UTC when the value of the Energy field on the " + "CumulativeEnergyExported attribute was most recently zero." + "\n" + - "If the server had determined the time in UTC when the value of the Energy field on the Cumula" + - "\n" + - "tiveEnergyExported attribute was most recently zero, this field shall be indicated." + + "If the server had determined the time in UTC when the value of the Energy field on the " + + "CumulativeEnergyExported attribute was most recently zero, this field shall be indicated." + "\n" + "Otherwise, if the server had not yet determined the time in UTC when the value of the Energy field " + "on the CumulativeEnergyExported attribute was most recently zero, or does not have the capability " + @@ -356,10 +355,10 @@ export const ElectricalEnergyMeasurement = Cluster( }), Field({ - name: "ImportedResetSystime", id: 0x2, type: "systime-ms", access: "R V", conformance: "[IMPE]", - default: null, quality: "X", + name: "ImportedResetSystime", id: 0x2, type: "systime-ms", conformance: "[IMPE]", default: null, + quality: "X", - details: "This field shall indicate the seconds since boot when the value of the Energy field on the " + + details: "This field shall indicate the time elapsed since boot when the value of the Energy field on the " + "CumulativeEnergyImported attribute was most recently zero." + "\n" + "If the server had not yet determined the time in UTC when the value of the Energy field on the " + @@ -368,17 +367,17 @@ export const ElectricalEnergyMeasurement = Cluster( "\n" + "Otherwise, if the server had determined the time in UTC when the value of the Energy field on the " + "CumulativeEnergyImported attribute was most recently zero, this field may be omitted; if it is " + - "indicated, its value shall be the seconds since boot at the UTC time indicated in " + + "indicated, its value shall be the time elapsed since boot at the UTC time indicated in " + "ImportedResetTimestamp.", xref: { document: "cluster", section: "2.12.5.2.3" } }), Field({ - name: "ExportedResetSystime", id: 0x3, type: "systime-ms", access: "R V", conformance: "[EXPE]", - default: null, quality: "X", + name: "ExportedResetSystime", id: 0x3, type: "systime-ms", conformance: "[EXPE]", default: null, + quality: "X", - details: "This field shall indicate the seconds since boot when the value of the Energy field on the " + + details: "This field shall indicate the time elapsed since boot when the value of the Energy field on the " + "CumulativeEnergyExported attribute was most recently zero." + "\n" + "If the server had not yet determined the time in UTC when the value of the Energy field on the " + @@ -387,7 +386,7 @@ export const ElectricalEnergyMeasurement = Cluster( "\n" + "Otherwise, if the server had determined the time in UTC when the value of the Energy field on the " + "CumulativeEnergyExported attribute was most recently zero, this field may be omitted; if it is " + - "indicated, its value shall be the seconds since boot at the UTC time indicated in " + + "indicated, its value shall be the time elapsed since boot at the UTC time indicated in " + "ImportedResetTimestamp.", xref: { document: "cluster", section: "2.12.5.2.4" } diff --git a/packages/model/src/standard/elements/ElectricalMeasurementNS.ts b/packages/model/src/standard/elements/ElectricalMeasurementNS.ts index 05b86cab92..1d16bc835a 100644 --- a/packages/model/src/standard/elements/ElectricalMeasurementNS.ts +++ b/packages/model/src/standard/elements/ElectricalMeasurementNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ export const ElectricalMeasurementNs = SemanticNamespace( name: "ElectricalMeasurement", id: 0xa, details: "The tags contained in this namespace are restricted for use in the electrical measurement domain " + "and shall NOT be used in any other domain or context.", - xref: { document: "namespace", section: "10" } + xref: { document: "namespace", section: "12" } }, SemanticTag({ name: "DC", id: 0x0, description: "Indicates values measured for a DC load" }), diff --git a/packages/model/src/standard/elements/ElectricalPowerMeasurement.ts b/packages/model/src/standard/elements/ElectricalPowerMeasurement.ts index d375ceae4f..65247f84e1 100644 --- a/packages/model/src/standard/elements/ElectricalPowerMeasurement.ts +++ b/packages/model/src/standard/elements/ElectricalPowerMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -443,7 +443,7 @@ export const ElectricalPowerMeasurement = Cluster( Event( { - name: "MeasurementPeriodRanges", id: 0x0, access: "R V", conformance: "Ranges", priority: "info", + name: "MeasurementPeriodRanges", id: 0x0, access: "V", conformance: "Ranges", priority: "info", details: "If supported, this event shall be generated at the end of a measurement period. The start and end " + "times for measurement periods shall be determined by the server, and may represent overlapping " + "periods.", @@ -518,7 +518,7 @@ export const ElectricalPowerMeasurement = Cluster( Field({ name: "EndTimestamp", id: 0x4, type: "epoch-s", conformance: "desc", - constraint: "min startTimestamp1", + constraint: "min startTimestamp + 1", details: "This field shall be the timestamp in UTC of the end of the measurement period." + "\n" + "If the server had not yet determined the time in UTC at or before the beginning of the measurement " + @@ -537,7 +537,7 @@ export const ElectricalPowerMeasurement = Cluster( Field({ name: "MaxTimestamp", id: 0x6, type: "epoch-s", conformance: "EndTimestamp", - constraint: "min minTimestamp1", + constraint: "min minTimestamp + 1", details: "This field shall be the most recent timestamp in UTC of the value in the Max field. This field " + "shall be greater than or equal to the value of the StartTimestamp field. This field shall be less " + "than or equal to the value of the EndTimestamp field.", @@ -555,7 +555,7 @@ export const ElectricalPowerMeasurement = Cluster( Field({ name: "EndSystime", id: 0x8, type: "systime-ms", conformance: "desc", - constraint: "min startSystime1", + constraint: "min startSystime + 1", details: "This field shall be the time since boot of the end of the measurement period." + "\n" + "If the server had determined the time in UTC at the end of the measurement period, this field may " + @@ -574,7 +574,7 @@ export const ElectricalPowerMeasurement = Cluster( Field({ name: "MaxSystime", id: 0xa, type: "systime-ms", conformance: "EndSystime", - constraint: "min minSystime1", + constraint: "min minSystime + 1", details: "This field shall be the measurement time since boot of the value in the Max field. This field shall " + "be greater than or equal to the value of the StartSystime field." + "\n" + diff --git a/packages/model/src/standard/elements/ElectricalSensorDT.ts b/packages/model/src/standard/elements/ElectricalSensorDT.ts index 2f6897edbe..b467cd1321 100644 --- a/packages/model/src/standard/elements/ElectricalSensorDT.ts +++ b/packages/model/src/standard/elements/ElectricalSensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/EnergyEvse.ts b/packages/model/src/standard/elements/EnergyEvse.ts index 91dff9c3cd..c7c980ddf5 100644 --- a/packages/model/src/standard/elements/EnergyEvse.ts +++ b/packages/model/src/standard/elements/EnergyEvse.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -31,8 +31,9 @@ export const EnergyEvse = Cluster( "a single wire." + "\n" + "Power Line Communication (PLC) is supported by some EVSEs (e.g. for support of ISO 15118 in Europe " + - "and SAE J2931/4 in NA) and may enable features such as Vehicle to Grid (V2G) or Vehicle to Home " + - "(V2H) that allows for bi-directional charging/discharging of electric vehicles." + + "and SAE J2931/4 in NA) and may enable features such as Vehicle to Grid (V2G) or Vehicle to" + + "\n" + + "Home (V2H) that allows for bi-directional charging/discharging of electric vehicles." + "\n" + "More modern EVSE devices may optionally support ISO 15118-20 in Europe and SAE J2836/3 for NA to " + "support bi-directional charging (Vehicle to Grid - V2G) and Plug and Charge capabilities." + @@ -56,13 +57,13 @@ export const EnergyEvse = Cluster( xref: { document: "cluster", section: "9.3" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.3.4" } }, Field({ - name: "PREF", conformance: "P", constraint: "0", description: "ChargingPreferences", + name: "PREF", conformance: "M", constraint: "0", description: "ChargingPreferences", details: "Since some EVSEs cannot obtain the SoC from the vehicle, some EV charging solutions allow the " + "consumer to specify a daily charging target (for adding energy to the EV’s battery). This feature " + @@ -70,19 +71,19 @@ export const EnergyEvse = Cluster( "daily commute. This range requirement can be converted into a daily energy demand with a target " + "charging completion time." + "\n" + - "The EVSE itself may use this information (or may allow a controller such as an EMS) to compute an" + - "\n" + + "The EVSE itself can use this information (or may allow a controller such as an EMS) to compute an " + "optimized charging schedule." + "\n" + - "An EVSE device may implement the Device Energy Management cluster PFR (Power Forecast Reporting) " + - "and FA (Forecast Adjustment) features. This can help a controller (such as an EMS) to optimize the " + - "EVSE against other ESAs. For example, a solar PV ESA may share its Forecast and allow the EVSE to " + - "know the best time to charge so that any excess solar generation is used to charge the EV." + + "An EVSE device which includes a Device Energy Management device with the Device Energy Management " + + "cluster PFR (Power Forecast Reporting) feature can use the charging preferences information to " + + "produce its power forecast." + "\n" + "EVSE devices that support the Device Energy Management cluster’s FA feature can have their charging " + "profiles set by a controller device such as an EMS. For example, if the EVSE advertises a simple " + "power forecast which allows the EMS to adjust over a wide range of power and time durations, then " + - "the EVSE may allow the EMS to propose a revised optimized forecast (which is the charging profile)." + + "the EVSE may allow the EMS to propose a revised optimized forecast (which is the charging profile). " + + "For example, a solar PV ESA may also share its Forecast, so enabling an EMS to adjust the EVSE " + + "forecast to the best time to charge so that any excess solar generation is used to charge the EV." + "\n" + "See the Device Energy Management Cluster for more details.", @@ -90,7 +91,7 @@ export const EnergyEvse = Cluster( }), Field({ - name: "SOC", conformance: "P", constraint: "1", description: "SoCReporting", + name: "SOC", conformance: "P, O", constraint: "1", description: "SoCReporting", details: "Vehicles and EVSEs which support ISO 15118 may allow the vehicle to report its battery size and " + "state of charge. If the EVSE supports PLC it may have a vehicle connected which optionally supports " + @@ -106,7 +107,7 @@ export const EnergyEvse = Cluster( }), Field({ - name: "PNC", conformance: "P", constraint: "2", description: "PlugAndCharge", + name: "PNC", conformance: "P, O", constraint: "2", description: "PlugAndCharge", details: "If the EVSE supports PLC, it may be able to support the Plug and Charge feature. e.g. this may " + "allow the vehicle ID to be obtained which may allow an energy management system to track energy " + @@ -134,9 +135,17 @@ export const EnergyEvse = Cluster( }), Field({ - name: "V2X", conformance: "P", constraint: "4", description: "V2X", + name: "V2X", conformance: "P, O", constraint: "4", description: "V2X", + details: "If the EVSE can support bi-directional charging, it may be possible to request that the vehicle can " + - "discharge to the home or grid.", + "discharge to the home or grid." + + "\n" + + "The charging and discharging may be controlled by a home Energy Management System (EMS) using the " + + "Device Energy Management cluster of the associated Device Energy Management device. For example, an " + + "EMS may use the PA (Power Adjustment) feature to continually adjust the charge/discharge current " + + "to/from the EV so as to minimise the energy flow from/to the grid as the demand in the home and the " + + "solar supply to the home both fluctuate.", + xref: { document: "cluster", section: "9.3.4.5" } }) ), @@ -152,10 +161,12 @@ export const EnergyEvse = Cluster( "\n" + "NOTE" + "\n" + - "SessionEnding is not really a state but a transition. However, the transition period" + + "SessionEnding is not really a state but a transition. However, the transition period may take a few " + + "seconds and is useful for some clean up purposes." + + "\n" + + "The Fault state is used to indicate that the FaultState attribute is not NoError." + "\n" + - "may take a few seconds and is useful for some clean up purposes. The Fault state is used to " + - "indicate that the FaultState attribute is not NoError.", + "A null value shall indicate that the state cannot be determined.", xref: { document: "cluster", section: "9.3.8.1" } }), @@ -222,8 +233,9 @@ export const EnergyEvse = Cluster( Attribute({ name: "MinimumChargeCurrent", id: 0x6, type: "amperage-mA", access: "R V", conformance: "M", constraint: "min 0", default: 6000, quality: "N", - details: "Indicates the minimum current that can be delivered by the EVSE to the EV. The attribute can be set " + - "using the EnableCharging command.", + details: "Indicates the minimum current that can be delivered by the EVSE to the EV." + + "\n" + + "The attribute can be set using the EnableCharging command.", xref: { document: "cluster", section: "9.3.8.7" } }), @@ -296,7 +308,7 @@ export const EnergyEvse = Cluster( Attribute({ name: "RandomizationDelayWindow", id: 0xa, type: "elapsed-s", access: "RW VM", conformance: "O", - constraint: "0 to 86400", default: 600, quality: "N", + constraint: "max 86400", default: 600, quality: "N", details: "Indicates the size of a random window over which the EVSE will randomize the start of a charging " + "session. This value is in seconds." + @@ -314,33 +326,43 @@ export const EnergyEvse = Cluster( Attribute({ name: "NextChargeStartTime", id: 0x23, type: "epoch-s", access: "R V", conformance: "PREF", default: null, quality: "X", + details: "Indicates the time, in UTC, when the EVSE plans to start the next scheduled charge based on the " + "charging preferences." + "\n" + - "If this is null it indicates that there is no scheduled charging, or that the vehicle is not " + - "plugged in.", + "A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to " + + "use Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that " + + "charging is enabled.", + xref: { document: "cluster", section: "9.3.8.12" } }), Attribute({ name: "NextChargeTargetTime", id: 0x24, type: "epoch-s", access: "R V", conformance: "PREF", default: null, quality: "X", + details: "Indicates the time, in UTC, when the EVSE SHOULD complete the next scheduled charge based on the " + "charging preferences." + "\n" + - "If this is null it indicates that there is no scheduled charging, or that the vehicle is not " + - "plugged in.", + "A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to " + + "use Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that " + + "charging is enabled.", + xref: { document: "cluster", section: "9.3.8.13" } }), Attribute({ name: "NextChargeRequiredEnergy", id: 0x25, type: "energy-mWh", access: "R V", conformance: "PREF", constraint: "min 0", default: null, quality: "X", + details: "Indicates the amount of energy that the EVSE is going to attempt to add to the vehicle in the next " + "charging target." + "\n" + - "If this is null it indicates that there is no scheduled charging, or that the EVSE is using the " + - "TargetSoC method to charge the vehicle.", + "A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to " + + "use Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that " + + "charging is enabled, or that the next ChargingTargetStruct is using the TargetSoC value to charge " + + "the vehicle.", + xref: { document: "cluster", section: "9.3.8.14" } }), @@ -350,8 +372,11 @@ export const EnergyEvse = Cluster( details: "Indicates the target SoC the EVSE is going to attempt to reach when the vehicle is next charged." + "\n" + - "If this is null it indicates that there is no scheduled charging, or that the EVSE cannot obtain " + - "the current State of Charge from the vehicle." + + "A null value indicates that there is no scheduled charging" + + "\n" + + "Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that " + + "charging is enabled, or that the next ChargingTargetStruct is using the AddedEnergy value to charge " + + "the vehicle." + "\n" + "If the SOC feature is not supported, only the values null and 100% are supported.", @@ -387,7 +412,9 @@ export const EnergyEvse = Cluster( "\n" + "AddedRange (km) = 10,000 x 4800 / 1,000,000 = 48 km" + "\n" + - "AddedRange (Miles) = AddedEnergy (Wh) x ApproxEVEfficiency (km/kWh x 1000) x 0.6213" + + "AddedRange (Miles) = AddedEnergy (Wh) x ApproxEVEfficiency (km/kWh x 1000) x" + + "\n" + + "0.6213" + "\n" + "= 29.82 Miles", @@ -430,17 +457,17 @@ export const EnergyEvse = Cluster( }), Attribute({ name: "SessionDuration", id: 0x41, type: "elapsed-s", access: "R V", conformance: "M", - default: null, quality: "X N", + default: null, quality: "X N Q", xref: { document: "cluster", section: "9.3.8" } }), Attribute({ name: "SessionEnergyCharged", id: 0x42, type: "energy-mWh", access: "R V", conformance: "M", - constraint: "min 0", default: null, quality: "X N", + constraint: "min 0", default: null, quality: "X N Q", xref: { document: "cluster", section: "9.3.8" } }), Attribute({ name: "SessionEnergyDischarged", id: 0x43, type: "energy-mWh", access: "R V", conformance: "V2X", - constraint: "min 0", default: null, quality: "X N", + constraint: "min 0", default: null, quality: "X N Q", xref: { document: "cluster", section: "9.3.8" } }), @@ -487,7 +514,7 @@ export const EnergyEvse = Cluster( name: "SessionEnergyCharged", id: 0x3, type: "energy-mWh", conformance: "M", constraint: "min 0", details: "This field shall indicate the total amount of energy transferred from the EVSE to the EV during the " + - "session. This value shall always be positive." + + "session." + "\n" + "Note that if bi-directional charging occurs during the session, then this value shall only include " + "the sum of energy transferred from the EVSE to the EV, and shall NOT be a net value of charging and " + @@ -501,7 +528,7 @@ export const EnergyEvse = Cluster( constraint: "min 0", details: "This field shall indicate the total amount of energy transferred from the EV to the EVSE during the " + - "session. This value shall always be positive." + + "session." + "\n" + "Note that if bi-directional discharging occurs during the session, then this value shall only " + "include the sum of energy transferred from the EV to the EVSE, and shall NOT be a net value of " + @@ -514,9 +541,12 @@ export const EnergyEvse = Cluster( Event( { name: "EnergyTransferStarted", id: 0x2, access: "V", conformance: "M", priority: "info", - details: "This event shall be generated when the EV starts charging or discharging.", + details: "This event shall be generated whenever the EV starts charging or discharging, except when an EV has " + + "switched between charging and discharging under the control of the PowerAdjustment feature of the " + + "Device Energy Management cluster of the associated Device Energy Management device.", xref: { document: "cluster", section: "9.3.10.3" } }, + Field({ name: "SessionId", id: 0x0, type: "uint32", conformance: "M", details: "This field shall indicate the value of the SessionID attribute at the time the event was generated.", @@ -531,24 +561,37 @@ export const EnergyEvse = Cluster( Field({ name: "MaximumCurrent", id: 0x2, type: "amperage-mA", conformance: "M", constraint: "min 0", - details: "This field shall indicate the value of the maximum charging or discharging current at the time the " + - "event was generated." + + details: "This field shall indicate the value of the maximum charging current at the time the event was " + + "generated." + "\n" + - "This field is signed. A positive value indicates the EV has been enabled for charging and the value " + - "is taken directly from the MaximumChargeCurrent attribute." + - "\n" + - "A negative value indicates that the EV has been enabled for discharging and the value can be taken " + - "from the MaximumDischargeCurrent attribute with its sign inverted. i.e. if the " + - "MaximumDischargeCurrent was 32000mA, this would be represented here as -32000mA.", + "A non-zero value indicates that the EV has been enabled for charging and the value is taken " + + "directly from the MaximumChargeCurrent attribute. A zero value indicates that the EV has not been " + + "enabled for charging.", xref: { document: "cluster", section: "9.3.10.3.3" } + }), + + Field({ + name: "MaximumDischargeCurrent", id: 0x3, type: "amperage-mA", conformance: "V2X", + constraint: "min 0", + + details: "This field shall indicate the value of the maximum discharging current at the time the event was " + + "generated." + + "\n" + + "A non-zero value indicates that the EV has been enabled for discharging and the value is taken " + + "directly from the MaximumDischargeCurrent attribute. A zero value indicates that the EV has not " + + "been enabled for discharging.", + + xref: { document: "cluster", section: "9.3.10.3.4" } }) ), Event( { name: "EnergyTransferStopped", id: 0x3, access: "V", conformance: "M", priority: "info", - details: "This event shall be generated when the EV stops charging or discharging.", + details: "This event shall be generated whenever the EV stops charging or discharging, except when an EV has " + + "switched between charging and discharging under the control of the PowerAdjustment feature of the " + + "Device Energy Management cluster of the associated Device Energy Management device.", xref: { document: "cluster", section: "9.3.10.4" } }, @@ -569,7 +612,20 @@ export const EnergyEvse = Cluster( details: "This field shall indicate the reason why the energy transferred stopped.", xref: { document: "cluster", section: "9.3.10.4.3" } }), - Field({ name: "EnergyTransferred", id: 0x4, type: "energy-mWh", conformance: "M", constraint: "min 0" }) + + Field({ + name: "EnergyTransferred", id: 0x4, type: "energy-mWh", conformance: "M", constraint: "min 0", + details: "This field shall indicate the amount of energy transferred from the EVSE to the EV since the " + + "previous EnergyTransferStarted event, in mWh.", + xref: { document: "cluster", section: "9.3.10.4.4" } + }), + + Field({ + name: "EnergyDischarged", id: 0x5, type: "energy-mWh", conformance: "V2X", constraint: "min 0", + details: "This field shall indicate the amount of energy transferred from the EV to the EVSE since the " + + "previous EnergyTransferStarted event, in mWh.", + xref: { document: "cluster", section: "9.3.10.4.5" } + }) ), Event( @@ -642,7 +698,8 @@ export const EnergyEvse = Cluster( { name: "EnableCharging", id: 0x2, access: "O T", conformance: "M", direction: "request", response: "status", - details: "Allows a client to enable the EVSE to charge an EV.", + details: "This command allows a client to enable the EVSE to charge an EV, and to provide or update the " + + "maximum and minimum charge current.", xref: { document: "cluster", section: "9.3.9.2" } }, @@ -674,10 +731,8 @@ export const EnergyEvse = Cluster( "\n" + "The value of the this field shall be stored by the EVSE to determine the value of " + "MaximumChargeCurrent attribute. For example, if the UserMaximumChargeCurrent attribute is adjusted " + - "below then" + - "\n" + - "this value, and then later adjusted above this value, the resulting MaximumChargeCurrent attribute " + - "will be limited to this value.", + "below then this value, and then later adjusted above this value, the resulting MaximumChargeCurrent " + + "attribute will be limited to this value.", xref: { document: "cluster", section: "9.3.9.2.3" } }) @@ -687,7 +742,8 @@ export const EnergyEvse = Cluster( { name: "EnableDischarging", id: 0x3, access: "O T", conformance: "V2X", direction: "request", response: "status", - details: "Allows a client to enable the EVSE to discharge an EV.", + details: "Upon receipt, this shall allow a client to enable the discharge of an EV, and to provide or update " + + "the maximum discharge current.", xref: { document: "cluster", section: "9.3.9.3" } }, @@ -696,22 +752,18 @@ export const EnergyEvse = Cluster( quality: "X", details: "This field shall indicate the expiry time, in UTC, when discharging will be automatically disabled." + "\n" + - "A value in the past in this field shall disable the EVSE whereas a null value shall enable it " + - "permanently.", + "A value in the past in this field shall disable the EVSE discharging whereas a null value shall " + + "enable EVSE discharging permanently.", xref: { document: "cluster", section: "9.3.9.3.1" } }), Field({ name: "MaximumDischargeCurrent", id: 0x1, type: "amperage-mA", conformance: "M", constraint: "min 0", - details: "This field shall indicate the maximum current that can be received by the EVSE from the EV. The " + "EVSE current limit can be advertised to an EV in 0.6A steps. The value of the " + "MaximumDischargeCurrent attribute shall be stored and persisted across reboots by the EVSE to the " + - "value of this" + - "\n" + - "field.", - + "value of this field.", xref: { document: "cluster", section: "9.3.9.3.2" } }) ), @@ -778,7 +830,18 @@ export const EnergyEvse = Cluster( ), Datatype( - { name: "StateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.1" } }, + { name: "TargetDayOfWeekBitmap", type: "map8", xref: { document: "cluster", section: "9.3.7.1" } }, + Field({ name: "Sunday", constraint: "0", description: "Sunday" }), + Field({ name: "Monday", constraint: "1", description: "Monday" }), + Field({ name: "Tuesday", constraint: "2", description: "Tuesday" }), + Field({ name: "Wednesday", constraint: "3", description: "Wednesday" }), + Field({ name: "Thursday", constraint: "4", description: "Thursday" }), + Field({ name: "Friday", constraint: "5", description: "Friday" }), + Field({ name: "Saturday", constraint: "6", description: "Saturday" }) + ), + + Datatype( + { name: "StateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.2" } }, Field({ name: "NotPluggedIn", id: 0x0, conformance: "M", description: "The EV is not plugged in." }), Field({ name: "PluggedInNoDemand", id: 0x1, conformance: "M", @@ -804,7 +867,7 @@ export const EnergyEvse = Cluster( ), Datatype( - { name: "SupplyStateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.2" } }, + { name: "SupplyStateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.3" } }, Field({ name: "Disabled", id: 0x0, conformance: "M", description: "The EV is not currently allowed to charge or discharge" @@ -820,12 +883,16 @@ export const EnergyEvse = Cluster( }), Field({ name: "DisabledDiagnostics", id: 0x4, conformance: "M", - description: "The EV is not currently allowed to charge or discharge due to Diagnostics Mode." + description: "The EV is not currently allowed to charge or discharge due to self- diagnostics mode." + }), + Field({ + name: "Enabled", id: 0x5, conformance: "[V2X]", + description: "The EV is currently allowed to charge and discharge" }) ), Datatype( - { name: "FaultStateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.3" } }, + { name: "FaultStateEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.4" } }, Field({ name: "NoError", id: 0x0, conformance: "M", description: "The EVSE is not in an error state." }), Field({ name: "MeterFailure", id: 0x1, conformance: "M", @@ -876,23 +943,12 @@ export const EnergyEvse = Cluster( ), Datatype( - { name: "EnergyTransferStoppedReasonEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.4" } }, + { name: "EnergyTransferStoppedReasonEnum", type: "enum8", xref: { document: "cluster", section: "9.3.7.5" } }, Field({ name: "EvStopped", id: 0x0, conformance: "M", description: "The EV decided to stop" }), Field({ name: "EvseStopped", id: 0x1, conformance: "M", description: "The EVSE decided to stop" }), Field({ name: "Other", id: 0x2, conformance: "M", description: "An other unknown reason" }) ), - Datatype( - { name: "TargetDayOfWeekBitmap", type: "map8", xref: { document: "cluster", section: "9.3.7.5" } }, - Field({ name: "Sunday", constraint: "0", description: "Sunday" }), - Field({ name: "Monday", constraint: "1", description: "Monday" }), - Field({ name: "Tuesday", constraint: "2", description: "Tuesday" }), - Field({ name: "Wednesday", constraint: "3", description: "Wednesday" }), - Field({ name: "Thursday", constraint: "4", description: "Thursday" }), - Field({ name: "Friday", constraint: "5", description: "Friday" }), - Field({ name: "Saturday", constraint: "6", description: "Saturday" }) - ), - Datatype( { name: "ChargingTargetStruct", type: "struct", @@ -916,7 +972,7 @@ export const EnergyEvse = Cluster( Field({ name: "TargetTimeMinutesPastMidnight", id: 0x0, type: "uint16", conformance: "M", - constraint: "0 to 1439", default: 0, + constraint: "max 1439", default: 0, details: "This field shall indicate the desired charging completion time of the associated day. The time will " + "be represented by a 16 bits unsigned integer to designate the minutes since midnight. For example, " + @@ -951,7 +1007,7 @@ export const EnergyEvse = Cluster( details: "This field represents the target SoC that the vehicle should be charged to before the " + "TargetTimeMinutesPastMidnight." + "\n" + - "If the EVSE can obtain the SoC of the vehicle:" + + "If the EVSE supports the SOC feature and can obtain the SoC of the vehicle:" + "\n" + " • the TargetSoC field shall take precedence over the AddedEnergy field." + "\n" + @@ -961,19 +1017,20 @@ export const EnergyEvse = Cluster( " • if the TargetSoC value is set to 100% then the EVSE SHOULD continue to charge the vehicle until " + " the vehicle decides to stop charging." + "\n" + - "If the EVSE cannot obtain the SoC of the vehicle:" + + "If the EVSE does not support the SOC feature or cannot obtain the SoC of the vehicle:" + "\n" + - " • in this case, the AddedEnergy field shall take precedence over the TargetSoC field, and the " + - " TargetSoC field may only take the values null or 100%." + + " • the AddedEnergy field shall take precedence over the TargetSoC field, and if the EVSE does not " + + " support the SOC feature then the TargetSoC field may only take the values null or 100%." + "\n" + - " • if the AddedEnergy field has not been provided, the EVSE SHOULD assume the vehicle is empty and " + - " charge until the vehicle stops demanding a charge.", + " • if the AddedEnergy field has not been provided, the EVSE SHOULD assume the vehicle is empty" + + "\n" + + "and charge until the vehicle stops demanding a charge.", xref: { document: "cluster", section: "9.3.7.6.2" } }), Field({ - name: "AddedEnergy", id: 0x2, type: "energy-mWh", conformance: "O.a+", constraint: "min 0", + name: "AddedEnergy", id: 0x2, type: "energy-mWh", conformance: "[SOC], O.a+", constraint: "min 0", default: 0, details: "This field represents the amount of energy that the user would like to have added to the vehicle " + @@ -991,7 +1048,7 @@ export const EnergyEvse = Cluster( "\n" + "NOTE" + "\n" + - "If the EVSE can obtain the Battery Capacity of the vehicle, it SHOULD not limit this AddedEnergy " + + "If the EVSE can obtain the Battery Capacity of the vehicle, it SHOULD NOT limit this AddedEnergy " + "value to the Battery Capacity of the vehicle, since the EV may also require energy for heating and " + "cooling of the battery during charging, or for heating or cooling the cabin.", @@ -1005,9 +1062,22 @@ export const EnergyEvse = Cluster( details: "This represents a set of user specified charging targets for an EV for a set of specified days.", xref: { document: "cluster", section: "9.3.7.7" } }, - Field({ name: "DayOfWeekForSequence", id: 0x0, type: "TargetDayOfWeekBitmap", access: "M", constraint: "desc" }), + + Field({ + name: "DayOfWeekForSequence", id: 0x0, type: "TargetDayOfWeekBitmap", conformance: "M", + details: "This field shall indicate the days of the week that the charging targets SHOULD be associated to. " + + "This field is a bitmap and therefore the associated targets could be applied to multiple days.", + xref: { document: "cluster", section: "9.3.7.8" } + }), + Field( - { name: "ChargingTargets", id: 0x1, type: "list", access: "M", constraint: "max 10" }, + { + name: "ChargingTargets", id: 0x1, type: "list", conformance: "M", constraint: "max 10", + details: "This field shall indicate a list of up to 10 charging targets for each of the associated days of " + + "the week.", + xref: { document: "cluster", section: "9.3.7.9" } + }, + Field({ name: "entry", type: "ChargingTargetStruct" }) ) ) diff --git a/packages/model/src/standard/elements/EnergyEvseDT.ts b/packages/model/src/standard/elements/EnergyEvseDT.ts new file mode 100644 index 0000000000..f59bc8700a --- /dev/null +++ b/packages/model/src/standard/elements/EnergyEvseDT.ts @@ -0,0 +1,43 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const EnergyEvseDt = DeviceType( + { + name: "EnergyEvse", id: 0x50c, category: "Energy", classification: "simple", + details: "An EVSE (Electric Vehicle Supply Equipment) is a device that allows an EV (Electric Vehicle) to be " + + "connected to the mains electricity supply to allow it to be charged (or discharged in case of " + + "Vehicle to Grid / Vehicle to Home applications).", + xref: { document: "device", section: "14.1" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 1292, revision: 2 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.1.6" } + }), + Requirement({ + name: "EnergyEvse", id: 0x99, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.1.6" } + }), + Requirement({ + name: "EnergyEvseMode", id: 0x9d, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.1.6" } + }), + Requirement({ + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.1.6" } + }) +); + +MatterDefinition.children.push(EnergyEvseDt); diff --git a/packages/model/src/standard/elements/EnergyEvseMode.ts b/packages/model/src/standard/elements/EnergyEvseMode.ts index e98a05c7ef..6d409b13cc 100644 --- a/packages/model/src/standard/elements/EnergyEvseMode.ts +++ b/packages/model/src/standard/elements/EnergyEvseMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,42 +10,107 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + DatatypeElement as Datatype } from "../../elements/index.js"; export const EnergyEvseMode = Cluster( { name: "EnergyEvseMode", id: 0x9d, type: "ModeBase", classification: "application", pics: "EEVSEM", - details: "This cluster is derived from the Mode Base cluster which also defines a namespace for the operation " + - "of EVSE devices.", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for EVSE devices.", xref: { document: "cluster", section: "9.4" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.4.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + + details: "At least one entry in the SupportedModes attribute shall include the Manual mode tag in the " + + "ModeTags field list." + + "\n" + + "Modes with entries in the SupportedModes attribute which contain multiple mode tags permitting" + + "\n" + + "charging or discharging under different conditions shall permit the charging or discharging to " + + "occur if any of the conditions are satisfied." + + "\n" + + "Modes shall NOT have both the Manual tag and the TimeOfUse or SolarCharging tags defined in the " + + "SupportedModes attribute.", + + xref: { document: "cluster", section: "9.4.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "9.4.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "9.4.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "9.4.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "9.4.5.1" } + }), Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "9.4.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "9.4.7.1" } }), Field({ name: "Manual", id: 0x4000, - details: "While in this mode, the EVSE needs to be sent an EnableEvseCharging or EnableEvseDischarging " + - "command to make the EVSE start charging or discharging.", - xref: { document: "cluster", section: "9.4.4.1.1" } + details: "While in modes with this tag, and once enabled with the EnableCharging command, the EVSE will " + + "permit charging based on demand from the EV.", + xref: { document: "cluster", section: "9.4.7.1.1" } }), Field({ name: "TimeOfUse", id: 0x4001, - details: "While in this mode, the EVSE will attempt to automatically start charging based on the user’s " + - "charging targets and a Time of Use tariff to charge at the cheapest times of the day.", - xref: { document: "cluster", section: "9.4.4.1.2" } + details: "While in modes with this tag, and once enabled with the EnableCharging command, the EVSE will " + + "attempt to automatically start charging based on the user’s charging targets (for example, set " + + "based on a Time of Use tariff to charge at the cheapest times of the day).", + xref: { document: "cluster", section: "9.4.7.1.2" } }), Field({ name: "SolarCharging", id: 0x4002, - details: "While in this mode, the EVSE will attempt to automatically start charging based on available excess " + - "solar PV generation, limiting the charging power to avoid imported energy from the grid.", - xref: { document: "cluster", section: "9.4.4.1.3" } + details: "While in modes with this tag, and once enabled with the EnableCharging, the EVSE will attempt to" + + "\n" + + "automatically start charging based on available excess solar PV generation, limiting the charging " + + "power to avoid importing energy from the grid.", + xref: { document: "cluster", section: "9.4.7.1.3" } + }), + + Field({ + name: "V2X", id: 0x4003, + + details: "While in modes with this tag, and once enabled with the EnableDischarging command, the EVSE will " + + "permit discharging based on the current charge state of the EV, and its control from an associated " + + "Device Energy Management cluster." + + "\n" + + "NOTE" + + "\n" + + "being in a mode with this tag set or not does not affect the handling of the EnableDischarging " + + "command by the Energy EVSE cluster, but once enabled, only modes with this tag enable the " + + "discharging to actually occur.", + + xref: { document: "cluster", section: "9.4.7.1.4" } }) ) ); diff --git a/packages/model/src/standard/elements/EnergyPreference.ts b/packages/model/src/standard/elements/EnergyPreference.ts index 0bd0b1e033..ae187790df 100644 --- a/packages/model/src/standard/elements/EnergyPreference.ts +++ b/packages/model/src/standard/elements/EnergyPreference.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,19 +20,19 @@ export const EnergyPreference = Cluster( details: "This cluster provides an interface to specify preferences for how devices should consume energy." + "\n" + "NOTE Support for Energy Preference cluster is provisional.", - xref: { document: "cluster", section: "9.5" } + xref: { document: "cluster", section: "9.7" } }, Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), Attribute( - { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.5.4" } }, + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.7.4" } }, Field({ name: "BALA", conformance: "O.a+", constraint: "0", description: "EnergyBalance", details: "This feature allows a user to select from a list of energy balances with associated descriptions of " + "which strategies a device will use to target the specified balance.", - xref: { document: "cluster", section: "9.5.4.1" } + xref: { document: "cluster", section: "9.7.4.1" } }), Field({ @@ -40,7 +40,7 @@ export const EnergyPreference = Cluster( details: "This feature allows the user to select a condition or set of conditions which will cause the device " + "to switch to a mode using less power. For example, a device might provide a scale of durations that " + "must elapse without user interaction before it goes to sleep.", - xref: { document: "cluster", section: "9.5.4.2" } + xref: { document: "cluster", section: "9.7.4.2" } }) ), @@ -49,13 +49,12 @@ export const EnergyPreference = Cluster( name: "EnergyBalances", id: 0x0, type: "list", access: "R V", conformance: "BALA", constraint: "2 to 10", quality: "F", - details: "Indicates a list of BalanceStructs, each representing a step along a linear scale" + - "\n" + - "of relative priorities. A Step field with a value of zero shall indicate that the device SHOULD " + - "entirely favor the priority specified by the first element in EnergyPriorities; whereas a Step " + - "field with a value of 100 shall indicate that the device SHOULD entirely favor the priority " + - "specified by the second element in EnergyPriorities. The midpoint value of 50 shall indicate an " + - "even split between the two priorities." + + details: "Indicates a list of BalanceStructs, each representing a step along a linear scale of relative " + + "priorities. A Step field with a value of zero shall indicate that the device SHOULD entirely favor " + + "the priority specified by the first element in EnergyPriorities; whereas a Step field with a value " + + "of 100 shall indicate that the device SHOULD entirely favor the priority specified by the second " + + "element in EnergyPriorities. The midpoint value of 50 shall indicate an even split between the two " + + "priorities." + "\n" + "This shall contain at least two BalanceStructs." + "\n" + @@ -65,7 +64,7 @@ export const EnergyPreference = Cluster( "The first BalanceStruct shall have a Step value of zero, and the last BalanceStruct shall have a " + "Step value of 100.", - xref: { document: "cluster", section: "9.5.6.1" } + xref: { document: "cluster", section: "9.7.6.1" } }, Field({ name: "entry", type: "BalanceStruct" }) @@ -95,7 +94,7 @@ export const EnergyPreference = Cluster( " the last element in EnergyPriorities, the new value of CurrentEnergyBalance shall be the index " + " of the last element in the updated value of EnergyBalances.", - xref: { document: "cluster", section: "9.5.6.2" } + xref: { document: "cluster", section: "9.7.6.2" } }), Attribute( @@ -110,7 +109,7 @@ export const EnergyPreference = Cluster( "If the value of EnergyPriorities changes after an update to represent a new balance between " + "priorities, the value of the CurrentEnergyBalance attribute shall be set to its default.", - xref: { document: "cluster", section: "9.5.6.3" } + xref: { document: "cluster", section: "9.7.6.3" } }, Field({ name: "entry", type: "EnergyPriorityEnum" }) @@ -120,16 +119,12 @@ export const EnergyPreference = Cluster( { name: "LowPowerModeSensitivities", id: 0x3, type: "list", access: "R V", conformance: "LPMS", constraint: "2 to 10", quality: "F", - details: "Indicates a list of BalanceStructs, each representing a condition or set of conditions for the " + - "device to enter a low power mode." + - "\n" + - "This shall contain at least two BalanceStructs." + + "device to enter a low power mode. This shall contain at least two BalanceStructs." + "\n" + "Each BalanceStruct shall have a Step field larger than the Step field on the previous BalanceStruct " + "in the list.", - - xref: { document: "cluster", section: "9.5.6.4" } + xref: { document: "cluster", section: "9.7.6.4" } }, Field({ name: "entry", type: "BalanceStruct" }) @@ -150,49 +145,51 @@ export const EnergyPreference = Cluster( "value of the LowPowerModeSensitivity attribute to the index which the manufacturer specifies most " + "closely matches the previous value.", - xref: { document: "cluster", section: "9.5.6.5" } + xref: { document: "cluster", section: "9.7.6.5" } }), Datatype( - { name: "EnergyPriorityEnum", type: "enum8", xref: { document: "cluster", section: "9.5.5.1" } }, + { name: "EnergyPriorityEnum", type: "enum8", xref: { document: "cluster", section: "9.7.5.1" } }, Field({ - name: "Comfort", id: 0x0, conformance: "M", + name: "Comfort", id: 0x0, conformance: "M", description: "User comfort", details: "This value shall emphasize user comfort; e.g. local temperature for a thermostat.", - xref: { document: "cluster", section: "9.5.5.1.1" } + xref: { document: "cluster", section: "9.7.5.1.1" } }), Field({ - name: "Speed", id: 0x1, conformance: "M", + name: "Speed", id: 0x1, conformance: "M", description: "Speed of operation", details: "This value shall emphasize how quickly a device accomplishes its targeted use; e.g. how quickly a " + "robot vacuum completes a cleaning cycle.", - xref: { document: "cluster", section: "9.5.5.1.2" } + xref: { document: "cluster", section: "9.7.5.1.2" } }), Field({ name: "Efficiency", id: 0x2, conformance: "M", + description: "Amount of Energy consumed by the device", details: "This value shall emphasize how much energy a device uses; e.g. electricity usage for a Pump.", - xref: { document: "cluster", section: "9.5.5.1.3" } + xref: { document: "cluster", section: "9.7.5.1.3" } }), - Field({ name: "WaterConsumption", id: 0x3, conformance: "M" }) + + Field({ name: "WaterConsumption", id: 0x3, conformance: "M", description: "Amount of water consumed by the device" }) ), Datatype( { name: "BalanceStruct", type: "struct", details: "This represents a step along a scale of preferences.", - xref: { document: "cluster", section: "9.5.5.2" } + xref: { document: "cluster", section: "9.7.5.2" } }, Field({ name: "Step", id: 0x0, type: "percent", conformance: "M", quality: "F", details: "This field shall indicate the relative value of this step.", - xref: { document: "cluster", section: "9.5.5.2.1" } + xref: { document: "cluster", section: "9.7.5.2.1" } }), Field({ name: "Label", id: 0x1, type: "string", conformance: "O", constraint: "max 64", quality: "F", details: "This field shall indicate an optional string explaining which actions a device might take at the " + "given step value.", - xref: { document: "cluster", section: "9.5.5.2.2" } + xref: { document: "cluster", section: "9.7.5.2.2" } }) ) ); diff --git a/packages/model/src/standard/elements/EthernetNetworkDiagnostics.ts b/packages/model/src/standard/elements/EthernetNetworkDiagnostics.ts index 0205202dbd..29146d4c8f 100644 --- a/packages/model/src/standard/elements/EthernetNetworkDiagnostics.ts +++ b/packages/model/src/standard/elements/EthernetNetworkDiagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -81,8 +81,7 @@ export const EthernetNetworkDiagnostics = Cluster( name: "TxErrCount", id: 0x4, type: "uint64", access: "R V", conformance: "ERRCNT", default: 0, quality: "C", details: "The TxErrCount attribute shall indicate the number of failed packet transmissions that have " + - "occurred on the ethernet network interface. The TxErrCount attribute shall be reset to 0 upon a" + - "\n" + + "occurred on the ethernet network interface. The TxErrCount attribute shall be reset to 0 upon a " + "reboot of the Node.", xref: { document: "core", section: "11.16.6.5" } }), diff --git a/packages/model/src/standard/elements/EventList.ts b/packages/model/src/standard/elements/EventList.ts index 371fc3a549..ee10c1ca83 100644 --- a/packages/model/src/standard/elements/EventList.ts +++ b/packages/model/src/standard/elements/EventList.ts @@ -1,24 +1,15 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MatterDefinition } from "../MatterDefinition.js"; -import { AttributeElement as Attribute, FieldElement as Field } from "../../elements/index.js"; +import { AttributeElement as Attribute } from "../../elements/index.js"; export const EventList = Attribute( - { - name: "EventList", id: 0xfffa, type: "list", access: "R V", conformance: "P, M", isSeed: true, - quality: "F", - details: "Each instance of a cluster shall support this attribute. This attribute shall be a list of the " + - "event IDs of the events supported by the cluster instance.", - xref: { document: "core", section: "7.13.6" } - }, - - Field({ name: "entry", type: "event-id" }) + { name: "EventList", id: 0xfffa, conformance: "D", isSeed: true, xref: { document: "core", section: "7.13" } } ); - MatterDefinition.children.push(EventList); diff --git a/packages/model/src/standard/elements/ExtendedColorLightDT.ts b/packages/model/src/standard/elements/ExtendedColorLightDT.ts index 824f2ad167..594b69f91b 100644 --- a/packages/model/src/standard/elements/ExtendedColorLightDT.ts +++ b/packages/model/src/standard/elements/ExtendedColorLightDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ExtractorHoodDT.ts b/packages/model/src/standard/elements/ExtractorHoodDT.ts index 9e94807ff4..e9d8755f6e 100644 --- a/packages/model/src/standard/elements/ExtractorHoodDT.ts +++ b/packages/model/src/standard/elements/ExtractorHoodDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/FabricIndex.ts b/packages/model/src/standard/elements/FabricIndex.ts index 4eff3bbb67..83ef8d0d46 100644 --- a/packages/model/src/standard/elements/FabricIndex.ts +++ b/packages/model/src/standard/elements/FabricIndex.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -21,7 +21,7 @@ export const FabricIndex = Field({ "after receipt of the interaction. For a read interaction this field shall be included in all " + "reported data that is defined as fabric-scoped.", - xref: { document: "core", section: "7.13.7" } + xref: { document: "core", section: "7.13.6" } }); MatterDefinition.children.push(FabricIndex); diff --git a/packages/model/src/standard/elements/FanControl.ts b/packages/model/src/standard/elements/FanControl.ts index ac7f85bfa8..b65a49f779 100644 --- a/packages/model/src/standard/elements/FanControl.ts +++ b/packages/model/src/standard/elements/FanControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -37,7 +37,7 @@ export const FanControl = Cluster( "The MultiSpeed feature includes new attributes that support a running fan speed value from 0 to " + "SpeedMax, which has a maximum of 100." + "\n" + - "See Speed Rules for more details.", + "See Section 4.4.6.6.1 for more details.", xref: { document: "cluster", section: "4.4.4.1" } }), @@ -53,8 +53,8 @@ export const FanControl = Cluster( ), Attribute({ - name: "FanMode", id: 0x0, type: "FanModeEnum", access: "RW VO", conformance: "M", - constraint: "0 to 6", default: 0, quality: "N", + name: "FanMode", id: 0x0, type: "FanModeEnum", access: "RW VO", conformance: "M", default: 0, + quality: "N", details: "Indicates the current speed mode of the fan. This attribute may be written by the client to request " + "a different fan mode. A server shall return INVALID_IN_STATE to indicate that the fan is not in a " + @@ -66,8 +66,8 @@ export const FanControl = Cluster( "This attribute shall be set to one of the values in FanModeEnum." + "\n" + "When the FanMode attribute is successfully written to, the PercentSetting and SpeedSetting (if " + - "present) attributes shall be set to appropriate values, as defined by the Percent Rules and Speed " + - "Rules respectively, unless otherwise specified below." + + "present) attributes shall be set to appropriate values, as defined by the Section 4.4.6.3.1 and " + + "Section 4.4.6.6.1 respectively, unless otherwise specified below." + "\n" + "When the FanMode attribute is set to any given mode, the PercentCurrent and SpeedCurrent (if " + "present) shall indicate the actual currently operating fan speed, unless otherwise specified below.", @@ -77,14 +77,14 @@ export const FanControl = Cluster( Attribute({ name: "FanModeSequence", id: 0x1, type: "FanModeSequenceEnum", access: "R V", conformance: "M", - constraint: "0 to 5", quality: "F", + quality: "F", details: "This attribute indicates the fan speed ranges that shall be supported.", xref: { document: "cluster", section: "4.4.6.2" } }), Attribute({ name: "PercentSetting", id: 0x2, type: "percent", access: "RW VO", conformance: "M", - constraint: "0 to 100", default: 0, quality: "X", + constraint: "max 100", default: 0, quality: "X", details: "Indicates the speed setting for the fan. This attribute may be written by the client to indicate a " + "new fan speed. If the client writes null to this attribute, the attribute value shall NOT change. A " + @@ -98,11 +98,11 @@ export const FanControl = Cluster( Attribute({ name: "PercentCurrent", id: 0x3, type: "percent", access: "R V", conformance: "M", - constraint: "0 to 100", + constraint: "max 100", details: "Indicates the actual currently operating fan speed, or zero to indicate that the fan is off. There " + "may be a temporary mismatch between the value of this attribute and the value of the PercentSetting " + "attribute due to other system requirements that would not allow the fan to operate at the requested " + - "setting. See Percent Rules for more details.", + "setting. See Section 4.4.6.3.1 for more details.", xref: { document: "cluster", section: "4.4.6.4" } }), @@ -116,7 +116,7 @@ export const FanControl = Cluster( Attribute({ name: "SpeedSetting", id: 0x5, type: "uint8", access: "RW VO", conformance: "SPD", - constraint: "0 to speedMax", default: 0, quality: "X", + constraint: "max speedMax", default: 0, quality: "X", details: "Indicates the speed setting for the fan. This attribute may be written by the client to indicate a " + "new fan speed. If the client writes null to this attribute, the attribute value shall NOT change. A " + @@ -124,14 +124,14 @@ export const FanControl = Cluster( "SpeedSetting can be changed to the requested value." + "\n" + "If this is successfully written to 0, the server shall set the FanMode attribute value to Off. " + - "Please see the Speed Rules for details on other values.", + "Please see the Section 4.4.6.6.1 for details on other values.", xref: { document: "cluster", section: "4.4.6.6" } }), Attribute({ name: "SpeedCurrent", id: 0x6, type: "uint8", access: "R V", conformance: "SPD", - constraint: "0 to speedMax", quality: "P", + constraint: "max speedMax", quality: "P", details: "Indicates the actual currently operating fan speed, or zero to indicate that the fan is off. There " + "may be a temporary mismatch between the value of this attribute and the value of the SpeedSetting " + "attribute due to other system requirements that would not allow the fan to operate at the requested " + diff --git a/packages/model/src/standard/elements/FanDT.ts b/packages/model/src/standard/elements/FanDT.ts index d0d1e47109..25b1c83b46 100644 --- a/packages/model/src/standard/elements/FanDT.ts +++ b/packages/model/src/standard/elements/FanDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,7 @@ export const FanDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 43, revision: 2 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 43, revision: 3 } ], element: "attribute" }) ), Requirement({ name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", @@ -29,6 +29,10 @@ export const FanDt = DeviceType( name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", xref: { document: "device", section: "9.2.5" } }), + Requirement({ + name: "OnOff", id: 0x6, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "9.2.5" } + }), Requirement( { diff --git a/packages/model/src/standard/elements/FeatureMap.ts b/packages/model/src/standard/elements/FeatureMap.ts index 556436ba43..2237af62c5 100644 --- a/packages/model/src/standard/elements/FeatureMap.ts +++ b/packages/model/src/standard/elements/FeatureMap.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,9 @@ export const FeatureMap = Attribute({ "features. A cluster feature is a set of cluster elements that are mandatory or optional for a " + "defined feature of the cluster. If a cluster feature is supported by the cluster instance, then the " + "corresponding bit shall be set to 1, otherwise the bit shall be set to 0 (zero). All undefined bits " + - "in this attribute shall be set to 0 (zero)." + + "in" + + "\n" + + "this attribute shall be set to 0 (zero)." + "\n" + "The set of cluster elements that are designated as mandatory (M) are implicitly part of the " + "mandatory cluster feature set, and do not have a bit in the FeatureMap attribute." + @@ -35,8 +37,8 @@ export const FeatureMap = Attribute({ "\n" + "Feature sets are revision controlled as part of a cluster using the ClusterRevision attribute. The " + "cluster specification is the independent element that is revision controlled. A remote application " + - "reading the FeatureMap Attribute and ClusterRevision Attribute will then know exactly what features " + - "are supported in the cluster instance." + + "reading the FeatureMap and ClusterRevision Attribute will then know exactly what features are " + + "supported in the cluster instance." + "\n" + "Each feature set shall be well defined within the cluster specification. Each feature shall be " + "mapped to a short capitalized code name for the feature set to be referenced as a conformance tag " + diff --git a/packages/model/src/standard/elements/FixedLabel.ts b/packages/model/src/standard/elements/FixedLabel.ts index f5eba04667..e8786bab7e 100644 --- a/packages/model/src/standard/elements/FixedLabel.ts +++ b/packages/model/src/standard/elements/FixedLabel.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,8 +17,10 @@ export const FixedLabel = Cluster( { name: "FixedLabel", id: 0x40, type: "Label", classification: "endpoint", pics: "FLABEL", - details: "This cluster provides a feature for the device to tag an endpoint with zero or more read only " + - "labels. Examples:" + + details: "This cluster is derived from the Label cluster and provides a feature for the device to tag an " + + "endpoint with zero or more read-only labels." + + "\n" + + "Examples:" + "\n" + " • A bridge can use this to indicate grouping of bridged devices. For example: All bridged devices " + " whose endpoints have an entry in their LabelList \"room\":\"bedroom 2\" are in the same (bed)room." + @@ -27,7 +29,9 @@ export const FixedLabel = Cluster( " identify the endpoints of a luminaire, one pointing up, the other pointing down, one of the " + " endpoints would have a LabelList entry \"orientation\":\"up\" while the other would have " + " \"orientation\":\"down\". Using such indication, the user interface of a Node controlling this " + - " luminaire knows which of the endpoints is which of the lights." + + " luminaire" + + "\n" + + "knows which of the endpoints is which of the lights." + "\n" + "Note that the TagList in the Descriptor cluster provides an alternative mechanism for such self- " + "description using standardized tags rather than manufacturer-selected strings, yielding a " + diff --git a/packages/model/src/standard/elements/FlowMeasurement.ts b/packages/model/src/standard/elements/FlowMeasurement.ts index 1fb1fad439..33d6189aaa 100644 --- a/packages/model/src/standard/elements/FlowMeasurement.ts +++ b/packages/model/src/standard/elements/FlowMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,7 @@ export const FlowMeasurement = Cluster( name: "MeasuredValue", id: 0x0, type: "uint16", access: "R V", conformance: "M", constraint: "minMeasuredValue to maxMeasuredValue", default: null, quality: "X P", - details: "MeasuredValue represents the flow in m/h as follows:" + + details: "Indicates the flow in m/h as follows:" + "\n" + "MeasuredValue = 10 x Flow" + "\n" + @@ -37,9 +37,9 @@ export const FlowMeasurement = Cluster( Attribute({ name: "MinMeasuredValue", id: 0x1, type: "uint16", access: "R V", conformance: "M", - constraint: "0 to maxMeasuredValue1", quality: "X", - details: "The MinMeasuredValue attribute indicates the minimum value of MeasuredValue that can be measured. " + - "See Measured Value for more details." + + constraint: "max 65533", quality: "X", + details: "Indicates the minimum value of MeasuredValue that can be measured. See Measured Value for more " + + "details." + "\n" + "The null value indicates that the value is not available.", xref: { document: "cluster", section: "2.5.4.2" } @@ -47,17 +47,18 @@ export const FlowMeasurement = Cluster( Attribute({ name: "MaxMeasuredValue", id: 0x2, type: "uint16", access: "R V", conformance: "M", - constraint: "minMeasuredValue1 to 65534", quality: "X", - details: "The MaxMeasuredValue attribute indicates the maximum value of MeasuredValue that can be measured. " + - "See Measured Value for more details." + + constraint: "min minMeasuredValue + 1", quality: "X", + details: "Indicates the maximum value of MeasuredValue that can be measured. See" + + "\n" + + "Measured Value for more details." + "\n" + "The null value indicates that the value is not available.", xref: { document: "cluster", section: "2.5.4.3" } }), Attribute({ - name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", - constraint: "0 to 2048", default: 0, + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", + default: 0, details: "See Measured Value.", xref: { document: "cluster", section: "2.5.4.4" } }) diff --git a/packages/model/src/standard/elements/FlowSensorDT.ts b/packages/model/src/standard/elements/FlowSensorDT.ts index 2dd632342e..63eaf85286 100644 --- a/packages/model/src/standard/elements/FlowSensorDT.ts +++ b/packages/model/src/standard/elements/FlowSensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/FormaldehydeConcentrationMeasurement.ts b/packages/model/src/standard/elements/FormaldehydeConcentrationMeasurement.ts index 684ad6c8c5..42478a5c3c 100644 --- a/packages/model/src/standard/elements/FormaldehydeConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/FormaldehydeConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/GeneralCommissioning.ts b/packages/model/src/standard/elements/GeneralCommissioning.ts index 58c74dcccb..d407ba59b5 100644 --- a/packages/model/src/standard/elements/GeneralCommissioning.ts +++ b/packages/model/src/standard/elements/GeneralCommissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,8 +10,8 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - CommandElement as Command, FieldElement as Field, + CommandElement as Command, DatatypeElement as Datatype } from "../../elements/index.js"; @@ -26,7 +26,15 @@ export const GeneralCommissioning = Cluster( xref: { document: "core", section: "11.10" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.10.4" } }, + Field({ + name: "TC", conformance: "P", constraint: "0", description: "TermsAndConditions", + details: "Supports Terms & Conditions acknowledgement" + }) + ), Attribute({ name: "Breadcrumb", id: 0x0, type: "uint64", access: "RW VA", conformance: "M", default: 0, @@ -46,7 +54,7 @@ export const GeneralCommissioning = Cluster( "the functioning of any cluster, other than being set as a side-effect of commands where this " + "behavior is described.", - xref: { document: "core", section: "11.10.5.1" } + xref: { document: "core", section: "11.10.6.1" } }), Attribute({ @@ -54,7 +62,7 @@ export const GeneralCommissioning = Cluster( conformance: "M", constraint: "desc", quality: "F", details: "This attribute shall describe critical parameters needed at the beginning of commissioning flow. " + "See BasicCommissioningInfo for more information.", - xref: { document: "core", section: "11.10.5.2" } + xref: { document: "core", section: "11.10.6.2" } }), Attribute({ @@ -64,7 +72,7 @@ export const GeneralCommissioning = Cluster( "\n" + "Note that the country code is part of Basic Information Cluster and therefore NOT listed on the " + "RegulatoryConfig attribute.", - xref: { document: "core", section: "11.10.5.3" } + xref: { document: "core", section: "11.10.6.3" } }), Attribute({ @@ -74,7 +82,8 @@ export const GeneralCommissioning = Cluster( details: "LocationCapability is statically set by the manufacturer and indicates if this Node needs to be " + "told an exact RegulatoryLocation. For example a Node which is \"Indoor Only\" would not be certified " + "for outdoor use at all, and thus there is no need for a commissioner to set or ask the user about " + - "whether the device will be used inside or outside. However a device which states its capability is " + + "whether the device will be used inside or outside. However a device which states its capability is" + + "\n" + "\"Indoor/Outdoor\" means it would like clarification if possible." + "\n" + "For Nodes without radio network interfaces (e.g. Ethernet-only devices), the value IndoorOutdoor " + @@ -84,7 +93,7 @@ export const GeneralCommissioning = Cluster( "This means devices always have a safe default value, and Commissioners which choose to implement " + "smarter handling can.", - xref: { document: "core", section: "11.10.5.4" } + xref: { document: "core", section: "11.10.6.4" } }), Attribute({ @@ -93,7 +102,88 @@ export const GeneralCommissioning = Cluster( details: "Indicates whether this device supports \"concurrent connection flow\" commissioning mode (see Section " + "5.5, “Commissioning Flows”). If false, the device only supports \"non-concurrent connection flow\" " + "mode.", - xref: { document: "core", section: "11.10.5.5" } + xref: { document: "core", section: "11.10.6.5" } + }), + + Attribute({ + name: "TcAcceptedVersion", id: 0x5, type: "uint16", access: "R A", conformance: "P, TC", + quality: "N", + + details: "Indicates the last version of the T&Cs for which the device received user acknowledgements. On " + + "factory reset this field shall be reset to 0." + + "\n" + + "When Custom Commissioning Flow is used to obtain user consent (e. g. because the Commissioner does " + + "not support the TC feature), the manufacturer-provided means for obtaining user consent shall " + + "ensure that this attribute is set to a value which is greater than or equal to TCMinRequiredVersion " + + "before returning the user back to the originating Commissioner (see Enhanced Setup Flow).", + + xref: { document: "core", section: "11.10.6.6" } + }), + + Attribute({ + name: "TcMinRequiredVersion", id: 0x6, type: "uint16", access: "R A", conformance: "P, TC", + quality: "N", + + details: "Indicates the minimum version of the texts presented by the Enhanced Setup Flow that need to be " + + "accepted by the user for this device. This attribute may change as the result of an OTA update." + + "\n" + + "If an event such as a software update causes TCAcceptedVersion to become less than " + + "TCMinRequiredVersion, then the device shall update TCAcknowledgementsRequired to True so that an " + + "administrator can detect that a newer version of the texts needs to be presented to the user.", + + xref: { document: "core", section: "11.10.6.7" } + }), + + Attribute({ + name: "TcAcknowledgements", id: 0x7, type: "map16", access: "R A", conformance: "P, TC", + quality: "N", + + details: "Indicates the user’s response to the presented terms. Each bit position corresponds to a user " + + "response for the associated index of matching text, such that bit 0 (bit value 1) is for text index " + + "0. Bit 15 (bit value 0x8000) is for text index 15. A bit value of 1 indicates acceptance and a " + + "value of 0 indicates non-acceptance. For example, if there are two texts that were presented where " + + "the first (bit 0, value 1) was declined and the second accepted (bit 1, value 2), we would expect " + + "the resulting value of the map to be 2." + + "\n" + + "Whenever a user provides responses to newly presented terms and conditions, this attribute shall be " + + "updated with the latest responses. This may happen in response to updated terms that were presented " + + "to the user. On a factory reset this field shall be reset with all bits set to 0.", + + xref: { document: "core", section: "11.10.6.8" } + }), + + Attribute({ + name: "TcAcknowledgementsRequired", id: 0x8, type: "bool", access: "R A", conformance: "P, TC", + default: true, quality: "N", + + details: "Indicates whether SetTCAcknowledgements is currently required to be called with the inclusion of " + + "mandatory terms accepted." + + "\n" + + "This attribute may be present and False in the case where no terms and conditions are currently " + + "mandatory to accept for CommissioningComplete to succeed." + + "\n" + + "This attribute may appear, or become True after commissioning (e.g. due to a firmware update) to " + + "indicate that new Terms & Conditions are available that the user must accept." + + "\n" + + "Upon Factory Data Reset, this attribute shall be set to a value of True." + + "\n" + + "When Custom Commissioning Flow is used to obtain user consent (e.g. because the Commissioner does " + + "not support the TC feature), the manufacturer-provided means for obtaining user consent shall " + + "ensure that this attribute is set to False before returning the user back to the original " + + "Commissioner (see Enhanced Setup Flow).", + + xref: { document: "core", section: "11.10.6.9" } + }), + + Attribute({ + name: "TcUpdateDeadline", id: 0x9, type: "uint32", access: "R A", conformance: "P, TC", + quality: "X N", + details: "Indicates the System Time in seconds when any functionality limitations will begin due to a lack of " + + "acceptance of updated Terms and Conditions, as described in Section 5.7.4.5, “Presenting Updated " + + "Terms and Conditions”." + + "\n" + + "A null value indicates that there is no pending deadline for updated TC acceptance.", + xref: { document: "core", section: "11.10.6.10" } }), Command( @@ -115,9 +205,8 @@ export const GeneralCommissioning = Cluster( "duration of ExpiryLengthSeconds, or disarm it, depending on the situation:" + "\n" + " • If ExpiryLengthSeconds is 0 and the fail-safe timer was already armed and the accessing fabric " + - " matches the Fabric currently associated with the fail-safe context, then the fail-safe timer" + - "\n" + - "shall be immediately expired (see further below for side-effects of expiration)." + + " matches the Fabric currently associated with the fail-safe context, then the fail-safe timer " + + " shall be immediately expired (see further below for side-effects of expiration)." + "\n" + " • If ExpiryLengthSeconds is 0 and the fail-safe timer was not armed, then this command invocation " + " shall lead to a success response with no side-effects against the fail-safe context." + @@ -133,8 +222,8 @@ export const GeneralCommissioning = Cluster( " respond with ArmFailSafeResponse containing an ErrorCode value of BusyWithOtherAdmin, " + " indicating a likely conflict between commissioners." + "\n" + - "The value of the Breadcrumb field shall be written to the Breadcrumb Attribute on successful " + - "execution of the command." + + "The value of the Breadcrumb field shall be written to the Breadcrumb on successful execution of the " + + "command." + "\n" + "If the receiver restarts unexpectedly (e.g., power interruption, software crash, or other reset) " + "the receiver shall behave as if the fail-safe timer expired and perform the sequence of clean-up " + @@ -182,7 +271,7 @@ export const GeneralCommissioning = Cluster( "Context timer (CFSC timer) serves to limit the lifetime of any particular Fail Safe Context; it " + "shall NOT be extended or modified on subsequent invocations of ArmFailSafe associated with this " + "Fail Safe Context. Upon expiry of the CFSC timer, the receiver shall execute cleanup behavior " + - "equivalent to that of fail-safe timer expiration as detailed in Section 11.10.6.2.2, “Behavior on " + + "equivalent to that of fail-safe timer expiration as detailed in Section 11.10.7.2.2, “Behavior on " + "expiry of Fail-Safe timer”. Termination of the session prior to the expiration of that timer for " + "any reason (including a successful end of commissioning or an expiry of a fail-safe timer) shall " + "also delete the CFSC timer." + @@ -196,12 +285,11 @@ export const GeneralCommissioning = Cluster( " the Server." + "\n" + " 2. Revoke the temporary administrative privileges granted to any open PASE session (see Section " + - " 6.6.2.8, “Bootstrapping of the Access Control Cluster”) at the Server." + + " 6.6.2.9, “Bootstrapping of the Access Control Cluster”) at the Server." + "\n" + " 3. If an AddNOC or UpdateNOC command has been successfully invoked, terminate all CASE sessions " + " associated with the Fabric whose Fabric Index is recorded in the Fail-Safe context (see " + - " Section 11.10.6.2, “ArmFailSafe Command”) by clearing any associated Secure Session Context " + - " at the Server." + + " ArmFailSafe) by clearing any associated Secure Session Context at the Server." + "\n" + " 4. Reset the configuration of all Network Commissioning Networks attribute to their state prior " + " to the Fail-Safe being armed." + @@ -227,11 +315,10 @@ export const GeneralCommissioning = Cluster( "\n" + " 9. Reset the Breadcrumb attribute to zero." + "\n" + - " 10. Optionally: if no factory-reset resulted from the previous steps, it is recommended that the" + - "\n" + - "Node rollback the state of all non fabric-scoped data present in the Fail-Safe context.", + " 10. Optionally: if no factory-reset resulted from the previous steps, it is recommended that the " + + " Node rollback the state of all non fabric-scoped data present in the Fail-Safe context.", - xref: { document: "core", section: "11.10.6.2" } + xref: { document: "core", section: "11.10.7.2" } }, Field({ name: "ExpiryLengthSeconds", id: 0x0, type: "uint16", conformance: "M", default: 900 }), @@ -241,20 +328,20 @@ export const GeneralCommissioning = Cluster( Command( { name: "ArmFailSafeResponse", id: 0x1, conformance: "M", direction: "response", - xref: { document: "core", section: "11.10.6.3" } + xref: { document: "core", section: "11.10.7.3" } }, Field({ name: "ErrorCode", id: 0x0, type: "CommissioningErrorEnum", conformance: "M", default: 0, details: "This field shall contain the result of the operation, based on the behavior specified in the " + "functional description of the ArmFailSafe command.", - xref: { document: "core", section: "11.10.6.3.1" } + xref: { document: "core", section: "11.10.7.3.1" } }), Field({ name: "DebugText", id: 0x1, type: "string", conformance: "M", constraint: "max 128", default: "", - details: "See Section 11.10.6.1, “Common fields in General Commissioning cluster responses”.", - xref: { document: "core", section: "11.10.6.3.2" } + details: "See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”.", + xref: { document: "core", section: "11.10.7.3.2" } }) ), @@ -278,7 +365,8 @@ export const GeneralCommissioning = Cluster( "still set the Location attribute reflected by the Basic Information Cluster configuration, but the " + "SetRegulatoryConfigResponse replied shall have the ErrorCode field set to ValueOutsideRange error." + "\n" + - "If the LocationCapability attribute is not Indoor/Outdoor and the NewRegulatoryConfig value " + + "If the LocationCapability attribute is not Indoor/Outdoor and the NewRegulatoryConfig value" + + "\n" + "received does not match either the Indoor or Outdoor fixed value in LocationCapability, then the " + "SetRegulatoryConfigResponse replied shall have the ErrorCode field set to ValueOutsideRange error " + "and the RegulatoryConfig attribute and associated internal radio configuration shall remain " + @@ -294,7 +382,7 @@ export const GeneralCommissioning = Cluster( "command, when SetRegulatoryConfigResponse has the ErrorCode field set to OK. If the command fails, " + "the Breadcrumb attribute shall be left unchanged.", - xref: { document: "core", section: "11.10.6.4" } + xref: { document: "core", section: "11.10.7.4" } }, Field({ name: "NewRegulatoryConfig", id: 0x0, type: "RegulatoryLocationTypeEnum", conformance: "M" }), @@ -305,20 +393,20 @@ export const GeneralCommissioning = Cluster( Command( { name: "SetRegulatoryConfigResponse", id: 0x3, conformance: "M", direction: "response", - xref: { document: "core", section: "11.10.6.5" } + xref: { document: "core", section: "11.10.7.5" } }, Field({ name: "ErrorCode", id: 0x0, type: "CommissioningErrorEnum", conformance: "M", default: 0, details: "This field shall contain the result of the operation, based on the behavior specified in the " + "functional description of the SetRegulatoryConfig command.", - xref: { document: "core", section: "11.10.6.5.1" } + xref: { document: "core", section: "11.10.7.5.1" } }), Field({ name: "DebugText", id: 0x1, type: "string", conformance: "M", default: "", - details: "See Section 11.10.6.1, “Common fields in General Commissioning cluster responses”.", - xref: { document: "core", section: "11.10.6.5.2" } + details: "See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”.", + xref: { document: "core", section: "11.10.7.5.2" } }) ), @@ -336,16 +424,20 @@ export const GeneralCommissioning = Cluster( "all steps needed during the Fail-Safe period, such as commissioning (see Section 5.5, " + "“Commissioning Flows”) or other Administrator operations requiring usage of the Fail Safe timer. It " + "ensures that the Server is configured in a state such that it still has all necessary elements to " + - "be fully operable within a Fabric, such as ACL entries (see Access Control Cluster) and operational " + - "credentials (see Section 6.4, “Node Operational Credentials Specification”), and that the Node is " + - "reach" + + "be fully operable within a Fabric, such as ACL entries (see Section 9.10, “Access Control Cluster”) " + + "and operational credentials (see Section 6.4, “Node Operational Credentials Specification”), and " + + "that the Node is reachable using CASE" + "\n" + - "able using CASE (see Section 4.14.2, “Certificate Authenticated Session Establishment (CASE)”) over " + - "an operational network." + + "(CASE)”) over an operational network." + "\n" + "An ErrorCode of NoFailSafe shall be responded to the invoker if the CommissioningComplete command " + "was received when no Fail-Safe context exists." + "\n" + + "If Terms and Conditions are required, then an ErrorCode of TCAcknowledgementsNotReceived shall be " + + "responded to the invoker if the user acknowledgements to the required Terms and Conditions have not " + + "been provided. If the TCAcceptedVersion for the provided acknowledgements is less than " + + "TCMinRequiredVersion, then an ErrorCode of TCMinVersionNotMet shall be responded to the invoker." + + "\n" + "This command is fabric-scoped, so cannot be issued over a session that does not have an associated " + "fabric, i.e. over PASE session prior to an AddNOC command. In addition, this command is only " + "permitted over CASE and must be issued by a node associated with the ongoing Fail-Safe context. An " + @@ -373,7 +465,7 @@ export const GeneralCommissioning = Cluster( " 2. The commissioning window at the Server shall be closed." + "\n" + " 3. Any temporary administrative privileges automatically granted to any open PASE session shall " + - " be revoked (see Section 6.6.2.8, “Bootstrapping of the Access Control Cluster”)." + + " be revoked (see Section 6.6.2.9, “Bootstrapping of the Access Control Cluster”)." + "\n" + " 4. The Secure Session Context of any PASE session still established at the Server shall be " + " cleared." + @@ -384,26 +476,88 @@ export const GeneralCommissioning = Cluster( "expect any previously established PASE session to still be usable, due to the server having cleared " + "such sessions.", - xref: { document: "core", section: "11.10.6.6" } + xref: { document: "core", section: "11.10.7.6" } }), Command( { name: "CommissioningCompleteResponse", id: 0x5, conformance: "M", direction: "response", - xref: { document: "core", section: "11.10.6.7" } + xref: { document: "core", section: "11.10.7.7" } }, Field({ name: "ErrorCode", id: 0x0, type: "CommissioningErrorEnum", conformance: "M", default: 0, details: "This field shall contain the result of the operation, based on the behavior specified in the " + "functional description of the CommissioningComplete command.", - xref: { document: "core", section: "11.10.6.7.1" } + xref: { document: "core", section: "11.10.7.7.1" } }), Field({ name: "DebugText", id: 0x1, type: "string", conformance: "M", default: "", - details: "See Section 11.10.6.1, “Common fields in General Commissioning cluster responses”.", - xref: { document: "core", section: "11.10.6.7.2" } + details: "See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”.", + xref: { document: "core", section: "11.10.7.7.2" } + }) + ), + + Command( + { + name: "SetTcAcknowledgements", id: 0x6, access: "A", conformance: "P, TC", direction: "request", + response: "SetTcAcknowledgementsResponse", + details: "This command sets the user acknowledgements received in the Enhanced Setup Flow Terms & Conditions " + + "into the node.", + xref: { document: "core", section: "11.10.7.8" } + }, + + Field({ + name: "TcVersion", id: 0x0, type: "uint16", conformance: "M", + details: "This field shall contain the version of the Enhanced Setup Flow Terms & Conditions that were " + + "presented to the user.", + xref: { document: "core", section: "11.10.7.8.1" } + }), + + Field({ + name: "TcUserResponse", id: 0x1, type: "map16", conformance: "M", + + details: "This field shall contain the user responses to the Enhanced Setup Flow Terms & Conditions as a map " + + "where each bit set in the bitmap corresponds to an accepted term in the file located at " + + "EnhancedSetupFlowTCUrl." + + "\n" + + "### Effect on Receipt" + + "\n" + + "This command shall copy the user responses and accepted version to the presented Enhanced Setup " + + "Flow Terms & Conditions from the values provided in the TCUserResponse and TCVersion fields to the " + + "TCAcknowledgements Attribute and the TCAcceptedVersion Attribute fields respectively." + + "\n" + + "This command shall result in success with an ErrorCode value of OK in the " + + "SetTCAcknowledgementsResponse if all required terms were accepted by the user. Specifically, all " + + "bits have a value of 1 in TCAcknowledgements whose ordinal is marked as required in the file " + + "located at EnhancedSe" + + "\n" + + "tupFlowTCUrl." + + "\n" + + "If the TCVersion field is less than the TCMinRequiredVersion, then the ErrorCode of " + + "TCMinVersionNotMet shall be returned and TCAcknowledgements shall remain unchanged." + + "\n" + + "If TCVersion is greater than or equal to TCMinRequiredVersion, but the TCUserResponse value " + + "indicates that not all required terms were accepted by the user, then the ErrorCode of " + + "RequiredTCNotAccepted shall be returned and TCAcknowledgements shall remain unchanged.", + + xref: { document: "core", section: "11.10.7.8.2" } + }) + ), + + Command( + { + name: "SetTcAcknowledgementsResponse", id: 0x7, conformance: "P, TC", direction: "response", + details: "This command is used to convey the result from SetTCAcknowledgements.", + xref: { document: "core", section: "11.10.7.9" } + }, + + Field({ + name: "ErrorCode", id: 0x0, type: "CommissioningErrorEnum", conformance: "M", default: 0, + details: "This field shall contain the result of the operation, based on the behavior specified in the " + + "functional description of the SetTCAcknowledgements command.", + xref: { document: "core", section: "11.10.7.9.1" } }) ), @@ -411,7 +565,7 @@ export const GeneralCommissioning = Cluster( { name: "CommissioningErrorEnum", type: "enum8", details: "This enumeration is used by several response commands in this cluster to indicate particular errors.", - xref: { document: "core", section: "11.10.4.1" } + xref: { document: "core", section: "11.10.5.1" } }, Field({ name: "Ok", id: 0x0, conformance: "M", description: "No error" }), Field({ @@ -429,6 +583,18 @@ export const GeneralCommissioning = Cluster( Field({ name: "BusyWithOtherAdmin", id: 0x4, conformance: "M", description: "Attempting to arm fail- safe or execute CommissioningComplete from a fabric different than the one associated with the current fail- safe context." + }), + Field({ + name: "RequiredTcNotAccepted", id: 0x5, conformance: "TC", + description: "One or more required TC features from the Enhanced Setup Flow were not accepted." + }), + Field({ + name: "TcAcknowledgementsNotReceived", id: 0x6, conformance: "TC", + description: "No acknowledgements from the user for the TC features were received." + }), + Field({ + name: "TcMinVersionNotMet", id: 0x7, conformance: "TC", + description: "The version of the TC features acknowledged by the user did not meet the minimum required version." }) ), @@ -437,7 +603,7 @@ export const GeneralCommissioning = Cluster( name: "RegulatoryLocationTypeEnum", type: "enum8", details: "This enumeration is used by the RegulatoryConfig and LocationCapability attributes to indicate " + "possible radio usage.", - xref: { document: "core", section: "11.10.4.2" } + xref: { document: "core", section: "11.10.5.2" } }, Field({ name: "Indoor", id: 0x0, conformance: "M", description: "Indoor only" }), @@ -449,7 +615,7 @@ export const GeneralCommissioning = Cluster( { name: "BasicCommissioningInfo", type: "struct", details: "This structure provides some constant values that may be of use to all commissioners.", - xref: { document: "core", section: "11.10.4.3" } + xref: { document: "core", section: "11.10.5.3" } }, Field({ @@ -459,20 +625,20 @@ export const GeneralCommissioning = Cluster( "of the Commissionee. This value, if used in the ArmFailSafe command’s ExpiryLengthSeconds field " + "SHOULD allow a Commissioner to proceed with a nominal commissioning without having to-rearm the " + "fail-safe, with some margin.", - xref: { document: "core", section: "11.10.4.3.1" } + xref: { document: "core", section: "11.10.5.3.1" } }), Field({ name: "MaxCumulativeFailsafeSeconds", id: 0x1, type: "uint16", conformance: "M", constraint: "desc", details: "This field shall contain a conservative value in seconds denoting the maximum total duration for " + - "which a fail safe timer can be re-armed. See Section 11.10.6.2.1, “Fail Safe Context”." + + "which a fail safe timer can be re-armed. See Section 11.10.7.2.1, “Fail Safe Context”." + "\n" + "The value of this field shall be greater than or equal to the FailSafeExpiryLengthSeconds. Absent " + "additional guidelines, it is recommended that the value of this field be aligned with the initial " + "Announcement Duration and default to 900 seconds.", - xref: { document: "core", section: "11.10.4.3.2" } + xref: { document: "core", section: "11.10.5.3.2" } }) ) ); diff --git a/packages/model/src/standard/elements/GeneralDiagnostics.ts b/packages/model/src/standard/elements/GeneralDiagnostics.ts index 4e6947beb9..2ffc90a077 100644 --- a/packages/model/src/standard/elements/GeneralDiagnostics.ts +++ b/packages/model/src/standard/elements/GeneralDiagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -97,7 +97,8 @@ export const GeneralDiagnostics = Cluster( details: "The ActiveHardwareFaults attribute shall indicate the set of faults currently detected by the Node. " + "When the Node detects a fault has been raised, the appropriate HardwareFaultEnum value shall be " + "added to this list. This list shall NOT contain more than one instance of a specific " + - "HardwareFaultEnum value. When the Node detects that all conditions contributing to a fault has been " + + "HardwareFaultEnum value. When the Node detects that all conditions contributing to a fault has been" + + "\n" + "cleared, the corresponding HardwareFaultEnum value shall be removed from this list. An empty list " + "shall indicate there are currently no active faults. The order of this list SHOULD have no " + "significance. Clients interested in monitoring changes in active faults may subscribe to this " + @@ -154,11 +155,10 @@ export const GeneralDiagnostics = Cluster( details: "The TestEventTriggersEnabled attribute shall indicate whether the Node has any TestEventTrigger " + "configured. When this attribute is true, the Node has been configured with one or more test event " + - "triggers by virtue of the internally programmed EnableKey value (see Section 11.12.7.1, " + - "“TestEventTrigger Command”) being set to a non-zero value. This attribute can be used by " + - "Administrators to detect if a device was inadvertently commissioned with test event trigger mode " + - "enabled, and take appropriate action (e.g. warn the user and/or offer to remove all fabrics on the " + - "Node).", + "triggers by virtue of the internally programmed EnableKey value (see TestEventTrigger) being set to " + + "a non-zero value. This attribute can be used by Administrators to detect if a device was " + + "inadvertently commissioned with test event trigger mode enabled, and take appropriate action (e.g. " + + "warn the user and/or offer to remove all fabrics on the Node).", xref: { document: "core", section: "11.12.6.9" } }), @@ -176,19 +176,17 @@ export const GeneralDiagnostics = Cluster( Field( { name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 11", - details: "This field shall represent the set of faults currently detected, as per Section 11.12.5.1, " + - "“HardwareFaultEnum Type”.", + details: "This field shall represent the set of faults currently detected, as per HardwareFaultEnum.", xref: { document: "core", section: "11.12.8.1.1" } }, - Field({ name: "entry", type: "HardwareFaultEnum" }) ), Field( { name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 11", - details: "This field shall represent the set of faults detected prior to this change event, as per Section " + - "11.12.5.1, “HardwareFaultEnum Type”.", + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "HardwareFaultEnum.", xref: { document: "core", section: "11.12.8.1.2" } }, @@ -207,19 +205,17 @@ export const GeneralDiagnostics = Cluster( Field( { name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 7", - details: "This field shall represent the set of faults currently detected, as per Section 11.12.5.2, " + - "“RadioFaultEnum Type”.", + details: "This field shall represent the set of faults currently detected, as per RadioFaultEnum.", xref: { document: "core", section: "11.12.8.2.1" } }, - Field({ name: "entry", type: "RadioFaultEnum" }) ), Field( { name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 7", - details: "This field shall represent the set of faults detected prior to this change event, as per Section " + - "11.12.5.2, “RadioFaultEnum Type”.", + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "RadioFaultEnum.", xref: { document: "core", section: "11.12.8.2.2" } }, @@ -238,19 +234,17 @@ export const GeneralDiagnostics = Cluster( Field( { name: "Current", id: 0x0, type: "list", conformance: "M", constraint: "max 4", - details: "This field shall represent the set of faults currently detected, as per Section 11.12.5.3, " + - "“NetworkFaultEnum Type”.", + details: "This field shall represent the set of faults currently detected, as per NetworkFaultEnum.", xref: { document: "core", section: "11.12.8.3.1" } }, - Field({ name: "entry", type: "NetworkFaultEnum" }) ), Field( { name: "Previous", id: 0x1, type: "list", conformance: "M", constraint: "max 4", - details: "This field shall represent the set of faults detected prior to this change event, as per Section " + - "11.12.5.3, “NetworkFaultEnum Type”.", + details: "This field shall represent the set of faults detected prior to this change event, as per " + + "NetworkFaultEnum.", xref: { document: "core", section: "11.12.8.3.2" } }, @@ -320,7 +314,8 @@ export const GeneralDiagnostics = Cluster( "Values of EventTrigger in the range 0xFFFF_FFFF_0000_0000 through 0xFFFF_FFFF_FFFF_FFFF are " + "reserved for testing use by manufacturers and will not appear in CSA certification test literature." + "\n" + - "If the value of EventTrigger received is not supported by the receiving Node, this command shall " + + "If the value of EventTrigger received is not supported by the receiving Node, this command shall" + + "\n" + "fail with a status code of INVALID_COMMAND." + "\n" + "Otherwise, if the EnableKey value matches the configured internal value for a particular Node, and " + @@ -342,10 +337,8 @@ export const GeneralDiagnostics = Cluster( details: "This command may be used by a client to obtain a correlated view of both System Time, and, if " + "currently synchronized and supported, \"wall clock time\" of the server. This can help clients " + - "establish" + - "\n" + - "time correlation between their concept of time and the server’s concept of time. This is especially " + - "useful when processing event histories where some events only contain System Time." + + "establish time correlation between their concept of time and the server’s concept of time. This is " + + "especially useful when processing event histories where some events only contain System Time." + "\n" + "Upon command invocation, the server shall respond with a TimeSnapshotResponse.", @@ -443,9 +436,10 @@ export const GeneralDiagnostics = Cluster( " • If Value is 0x55 and the Count is zero, then the PayloadTestResponse would have the Payload " + " field set to an empty octet string." + "\n" + - " • If Value is 0xA5 and the Count is 10, the PayloadTestResponse would have the Payload field set " + - " to a content whose hexadecimal representation would be A5A5A5A5A5A5A5A5A5A5, and base64 " + - " representation would be paWlpaWlpaWlpQ==.", + " • If Value is 0xA5 and the Count is 10, the PayloadTestResponse would have the Payload field set" + + "\n" + + "to a content whose hexadecimal representation would be A5A5A5A5A5A5A5A5A5A5, and base64 " + + "representation would be paWlpaWlpaWlpQ==.", xref: { document: "core", section: "11.12.7.4.3" } }) @@ -453,7 +447,7 @@ export const GeneralDiagnostics = Cluster( Command( { - name: "PayloadTestResponse", id: 0x4, access: "M", conformance: "DMTEST", direction: "response", + name: "PayloadTestResponse", id: 0x4, conformance: "DMTEST", direction: "response", details: "This command is sent by the server on receipt of the PayloadTestRequest command.", xref: { document: "core", section: "11.12.7.5" } }, @@ -650,7 +644,8 @@ export const GeneralDiagnostics = Cluster( Field({ name: "HardwareAddress", id: 0x4, type: "hwadr", conformance: "M", - details: "This field shall contain the current link-layer address for a 802.3 or IEEE 802.11-2020 network " + + details: "This field shall contain the current link-layer address for a 802.3 or IEEE 802.11-2020 network" + + "\n" + "interface and contain the current extended MAC address for a 802.15.4 interface. The byte order of " + "the octstr shall be in wire byte order. For addresses values less than 64 bits, the first two bytes " + "shall be zero.", diff --git a/packages/model/src/standard/elements/GeneratedCommandList.ts b/packages/model/src/standard/elements/GeneratedCommandList.ts index 47da46ffac..35ef513f09 100644 --- a/packages/model/src/standard/elements/GeneratedCommandList.ts +++ b/packages/model/src/standard/elements/GeneratedCommandList.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,10 @@ export const GeneratedCommandList = Attribute( "This attribute shall be a list of the command IDs for server generated commands." + "\n" + "For each command in this list that is a response to a client command request, the request command " + - "shall be indicated in the AcceptedCommandList attribute.", + "shall be indicated in the AcceptedCommandList attribute." + + "\n" + + "If any attribute on a server supports atomic writes, this attribute shall contain the command ID " + + "for AtomicResponse.", xref: { document: "core", section: "7.13.5" } }, diff --git a/packages/model/src/standard/elements/GenericSwitchDT.ts b/packages/model/src/standard/elements/GenericSwitchDT.ts index 315d28d69d..ad11d7cefa 100644 --- a/packages/model/src/standard/elements/GenericSwitchDT.ts +++ b/packages/model/src/standard/elements/GenericSwitchDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/GroupKeyManagement.ts b/packages/model/src/standard/elements/GroupKeyManagement.ts index 070148eda0..43ae6db5f7 100644 --- a/packages/model/src/standard/elements/GroupKeyManagement.ts +++ b/packages/model/src/standard/elements/GroupKeyManagement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -26,8 +26,9 @@ export const GroupKeyManagement = Cluster( "via modifications of the list. Such modifications require Administer privilege." + "\n" + "Each group entry includes a membership list of zero of more endpoints that are members of the group " + - "on the node. Modification of this membership list is done via the Groups cluster, which is scoped " + - "to an endpoint. Please see the System Model specification for more information on groups.", + "on the node. Modification of this membership list is done via the Groups cluster, which is" + + "\n" + + "scoped to an endpoint. Please see the System Model specification for more information on groups.", xref: { document: "core", section: "11.2" } }, @@ -37,7 +38,7 @@ export const GroupKeyManagement = Cluster( Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.2.4" } }, Field({ - name: "CS", constraint: "0", description: "CacheAndSync", + name: "CS", conformance: "P", constraint: "0", description: "CacheAndSync", details: "The ability to support CacheAndSync security policy and MCSP." }) ), @@ -60,7 +61,8 @@ export const GroupKeyManagement = Cluster( default: [], details: "This attribute is a list of GroupInfoMapStruct entries. Each entry provides read-only information " + - "about how a given logical Group ID maps to a particular set of endpoints, and a name for the group. " + + "about how a given logical Group ID maps to a particular set of endpoints, and a name for the group." + + "\n" + "The content of this attribute reflects data managed via the Groups cluster (see AppClusters), and " + "is in general terms referred to as the 'node-wide Group Table'." + "\n" + @@ -148,17 +150,18 @@ export const GroupKeyManagement = Cluster( "\n" + "If there exists a Group Key Set associated with the accessing fabric which has the same " + "GroupKeySetID as that provided in the GroupKeySet field, then the contents of that group key set " + - "shall be replaced. A replacement shall be done by executing the equivalent of entirely removing the " + - "previous Group Key Set with the given GroupKeySetID, followed by an addition of a Group Key Set " + - "with the provided configuration. Otherwise, if the GroupKeySetID did not match an existing entry, a " + - "new Group Key Set associated with the accessing fabric shall be created with the provided data. The " + + "shall be" + + "\n" + + "replaced. A replacement shall be done by executing the equivalent of entirely removing the previous " + + "Group Key Set with the given GroupKeySetID, followed by an addition of a Group Key Set with the " + + "provided configuration. Otherwise, if the GroupKeySetID did not match an existing entry, a new " + + "Group Key Set associated with the accessing fabric shall be created with the provided data. The " + "Group Key Set shall be written to non-volatile storage." + "\n" + "Upon completion, this command shall send a status code back to the initiator:" + "\n" + - " • If the Group Key Set was properly installed or updated on the Node, the status code shall be" + - "\n" + - "set to SUCCESS." + + " • If the Group Key Set was properly installed or updated on the Node, the status code shall be " + + " set to SUCCESS." + "\n" + " • If there are insufficient resources on the receiver to store an additional Group Key Set, the " + " status code shall be set to RESOURCE_EXHAUSTED (see group key limits);" + @@ -215,10 +218,9 @@ export const GroupKeyManagement = Cluster( "\n" + "Effect on Receipt" + "\n" + - "If there exists a Group Key Set associated with the accessing fabric which has the same GroupKey" + - "\n" + - "SetID as that provided in the GroupKeySetID field, then the contents of that Group Key Set shall be " + - "removed, including all epoch keys it contains." + + "If there exists a Group Key Set associated with the accessing fabric which has the same " + + "GroupKeySetID as that provided in the GroupKeySetID field, then the contents of that Group Key Set " + + "shall be removed, including all epoch keys it contains." + "\n" + "If there exist any entries for the accessing fabric within the GroupKeyMap attribute that refer to " + "the GroupKeySetID just removed, then these entries shall be removed from that list." + @@ -245,8 +247,6 @@ export const GroupKeyManagement = Cluster( details: "This command is used by Administrators to query a list of all Group Key Sets associated with the " + "accessing fabric." + "\n" + - "NOTE Field 0 for this command is reserved and shall NOT be used." + - "\n" + "Effect on Receipt" + "\n" + "Upon receipt, this command shall iterate all stored GroupKeySetStruct associated with the accessing " + @@ -256,7 +256,7 @@ export const GroupKeyManagement = Cluster( xref: { document: "core", section: "11.2.7.5" } }, - Field({ name: "Reserved", id: 0x0, conformance: "X" }), + Field({ name: "DoNotUse", id: 0x0, conformance: "X" }), Field({ name: "GroupKeySetIDs", id: 0x1, conformance: "X" }) ), @@ -324,7 +324,7 @@ export const GroupKeyManagement = Cluster( name: "GroupKeySetId", id: 0x2, type: "uint16", access: "F", conformance: "M", constraint: "1 to 65535", details: "This field references the set of group keys that generate operational group keys for use with this " + - "group, as specified in Section 4.16.3.5.1, “Group Key Set ID”." + + "group, as specified in Section 4.17.3.5.1, “Group Key Set ID”." + "\n" + "A GroupKeyMapStruct shall NOT accept GroupKeySetID of 0, which is reserved for the IPK.", xref: { document: "core", section: "11.2.5.3.2" } @@ -339,7 +339,7 @@ export const GroupKeyManagement = Cluster( Field({ name: "GroupKeySetId", id: 0x0, type: "uint16", conformance: "M", details: "This field shall provide the fabric-unique index for the associated group key set, as specified in " + - "Section 4.16.3.5.1, “Group Key Set ID”.", + "Section 4.17.3.5.1, “Group Key Set ID”.", xref: { document: "core", section: "11.2.5.4.1" } }), @@ -364,7 +364,7 @@ export const GroupKeyManagement = Cluster( Field({ name: "EpochStartTime0", id: 0x3, type: "epoch-us", access: "S", conformance: "M", quality: "X", - details: "This field, if not null, shall define when EpochKey0 becomes valid as specified by Section 4.16.3, " + + details: "This field, if not null, shall define when EpochKey0 becomes valid as specified by Section 4.17.3, " + "“Epoch Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation.", xref: { document: "core", section: "11.2.5.4.4" } }), @@ -372,16 +372,15 @@ export const GroupKeyManagement = Cluster( Field({ name: "EpochKey1", id: 0x4, type: "octstr", access: "S", conformance: "M", constraint: "16", quality: "X", - details: "This field, if not null, shall be the root credential used in the derivation of an operational group" + - "\n" + - "key for epoch slot 1 of the given group key set. If EpochKey1 is not null, EpochStartTime1 shall " + - "NOT be null.", + details: "This field, if not null, shall be the root credential used in the derivation of an operational " + + "group key for epoch slot 1 of the given group key set. If EpochKey1 is not null, EpochStartTime1 " + + "shall NOT be null.", xref: { document: "core", section: "11.2.5.4.5" } }), Field({ name: "EpochStartTime1", id: 0x5, type: "epoch-us", access: "S", conformance: "M", quality: "X", - details: "This field, if not null, shall define when EpochKey1 becomes valid as specified by Section 4.16.3, " + + details: "This field, if not null, shall define when EpochKey1 becomes valid as specified by Section 4.17.3, " + "“Epoch Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation.", xref: { document: "core", section: "11.2.5.4.6" } }), @@ -397,7 +396,7 @@ export const GroupKeyManagement = Cluster( Field({ name: "EpochStartTime2", id: 0x7, type: "epoch-us", access: "S", conformance: "M", quality: "X", - details: "This field, if not null, shall define when EpochKey2 becomes valid as specified by Section 4.16.3, " + + details: "This field, if not null, shall define when EpochKey2 becomes valid as specified by Section 4.17.3, " + "“Epoch Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation.", xref: { document: "core", section: "11.2.5.4.8" } }), diff --git a/packages/model/src/standard/elements/Groups.ts b/packages/model/src/standard/elements/Groups.ts index a74e9df1b1..42a93a4b1c 100644 --- a/packages/model/src/standard/elements/Groups.ts +++ b/packages/model/src/standard/elements/Groups.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -164,7 +164,8 @@ export const Groups = Cluster( Field({ name: "GroupName", id: 0x1, type: "string", conformance: "M", constraint: "max 16", - details: "This field may be set to a human-readable name for the group. If the client has no name for the " + + details: "This field may be set to a human-readable name for the group. If the client has no name for the" + + "\n" + "group, the GroupName field shall be set to the empty string." + "\n" + "Support of group names is optional and is indicated by the FeatureMap and NameSupport attribute.", diff --git a/packages/model/src/standard/elements/HeatPumpDT.ts b/packages/model/src/standard/elements/HeatPumpDT.ts new file mode 100644 index 0000000000..0db42da6e4 --- /dev/null +++ b/packages/model/src/standard/elements/HeatPumpDT.ts @@ -0,0 +1,41 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const HeatPumpDt = DeviceType( + { + name: "HeatPump", id: 0x309, category: "Energy", classification: "simple", + + details: "A Heat Pump device is a device that uses electrical energy to heat either spaces or water tanks " + + "using ground, water or air as the heat source. These typically can heat the air or can pump water " + + "via central heating radiators or underfloor heating systems. It is typical to also heat hot water " + + "and store the heat in a hot water tank." + + "\n" + + "Note that the Water Heater device type can also be heated by a heat pump and has similar " + + "requirements, but that cannot be used for space heating.", + + xref: { document: "device", section: "14.5" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 777, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.5.6" } + }), + Requirement({ + name: "Thermostat", id: 0x201, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "14.5.6" } + }) +); + +MatterDefinition.children.push(HeatPumpDt); diff --git a/packages/model/src/standard/elements/HepaFilterMonitoring.ts b/packages/model/src/standard/elements/HepaFilterMonitoring.ts index a51b48cac2..867643e649 100644 --- a/packages/model/src/standard/elements/HepaFilterMonitoring.ts +++ b/packages/model/src/standard/elements/HepaFilterMonitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/HumiditySensorDT.ts b/packages/model/src/standard/elements/HumiditySensorDT.ts index dd0fb5579b..9f908fe8e5 100644 --- a/packages/model/src/standard/elements/HumiditySensorDT.ts +++ b/packages/model/src/standard/elements/HumiditySensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/IcdManagement.ts b/packages/model/src/standard/elements/IcdManagement.ts index 0466bad225..6c7b859736 100644 --- a/packages/model/src/standard/elements/IcdManagement.ts +++ b/packages/model/src/standard/elements/IcdManagement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -18,42 +18,43 @@ import { export const IcdManagement = Cluster( { name: "IcdManagement", id: 0x46, classification: "node", pics: "ICDM", - details: "ICD Management Cluster enables configuration of the ICD’s behavior and ensuring that listed clients " + "can be notified when an intermittently connected device, ICD, is available for communication." + "\n" + "The cluster implements the requirements of the Check-In Protocol that enables the ICD Check-In use " + - "case." + - "\n" + - "NOTE This feature is provisional.", - + "case.", xref: { document: "core", section: "9.17" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "9.17.4" } }, Field({ - name: "CIP", conformance: "P, LITS, O", constraint: "0", description: "CheckInProtocolSupport", + name: "CIP", conformance: "LITS, O", constraint: "0", description: "CheckInProtocolSupport", details: "When this feature is supported, the device shall support all the associated commands and attributes " + "to properly support the Check-In Protocol.", xref: { document: "core", section: "9.17.4.1" } }), Field({ - name: "UAT", conformance: "P, LITS, O", constraint: "1", description: "UserActiveModeTrigger", + name: "UAT", conformance: "LITS, O", constraint: "1", description: "UserActiveModeTrigger", details: "This feature is supported if and only if the device has a user active mode trigger.", xref: { document: "core", section: "9.17.4.2" } }), - Field({ - name: "LITS", conformance: "P, O", constraint: "2", description: "LongIdleTimeSupport", - details: "This feature is supported if and only the device is a Long Idle Time ICD." + - "\n" + - "NOTE In this version of the specification, the support for the feature is provisional.", + name: "LITS", conformance: "O", constraint: "2", description: "LongIdleTimeSupport", + details: "This feature is supported if and only the device is a Long Idle Time ICD.", xref: { document: "core", section: "9.17.4.3" } + }), + + Field({ + name: "DSLS", conformance: "[LITS]", constraint: "3", description: "DynamicSitLitSupport", + details: "This feature is supported if and only if the device can switch between SIT and LIT operating modes " + + "even if it has a valid registered client. See the dynamic SIT / LIT operating mode switching for " + + "more details.", + xref: { document: "core", section: "9.17.4.4" } }) ), @@ -113,7 +114,7 @@ export const IcdManagement = Cluster( Attribute({ name: "UserActiveModeTriggerHint", id: 0x6, type: "UserActiveModeTriggerBitmap", access: "R V", - conformance: "P, UAT", constraint: "desc", default: 0, quality: "F", + conformance: "UAT", constraint: "desc", default: 0, quality: "F", details: "Indicates which user action(s) will trigger the ICD to switch to Active mode. If the attribute " + "indicates support for a trigger that is dependent on the UserActiveModeTriggerInstruction in the " + @@ -125,7 +126,7 @@ export const IcdManagement = Cluster( "have a dependency on the UserActiveModeTriggerInstruction attribute but do not require the " + "attribute to be present." + "\n" + - "An ICD can indicate multiple ways of being put into Active Mode by setting multiple bits in the " + + "### An ICD can indicate multiple ways of being put into Active Mode by setting multiple bits in the " + "bitmap at the same time. However, a device shall NOT set more than one bit which has a dependency " + "on the UserActiveModeTriggerInstruction attribute.", @@ -134,7 +135,7 @@ export const IcdManagement = Cluster( Attribute({ name: "UserActiveModeTriggerInstruction", id: 0x7, type: "string", access: "R V", - conformance: "P, desc", constraint: "max 128", default: "", quality: "F", + conformance: "desc", constraint: "max 128", default: "", quality: "F", details: "The meaning of the attribute is dependent upon the UserActiveModeTriggerHint attribute value, and " + "the conformance is in indicated in the \"dependency\" column in UserActiveModeTriggerHint table. The " + @@ -142,9 +143,8 @@ export const IcdManagement = Cluster( "device to Active Mode. If the attribute is present, the value shall be encoded as a valid UTF-8 " + "string with a maximum length of 128 bytes. If the UserActiveModeTriggerHint has the " + "ActuateSensorSeconds, ActuateSensorTimes, ResetButtonSeconds, ResetButtonTimes, SetupButtonSeconds " + - "or SetupButtonTimes set, the string shall consist solely of an encoding of N as a decimal" + - "\n" + - "unsigned integer using the ASCII digits 0-9, and without leading zeros." + + "or SetupButtonTimes set, the string shall consist solely of an encoding of N as a decimal unsigned " + + "integer using the ASCII digits 0-9, and without leading zeros." + "\n" + "For example, given UserActiveModeTriggerHint=\"2048\", ResetButtonTimes is set which indicates \"Press " + "Reset Button for N seconds\". Therefore, a value of UserActiveModeTriggerInstruction=\"10\" would " + @@ -155,19 +155,17 @@ export const IcdManagement = Cluster( "indicated in the Device’s currently configured locale). The Custom Instruction option SHOULD NOT be " + "used by an ICD that does not have knowledge of the user’s language preference." + "\n" + - "### When the UserActiveModeTriggerHint key indicates a light to blink (ActuateSensorLightsBlink, " + + "When the UserActiveModeTriggerHint key indicates a light to blink (ActuateSensorLightsBlink, " + "ResetButtonLightsBlink or SetupButtonLightsBlink), information on color of light may be made " + "available via the UserActiveModeTriggerInstruction attribute. When using such color indication in " + - "the UserActiveModeTriggerInstruction attribute, only basic primary and secondary colors that could " + - "unambiguously be decoded by a commissioner and understood by an end-user, but without worry of " + - "localization, SHOULD be used, e.g. white, red, green, blue, orange, yellow, purple. The length of " + - "the attribute SHOULD be kept small.", + "the UserActiveModeTriggerInstruction attribute, the string shall consist of exactly 6 hexadecimal " + + "digits using the ASCII characters 0-F and encoding the RGB color value as used in HTML encodings.", xref: { document: "core", section: "9.17.6.8" } }), Attribute({ - name: "OperatingMode", id: 0x8, type: "OperatingModeEnum", access: "R V", conformance: "P, LITS", + name: "OperatingMode", id: 0x8, type: "OperatingModeEnum", access: "R V", conformance: "LITS", details: "Indicates the operating mode of the ICD as specified in the OperatingModeEnum." + "\n" + " • If the ICD is operating as a LIT ICD, OperatingMode shall be LIT." + @@ -176,6 +174,16 @@ export const IcdManagement = Cluster( xref: { document: "core", section: "9.17.6.9" } }), + Attribute({ + name: "MaximumCheckInBackoff", id: 0x9, type: "uint32", access: "R V", conformance: "CIP", + constraint: "idleModeDuration to 64800", default: 1, quality: "F", + details: "Indicates the maximum time in seconds between two Check-In messages when back-off is active. The " + + "MaximumCheckInBackoff shall NOT be smaller than the IdleModeDuration." + + "\n" + + "If the MaximumCheckInBackoff is equal to the IdleModeDuration, it means the ICD does notback- off.", + xref: { document: "core", section: "9.17.6.10" } + }), + Command( { name: "RegisterClient", id: 0x0, access: "F M", conformance: "CIP", direction: "request", @@ -217,6 +225,12 @@ export const IcdManagement = Cluster( "with administrator permissions for the server cluster.", xref: { document: "core", section: "9.17.7.1.4" } + }), + + Field({ + name: "ClientType", id: 0x4, type: "ClientTypeEnum", conformance: "M", + details: "This field shall provide the client type of the client registering.", + xref: { document: "core", section: "9.17.7.1.5" } }) ), @@ -380,13 +394,31 @@ export const IcdManagement = Cluster( ), Datatype( - { name: "MonitoringRegistrationStruct", type: "struct", xref: { document: "core", section: "9.17.5.2" } }, + { name: "ClientTypeEnum", type: "enum8", xref: { document: "core", section: "9.17.5.1.1" } }, + Field({ + name: "Permanent", id: 0x0, conformance: "M", + description: "The client is typically resident, always-on, fixed infrastructure in the home." + }), + Field({ + name: "Ephemeral", id: 0x1, conformance: "M", + description: "The client is mobile or non-resident or not always-on and may not always be available in the home." + }) + ), + + Datatype( + { name: "OperatingModeEnum", type: "enum8", xref: { document: "core", section: "9.17.5.2" } }, + Field({ name: "Sit", id: 0x0, conformance: "M", description: "ICD is operating as a Short Idle Time ICD." }), + Field({ name: "Lit", id: 0x1, conformance: "M", description: "ICD is operating as a Long Idle Time ICD." }) + ), + + Datatype( + { name: "MonitoringRegistrationStruct", type: "struct", xref: { document: "core", section: "9.17.5.3" } }, Field({ name: "CheckInNodeId", id: 0x1, type: "node-id", access: "S", conformance: "M", quality: "N", details: "This field shall indicate the NodeID of the Node to which Check-In messages will be sent when the " + "MonitoredSubject is not subscribed.", - xref: { document: "core", section: "9.17.5.2.1" } + xref: { document: "core", section: "9.17.5.3.1" } }), Field({ @@ -407,21 +439,25 @@ export const IcdManagement = Cluster( "For example, if the MonitoredSubject is Node ID 0x1111_2222_3333_AAAA, and one of the subscribers " + "to the server on the entry’s associated fabric bears that Node ID, then the entry matches." + "\n" + - "Another example is if the MonitoredSubject has the value 0xFFFF_FFFD_AA12_0002, and one of the " + + "Another example is if the MonitoredSubject has the value 0xFFFF_FFFD_AA12_0002, and one of the" + + "\n" + "subscribers to the server on the entry’s associated fabric bears the CASE Authenticated TAG value " + "0xAA12 and the version 0x0002 or higher within its NOC, then the entry matches.", - xref: { document: "core", section: "9.17.5.2.2" } + xref: { document: "core", section: "9.17.5.3.2" } }), Field({ name: "Key", id: 0x3, access: "F", conformance: "D" }), - Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) - ), - Datatype( - { name: "OperatingModeEnum", type: "enum8", xref: { document: "core", section: "9.17.5.3" } }, - Field({ name: "Sit", id: 0x0, conformance: "M", description: "ICD is operating as a Short Idle Time ICD." }), - Field({ name: "Lit", id: 0x1, conformance: "M", description: "ICD is operating as a Long Idle Time ICD." }) + Field({ + name: "ClientType", id: 0x4, type: "ClientTypeEnum", access: "S", conformance: "M", default: 0, + quality: "N", + details: "This field shall indicate the client’s type to inform the ICD of the availability for communication " + + "of the client.", + xref: { document: "core", section: "9.17.5.4" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) ) ); diff --git a/packages/model/src/standard/elements/Identify.ts b/packages/model/src/standard/elements/Identify.ts index 21a860e40a..d8bacd1db4 100644 --- a/packages/model/src/standard/elements/Identify.ts +++ b/packages/model/src/standard/elements/Identify.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -32,13 +32,13 @@ export const Identify = Cluster( xref: { document: "cluster", section: "1.2" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 5 }), Attribute({ name: "IdentifyTime", id: 0x0, type: "uint16", access: "RW VO", conformance: "M", default: 0, - details: "This attribute specifies the remaining length of time, in seconds, that the endpoint will continue " + - "to identify itself." + + details: "Indicates the remaining length of time, in seconds, that the endpoint will continue to identify " + + "itself." + "\n" + "If this attribute is set to a value other than 0 then the device shall enter its identification " + "state, in order to indicate to an observer which of several nodes and/or endpoints it is. It is " + @@ -54,11 +54,11 @@ export const Identify = Cluster( Attribute({ name: "IdentifyType", id: 0x1, type: "IdentifyTypeEnum", access: "R V", conformance: "M", constraint: "desc", - details: "This attribute specifies how the identification state is presented to the user." + + details: "Indicates how the identification state is presented to the user." + "\n" + - "This field shall contain one of the values defined in IdentifyTypeEnum. The value None shall NOT be " + - "used if the device is capable of presenting its identification state using one of the other methods " + - "defined in IdentifyTypeEnum.", + "This attribute shall contain one of the values defined in IdentifyTypeEnum. The value None shall " + + "NOT be used if the device is capable of presenting its identification state using one of the other " + + "methods defined in IdentifyTypeEnum.", xref: { document: "cluster", section: "1.2.5.2" } }), @@ -90,8 +90,8 @@ export const Identify = Cluster( name: "EffectIdentifier", id: 0x0, type: "EffectIdentifierEnum", conformance: "M", constraint: "desc", - details: "This field specifies the identify effect to use and shall contain one of the non-reserved values in " + - "EffectIdentifierEnum." + + details: "This field shall indicate the identify effect to use and shall contain one of the non-reserved " + + "values in EffectIdentifierEnum." + "\n" + "All values of the EffectIdentifierEnum shall be supported. Implementors may deviate from the " + "example light effects in EffectIdentifierEnum, but they SHOULD indicate during testing how they " + @@ -102,9 +102,9 @@ export const Identify = Cluster( Field({ name: "EffectVariant", id: 0x1, type: "EffectVariantEnum", conformance: "M", constraint: "desc", - details: "This field is used to indicate which variant of the effect, indicated in the EffectIdentifier " + - "field, SHOULD be triggered. If a device does not support the given variant, it shall use the " + - "default variant. This field shall contain one of the values in EffectVariantEnum.", + details: "This field shall indicate which variant of the effect, indicated in the EffectIdentifier field, " + + "SHOULD be triggered. If a device does not support the given variant, it shall use the default " + + "variant. This field shall contain one of the values in EffectVariantEnum.", xref: { document: "cluster", section: "1.2.6.2.2" } }) ), diff --git a/packages/model/src/standard/elements/IlluminanceMeasurement.ts b/packages/model/src/standard/elements/IlluminanceMeasurement.ts index 19d14bfc9b..b19edab281 100644 --- a/packages/model/src/standard/elements/IlluminanceMeasurement.ts +++ b/packages/model/src/standard/elements/IlluminanceMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -29,7 +29,7 @@ export const IlluminanceMeasurement = Cluster( name: "MeasuredValue", id: 0x0, type: "uint16", access: "R V", conformance: "M", constraint: "0, minMeasuredValue to maxMeasuredValue", default: 0, quality: "X P", - details: "The MeasuredValue attribute represents the illuminance in Lux (symbol lx) as follows:" + + details: "Indicates the illuminance in Lux (symbol lx) as follows:" + "\n" + " • MeasuredValue = 10,000 x log10(illuminance) + 1," + "\n" + @@ -50,23 +50,22 @@ export const IlluminanceMeasurement = Cluster( Attribute({ name: "MinMeasuredValue", id: 0x1, type: "uint16", access: "R V", conformance: "M", - constraint: "1 to maxMeasuredValue1", quality: "X", - details: "The MinMeasuredValue attribute indicates the minimum value of MeasuredValue that can be measured. A " + - "value of null indicates that this attribute is not defined. See Measured Value for more details.", + constraint: "1 to 65533", quality: "X", + details: "Indicates the minimum value of MeasuredValue that can be measured. A value of null indicates that " + + "this attribute is not defined. See Measured Value for more details.", xref: { document: "cluster", section: "2.2.5.2" } }), Attribute({ name: "MaxMeasuredValue", id: 0x2, type: "uint16", access: "R V", conformance: "M", - constraint: "minMeasuredValue1 to 65534", quality: "X", - details: "The MaxMeasuredValue attribute indicates the maximum value of MeasuredValue that can be measured. A " + - "value of null indicates that this attribute is not defined. See Measured Value for more details.", + constraint: "min minMeasuredValue + 1", quality: "X", + details: "Indicates the maximum value of MeasuredValue that can be measured. A value of null indicates that " + + "this attribute is not defined. See Measured Value for more details.", xref: { document: "cluster", section: "2.2.5.3" } }), Attribute({ - name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", - constraint: "0 to 2048", + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", details: "See Measured Value.", xref: { document: "cluster", section: "2.2.5.4" } }), @@ -74,9 +73,8 @@ export const IlluminanceMeasurement = Cluster( Attribute({ name: "LightSensorType", id: 0x4, type: "uint8", access: "R V", conformance: "O", default: null, quality: "X", - details: "The LightSensorType attribute specifies the electronic type of the light sensor. This attribute " + - "shall be set to one of the non-reserved values listed in LightSensorTypeEnum or null in case the " + - "sensor type is unknown.", + details: "Indicates the electronic type of the light sensor. This attribute shall be set to one of the " + + "non-reserved values listed in LightSensorTypeEnum or null in case the sensor type is unknown.", xref: { document: "cluster", section: "2.2.5.5" } }), diff --git a/packages/model/src/standard/elements/JointFabricAdministratorDT.ts b/packages/model/src/standard/elements/JointFabricAdministratorDT.ts new file mode 100644 index 0000000000..12ce25b6a3 --- /dev/null +++ b/packages/model/src/standard/elements/JointFabricAdministratorDT.ts @@ -0,0 +1,40 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const JointFabricAdministratorDt = DeviceType( + { + name: "JointFabricAdministrator", id: 0x130, category: "Utility", classification: "utility", + + details: "A Joint Fabric Administrator device provides capabilities to manage the Joint Fabric Datastore and " + + "issue an ICAC signed by the Joint Fabric Anchor Root CA." + + "\n" + + "A client wanting to access the capabilities of the Joint Fabric Administrator may use the Joint " + + "Commissioning Method to be commissioned onto the Joint Fabric. Once commissioned, a client may " + + "access the capabilities of the Joint Fabric Administrator.", + + xref: { document: "device", section: "2.9" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 304, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "JointFabricDatastore", id: 0x752, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.9.4" } + }), + Requirement({ + name: "JointFabricPki", id: 0x753, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.9.4" } + }) +); + +MatterDefinition.children.push(JointFabricAdministratorDt); diff --git a/packages/model/src/standard/elements/JointFabricDatastoreCluster.ts b/packages/model/src/standard/elements/JointFabricDatastoreCluster.ts new file mode 100644 index 0000000000..e96c65f411 --- /dev/null +++ b/packages/model/src/standard/elements/JointFabricDatastoreCluster.ts @@ -0,0 +1,520 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + FieldElement as Field, + CommandElement as Command, + DatatypeElement as Datatype +} from "../../elements/index.js"; + +export const JointFabricDatastoreCluster = Cluster( + { + name: "JointFabricDatastoreCluster", id: 0x752, classification: "node", pics: "JFDS", + + details: "The Joint Fabric Datastore Cluster is a cluster that provides a mechanism for the Joint Fabric " + + "Administrators to manage the set of Nodes, Groups, and Group membership among Nodes in the Joint " + + "Fabric." + + "\n" + + "When an Ecosystem Administrator Node is commissioned onto the Joint Fabric, the Ecosystem " + + "Administrator Node has no knowledge of what Nodes and Groups are present, or what set-up " + + "information related to the Joint Fabric is provided by the user. To address lack of knowledge, the " + + "Joint Fabric Datastore provides the information required for all Ecosystem Administrators to " + + "maintain a consistent view of the Joint Fabric including Nodes, Groups, settings and privileges." + + "\n" + + "The Joint Fabric Datastore cluster server shall only be accessible on a Node which is acting as the " + + "Joint Fabric Anchor Administrator. When not acting as the Joint Fabric Anchor Administrator, the " + + "Joint Fabric Datastore cluster shall NOT be accessible." + + "\n" + + "The Admin level of access to the Joint Fabric Datastore cluster server shall be limited to JF " + + "Administrator Nodes identified using the Administrator CAT." + + "\n" + + "NOTE Support for Joint Fabric Datastore cluster is provisional.", + + xref: { document: "core", section: "11.24" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "AnchorRootCa", id: 0x0, type: "octstr", access: "R S A", conformance: "M", + details: "This shall indicate the Anchor Root CA used to sign all NOC Issuers in the Joint Fabric. A null " + + "value indicates that the Joint Fabric is not yet formed.", + xref: { document: "core", section: "11.24.6.1" } + }), + + Attribute({ + name: "AnchorNodeId", id: 0x1, type: "node-id", access: "R S A", conformance: "M", + details: "This shall indicate the Node identifier of the Joint Fabric Anchor Root CA.", + xref: { document: "core", section: "11.24.6.2" } + }), + Attribute({ + name: "AnchorVendorId", id: 0x2, type: "vendor-id", access: "R S A", conformance: "M", + details: "This shall indicate the Vendor identifier of the Joint Fabric Anchor Root CA.", + xref: { document: "core", section: "11.24.6.3" } + }), + + Attribute({ + name: "FriendlyName", id: 0x3, type: "string", access: "R S A", conformance: "M", + constraint: "max 32", + details: "Friendly name for this fabric which can be propagated to nodes.", + xref: { document: "core", section: "11.24.6.4" } + }), + + Attribute( + { + name: "GroupKeySetList", id: 0x4, type: "list", access: "R S A", conformance: "M", + details: "This shall indicate the list of GroupKeySetStruct used in the Joint Fabric." + + "\n" + + "This attribute shall contain at least one entry, the IPK, which has GroupKeySetID of 0.", + xref: { document: "core", section: "11.24.6.5" } + }, + + Field({ name: "entry", type: "GroupKeyManagement.GroupKeySetStruct" }) + ), + + Attribute( + { + name: "GroupList", id: 0x5, type: "list", access: "R S A", conformance: "M", + details: "This shall indicate the list of groups in the Joint Fabric.", + xref: { document: "core", section: "11.24.6.6" } + }, + Field({ name: "entry", type: "DatastoreGroupInformationEntry" }) + ), + + Attribute( + { + name: "NodeList", id: 0x6, type: "list", access: "R S A", conformance: "M", + details: "This shall indicate the list of nodes in the Joint Fabric.", + xref: { document: "core", section: "11.24.6.7" } + }, + Field({ name: "entry", type: "DatastoreNodeInformationEntry" }) + ), + + Attribute( + { + name: "AdminList", id: 0x7, type: "list", access: "R S A", conformance: "M", + + details: "This shall indicate the list of administrators in the Joint Fabric." + + "\n" + + "Only one Administrator may serve as the Anchor Root CA and Anchor Fabric Administrator and shall " + + "have index value 0. All other Joint Fabric Administrators shall be referenced at index 1 or greater." + + "\n" + + "A null value or empty list indicates that the Joint Fabric is not yet formed.", + + xref: { document: "core", section: "11.24.6.8" } + }, + + Field({ name: "entry", type: "DatastoreAdministratorInformationEntry" }) + ), + + Attribute({ + name: "StatusEntry", id: 0x8, type: "DatastoreAdministratorInformationEntry", access: "R S A", + conformance: "M", + details: "This shall indicate the current state of the Joint Fabric Datastore Cluster." + + "\n" + + "The Committed status indicates the DataStore is ready for use. The Pending status indicates that " + + "the DataStore is not yet ready for use. The DeletePending status indicates that the DataStore is in " + + "the process of being transferred to another Joint Fabric Anchor Administrator.", + xref: { document: "core", section: "11.24.6.9" } + }), + + Command({ + name: "Section112471", id: 0x0, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112472", id: 0x1, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112473", id: 0x2, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112474", id: 0x3, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112475", id: 0x4, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112476", id: 0x5, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112477", id: 0x6, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112478", id: 0x7, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section112479", id: 0x8, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124710", id: 0x9, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124711", id: 0xa, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124712", id: 0xb, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124713", id: 0xc, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124714", id: 0xd, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124715", id: 0xe, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124716", id: 0xf, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124717", id: 0x10, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124718", id: 0x11, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124719", id: 0x12, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + Command({ + name: "Section1124720", id: 0x13, access: "F A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.24.7" } + }), + + Datatype( + { name: "DatastoreStateEnum", type: "enum8", xref: { document: "core", section: "11.24.5.1" } }, + Field({ name: "Pending", id: 0x0, conformance: "M", description: "Target device operation is pending" }), + Field({ name: "Committed", id: 0x1, conformance: "M", description: "Target device operation has been committed" }), + Field({ name: "DeletePending", id: 0x2, conformance: "M", description: "Target device delete operation is pending" }) + ), + + Datatype( + { name: "DatastoreStatusEntry", type: "struct", xref: { document: "core", section: "11.24.5.2" } }, + Field({ + name: "State", id: 0x0, type: "DatastoreStateEnum", access: "R F V", conformance: "M", default: 0, + details: "This field shall contain the current state of the target device operation.", + xref: { document: "core", section: "11.24.5.2.1" } + }), + Field({ + name: "UpdateTimestamp", id: 0x1, type: "epoch-s", access: "R F V", conformance: "M", default: null, + details: "This field shall contain the timestamp of the last update.", + xref: { document: "core", section: "11.24.5.2.2" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreNodeKeyEntry", type: "struct", xref: { document: "core", section: "11.24.5.3" } }, + Field({ name: "GroupKeySetId", id: 0x0, type: "uint16", access: "R F V", conformance: "M" }), + Field({ + name: "StatusEntry", id: 0x1, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether entry in this list is pending, committed, or delete-pending.", + xref: { document: "core", section: "11.24.5.3.2" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreGroupInformationEntry", type: "struct", xref: { document: "core", section: "11.24.5.4" } }, + Field({ + name: "GroupId", id: 0x0, type: "uint64", access: "R F V", conformance: "M", + details: "The unique identifier for the group.", + xref: { document: "core", section: "11.24.5.4.1" } + }), + + Field({ + name: "FriendlyName", id: 0x1, type: "string", access: "R F V", conformance: "M", + constraint: "max 32", + details: "The friendly name for the group.", + xref: { document: "core", section: "11.24.5.4.2" } + }), + + Field({ + name: "GroupKeySetId", id: 0x2, type: "uint16", access: "R F V", conformance: "M", + constraint: "1 to 65535", + details: "The unique identifier for the group key set.", + xref: { document: "core", section: "11.24.5.4.3" } + }), + + Field({ + name: "GroupCat", id: 0x3, type: "uint16", access: "R F V", conformance: "M", + constraint: "1 to 65535", + details: "CAT value for this group. This is used for control of individual members of a group (non-broadcast " + + "commands).", + xref: { document: "core", section: "11.24.5.4.4" } + }), + + Field({ + name: "GroupCatVersion", id: 0x4, type: "uint16", access: "R F V", conformance: "M", + constraint: "1 to 65535", + details: "Current version number for this CAT.", + xref: { document: "core", section: "11.24.5.4.5" } + }), + + Field({ + name: "GroupPermission", id: 0x5, type: "AccessControl.AccessControlEntryPrivilegeEnum", + access: "R F V", conformance: "M", + details: "The permission level associated with ACL entries for this group. There should be only one " + + "Administrator group per fabric, and at most one Manage group per Ecosystem (Vendor Entry).", + xref: { document: "core", section: "11.24.5.4.6" } + }), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreBindingEntry", type: "struct", xref: { document: "core", section: "11.24.5.4.7" } }, + Field({ + name: "ListId", id: 0x0, type: "uint16", access: "R F V", conformance: "M", + details: "The unique identifier for the Binding entry in the Datastore’s list of DatastoreBindingEntry.", + xref: { document: "core", section: "11.24.5.4.7.1" } + }), + + Field({ + name: "Binding", id: 0x1, type: "Binding.TargetStruct", access: "R F V", conformance: "M", + constraint: "desc", + details: "The binding target structure.", + xref: { document: "core", section: "11.24.5.4.7.2" } + }), + + Field({ + name: "StatusEntry", id: 0x2, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether entry in this list is pending, committed, or delete-pending.", + xref: { document: "core", section: "11.24.5.4.7.3" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreGroupIDEntry", type: "struct", xref: { document: "core", section: "11.24.5.5" } }, + Field({ + name: "GroupId", id: 0x0, type: "group-id", access: "R F V", conformance: "M", + details: "The unique identifier for the group.", + xref: { document: "core", section: "11.24.5.5.1" } + }), + Field({ + name: "StatusEntry", id: 0x1, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether entry in this list is pending, committed, or delete-pending.", + xref: { document: "core", section: "11.24.5.5.2" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreEndpointEntry", type: "struct", xref: { document: "core", section: "11.24.5.6" } }, + Field({ + name: "EndpointId", id: 0x0, type: "endpoint-no", access: "R F V", conformance: "M", + details: "The unique identifier for the endpoint.", + xref: { document: "core", section: "11.24.5.6.1" } + }), + Field({ + name: "NodeId", id: 0x1, type: "node-id", access: "R F V", conformance: "M", + details: "The unique identifier for the node.", + xref: { document: "core", section: "11.24.5.6.2" } + }), + + Field({ + name: "FriendlyName", id: 0x2, type: "string", access: "R F V", conformance: "M", + constraint: "max 32", + details: "Friendly name for this endpoint which is propagated to nodes. Any changes to Friendly Name or Group " + + "Id List (add/remove entry) must follow the pending→committed workflow with current state reflected " + + "in the Status Entry.", + xref: { document: "core", section: "11.24.5.6.3" } + }), + + Field({ + name: "StatusEntry", id: 0x3, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether changes to Friendly Name are pending or committed.", + xref: { document: "core", section: "11.24.5.6.4" } + }), + + Field( + { + name: "GroupIdList", id: 0x4, type: "list", access: "R F V", conformance: "M", + details: "List of Group IDs that this endpoint is a member of. Any changes to Group Id List (add/remove " + + "entry) must follow the pending→committed workflow with current state reflected in the Status Entry.", + xref: { document: "core", section: "11.24.5.6.5" } + }, + + Field({ name: "entry", type: "DatastoreGroupIDEntry" }) + ), + + Field( + { + name: "BindingList", id: 0x5, type: "list", access: "R F V", conformance: "M", + details: "List of Binding Targets for this endpoint. Any changes to Binding List (add/remove entry) must " + + "follow the pending→committed workflow with current state reflected in the Status Entry.", + xref: { document: "core", section: "11.24.5.6.6" } + }, + + Field({ name: "entry", type: "DatastoreBindingEntry" }) + ), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreACLEntry", type: "struct", xref: { document: "core", section: "11.24.5.7" } }, + Field({ + name: "ListId", id: 0x0, type: "uint16", access: "R F V", conformance: "M", + details: "The unique identifier for the ACL entry in the Datastore’s list of DatastoreACLEntry.", + xref: { document: "core", section: "11.24.5.7.1" } + }), + + Field({ + name: "AclEntry", id: 0x1, type: "AccessControl.AccessControlEntryStruct", access: "R F V", + conformance: "M", + details: "The Access Control Entry structure.", + xref: { document: "core", section: "11.24.5.7.2" } + }), + + Field({ + name: "StatusEntry", id: 0x2, type: "DatastoreStatusEntry", access: "R F V", conformance: "M", + details: "Indicates whether entry in this list is pending, committed, or delete-pending.", + xref: { document: "core", section: "11.24.5.7.3" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { name: "DatastoreNodeInformationEntry", type: "struct", xref: { document: "core", section: "11.24.5.8" } }, + Field({ + name: "NodeId", id: 0x1, type: "node-id", access: "R F V", conformance: "M", + details: "The unique identifier for the node.", + xref: { document: "core", section: "11.24.5.8.1" } + }), + + Field({ + name: "FriendlyName", id: 0x2, type: "string", access: "R F V", conformance: "M", + constraint: "max 32", + details: "Friendly name for this node which is not propagated to nodes.", + xref: { document: "core", section: "11.24.5.8.2" } + }), + + Field({ + name: "CommissioningStatusEntry", id: 0x3, type: "DatastoreStatusEntry", access: "R F V", + conformance: "M", + details: "Set to pending prior to completing commissioning, and set to completed after commissioning complete " + + "is successful.", + xref: { document: "core", section: "11.24.5.8.3" } + }), + + Field( + { + name: "NodeKeySetList", id: 0x4, type: "list", access: "R F V", conformance: "M", + details: "List of Key Set information for the given Node. Updates to the Group Key List must follow the " + + "pending→committed workflow with current state reflected in the Status Entry for the corresponding " + + "entry in the list.", + xref: { document: "core", section: "11.24.5.8.4" } + }, + + Field({ name: "entry", type: "DatastoreNodeKeyEntry" }) + ), + + Field( + { + name: "AclList", id: 0x5, type: "list", access: "R F V", conformance: "M", + details: "List of ACL entries. Group membership for this node is inferred from the ACLs. Client access to a " + + "Node Information Entry will be determined from the ACL List. Any changes to ACL List (add/remove " + + "entry) must follow the pending→committed workflow with current state reflected in the Status Entry " + + "for the corresponding entry in the list.", + xref: { document: "core", section: "11.24.5.8.5" } + }, + + Field({ name: "entry", type: "DatastoreACLEntry" }) + ), + + Field( + { + name: "EndpointList", id: 0x6, type: "list", access: "R F V", conformance: "M", + details: "The list of endpoints for this node. Any changes to Endpoint List (add/remove entry) must follow " + + "the pending→committed workflow with current state reflected in the Status Entry for the " + + "corresponding entry in the list.", + xref: { document: "core", section: "11.24.5.8.6" } + }, + + Field({ name: "entry", type: "DatastoreEndpointEntry" }) + ), + + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ), + + Datatype( + { + name: "DatastoreAdministratorInformationEntry", type: "struct", + xref: { document: "core", section: "11.24.5.9" } + }, + Field({ + name: "NodeId", id: 0x1, type: "node-id", access: "R F V", conformance: "M", + details: "The unique identifier for the node.", + xref: { document: "core", section: "11.24.5.9.1" } + }), + + Field({ + name: "FriendlyName", id: 0x2, type: "string", access: "R F V", conformance: "M", + constraint: "max 32", + details: "Friendly name for this node which is not propagated to nodes.", + xref: { document: "core", section: "11.24.5.9.2" } + }), + + Field({ + name: "VendorId", id: 0x3, type: "vendor-id", access: "R F V", conformance: "M", + details: "The Vendor ID for the node.", + xref: { document: "core", section: "11.24.5.9.3" } + }), + Field({ + name: "Icac", id: 0x4, type: "octstr", access: "R F V", conformance: "M", constraint: "max 400", + details: "The ICAC used to issue the NOC.", + xref: { document: "core", section: "11.24.5.9.4" } + }), + Field({ name: "FabricIndex", id: 0xfe, type: "FabricIndex" }) + ) +); + +MatterDefinition.children.push(JointFabricDatastoreCluster); diff --git a/packages/model/src/standard/elements/JointFabricPki.ts b/packages/model/src/standard/elements/JointFabricPki.ts new file mode 100644 index 0000000000..e6752b621c --- /dev/null +++ b/packages/model/src/standard/elements/JointFabricPki.ts @@ -0,0 +1,131 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + CommandElement as Command, + FieldElement as Field, + DatatypeElement as Datatype +} from "../../elements/index.js"; + +export const JointFabricPki = Cluster( + { + name: "JointFabricPki", id: 0x753, classification: "node", pics: "JFPKI", + details: "An instance of the Joint Fabric PKI Cluster only applies to Joint Fabric Administrator nodes " + + "fulfilling the role of Anchor CA." + + "\n" + + "NOTE Support for Joint Fabric PKI Cluster is provisional.", + xref: { document: "core", section: "11.25" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Command( + { + name: "IcacsrRequest", id: 0x0, access: "A", conformance: "M", direction: "request", + response: "IcacsrResponse", + details: "This command shall be generated and executed during the Joint Commissioning Method steps and " + + "subsequently respond in the form of an ICACSRResponse command." + + "\n" + + "Check ICA Cross Signing for details about the generation and contents of the ICACSR.", + xref: { document: "core", section: "11.25.5.1" } + }, + + Field({ name: "Icacsr", id: 0x0, type: "octstr", conformance: "M", constraint: "max 400" }) + ), + + Command( + { + name: "IcacsrResponse", id: 0x1, access: "A", conformance: "M", direction: "response", + details: "This command shall be generated in response to the ICACSRRequest command. Check ICA Cross Signing " + + "for details about the generation and contents of ICAC.", + xref: { document: "core", section: "11.25.5.2" } + }, + + Field({ + name: "StatusCode", id: 0x0, type: "IcacsrRequestStatusEnum", conformance: "M", + details: "This field shall contain an ICACSRRequestStatusEnum value representing the status of the Section " + + "11.25.5.1, “ICACSRRequest Command” operation.", + xref: { document: "core", section: "11.25.5.2.1" } + }), + + Field({ + name: "Icac", id: 0x1, type: "octstr", conformance: "O", constraint: "max 400", + details: "If present, it shall contain the NOC Issuer Certificate in PEM format.", + xref: { document: "core", section: "11.25.5.2.2" } + }) + ), + + Command({ + name: "TransferAnchorRequest", id: 0x2, access: "A", conformance: "M", direction: "request", + response: "TransferAnchorResponse", + xref: { document: "core", section: "11.25.5" } + }), + Command({ + name: "TransferAnchorResponse", id: 0x3, access: "A", conformance: "M", direction: "response", + xref: { document: "core", section: "11.25.5" } + }), + Command({ + name: "TransferAnchorComplete", id: 0x4, access: "A", conformance: "M", direction: "request", + response: "status", + xref: { document: "core", section: "11.25.5" } + }), + + Datatype( + { + name: "IcacsrRequestStatusEnum", type: "enum8", + details: "This enumeration is used by the ICACSRResponse command to convey the detailed outcome of this " + + "cluster’s ICACSRRequest command.", + xref: { document: "core", section: "11.25.4.1" } + }, + + Field({ name: "Ok", id: 0x0, conformance: "M", description: "No error" }), + Field({ + name: "InvalidIcaCsrFormat", id: 0x1, conformance: "M", + description: "The ICACSR in the request is not compliant to PKCS #10 rules" + }), + Field({ + name: "InvalidIcaCsrSignature", id: 0x2, conformance: "M", + description: "The ICACSR in the request has an incorrect signature" + }), + Field({ + name: "FailedDclVendorIdValidation", id: 0x3, conformance: "M", + description: "DCL Vendor ID validation failed" + }), + Field({ name: "NotAnIcac", id: 0x4, conformance: "M", description: "DCL returned certificate is not an ICAC" }), + Field({ + name: "BusyAnchorTransfer", id: 0x5, conformance: "M", + description: "Error due to an in progress Anchor Transfer" + }), + Field({ name: "IcaCsrSigningFailed", id: 0x6, conformance: "M", description: "Signing the ICA CSR failed" }), + Field({ name: "IcaCsrRequestNoUserConsent", id: 0x7, conformance: "M", description: "No user consent" }) + ), + + Datatype( + { + name: "TransferAnchorResponseStatusEnum", type: "enum8", + details: "This enumeration is used by the TransferAnchorResponse command to convey the detailed outcome of " + + "this cluster’s TransferAnchorRequest command.", + xref: { document: "core", section: "11.25.4.2" } + }, + + Field({ name: "Ok", id: 0x0, conformance: "M", description: "No error" }), + Field({ + name: "TransferAnchorStatusDatastoreBusy", id: 0x1, conformance: "M", + description: "Anchor Transfer was not started due to on- going Datastore operations" + }), + Field({ + name: "TransferAnchorStatusNoUserConsent", id: 0x2, conformance: "M", + description: "User has not consented for Anchor Transfer" + }) + ) +); + +MatterDefinition.children.push(JointFabricPki); diff --git a/packages/model/src/standard/elements/KeypadInput.ts b/packages/model/src/standard/elements/KeypadInput.ts index 77cdecceaf..8a43b2ed87 100644 --- a/packages/model/src/standard/elements/KeypadInput.ts +++ b/packages/model/src/standard/elements/KeypadInput.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -83,9 +83,11 @@ export const KeypadInput = Cluster( Command( { name: "SendKeyResponse", id: 0x1, conformance: "M", direction: "response", - details: "This command shall be generated in response to a SendKey command.", + details: "This command shall be generated in response to a SendKey command. The data for this command shall " + + "be as follows:", xref: { document: "cluster", section: "6.8.6.2" } }, + Field({ name: "Status", id: 0x0, type: "StatusEnum", conformance: "M", details: "This field shall indicate the status of the request.", diff --git a/packages/model/src/standard/elements/Label.ts b/packages/model/src/standard/elements/Label.ts index a7f15bf9cc..651ecbde32 100644 --- a/packages/model/src/standard/elements/Label.ts +++ b/packages/model/src/standard/elements/Label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/LandmarkNamespaceNS.ts b/packages/model/src/standard/elements/LandmarkNamespaceNS.ts new file mode 100644 index 0000000000..781d6d0c92 --- /dev/null +++ b/packages/model/src/standard/elements/LandmarkNamespaceNS.ts @@ -0,0 +1,76 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + SemanticNamespaceElement as SemanticNamespace, + SemanticTagElement as SemanticTag +} from "../../elements/index.js"; + +export const LandmarkNamespaceNs = SemanticNamespace( + { + name: "LandmarkNamespace", id: 0x11, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a home landmark.", + xref: { document: "namespace", section: "10" } + }, + + SemanticTag({ name: "Air Conditioner", id: 0x0 }), + SemanticTag({ name: "Air Purifier", id: 0x1 }), + SemanticTag({ name: "Back Door", id: 0x2 }), + SemanticTag({ name: "Bar Stool", id: 0x3 }), + SemanticTag({ name: "Bath Mat", id: 0x4 }), + SemanticTag({ name: "Bathtub", id: 0x5 }), + SemanticTag({ name: "Bed", id: 0x6 }), + SemanticTag({ name: "Bookshelf", id: 0x7 }), + SemanticTag({ name: "Chair", id: 0x8 }), + SemanticTag({ name: "Christmas Tree", id: 0x9 }), + SemanticTag({ name: "Coat Rack", id: 0xa }), + SemanticTag({ name: "Coffee Table", id: 0xb }), + SemanticTag({ name: "Cooking Range", id: 0xc }), + SemanticTag({ name: "Couch", id: 0xd }), + SemanticTag({ name: "Countertop", id: 0xe }), + SemanticTag({ name: "Cradle", id: 0xf }), + SemanticTag({ name: "Crib", id: 0x10 }), + SemanticTag({ name: "Desk", id: 0x11 }), + SemanticTag({ name: "Dining Table", id: 0x12 }), + SemanticTag({ name: "Dishwasher", id: 0x13 }), + SemanticTag({ name: "Door", id: 0x14 }), + SemanticTag({ name: "Dresser", id: 0x15 }), + SemanticTag({ name: "Laundry Dryer", id: 0x16 }), + SemanticTag({ name: "Fan", id: 0x17 }), + SemanticTag({ name: "Fireplace", id: 0x18 }), + SemanticTag({ name: "Freezer", id: 0x19 }), + SemanticTag({ name: "Front Door", id: 0x1a }), + SemanticTag({ name: "High Chair", id: 0x1b }), + SemanticTag({ name: "Kitchen Island", id: 0x1c }), + SemanticTag({ name: "Lamp", id: 0x1d }), + SemanticTag({ name: "Litter Box", id: 0x1e }), + SemanticTag({ name: "Mirror", id: 0x1f }), + SemanticTag({ name: "Nightstand", id: 0x20 }), + SemanticTag({ name: "Oven", id: 0x21 }), + SemanticTag({ name: "Pet Bed", id: 0x22 }), + SemanticTag({ name: "Pet Bowl", id: 0x23 }), + SemanticTag({ name: "Pet Crate", id: 0x24 }), + SemanticTag({ name: "Refrigerator", id: 0x25 }), + SemanticTag({ name: "Scratching Post", id: 0x26 }), + SemanticTag({ name: "Shoe Rack", id: 0x27 }), + SemanticTag({ name: "Shower", id: 0x28 }), + SemanticTag({ name: "Side Door", id: 0x29 }), + SemanticTag({ name: "Sink", id: 0x2a }), + SemanticTag({ name: "Sofa", id: 0x2b }), + SemanticTag({ name: "Stove", id: 0x2c }), + SemanticTag({ name: "Table", id: 0x2d }), + SemanticTag({ name: "Toilet", id: 0x2e }), + SemanticTag({ name: "Trash Can", id: 0x2f }), + SemanticTag({ name: "Laundry Washer", id: 0x30 }), + SemanticTag({ name: "Window", id: 0x31 }), + SemanticTag({ name: "Wine Cooler", id: 0x32 }) +); + +MatterDefinition.children.push(LandmarkNamespaceNs); diff --git a/packages/model/src/standard/elements/LaundryDryerControls.ts b/packages/model/src/standard/elements/LaundryDryerControls.ts index 55d6b631a3..62f4cae8ad 100644 --- a/packages/model/src/standard/elements/LaundryDryerControls.ts +++ b/packages/model/src/standard/elements/LaundryDryerControls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -26,12 +26,12 @@ export const LaundryDryerControls = Cluster( Attribute( { - name: "SupportedDrynessLevels", id: 0x0, type: "list", conformance: "M", constraint: "1 to 4", - details: "Indicates the list of supported dryness levels available to the appliance in the" + - "\n" + - "currently selected mode. The dryness level values are determined by the manufacturer. At least one " + - "dryness level value shall be provided in the SupportedDrynessLevels list. The list of dryness " + - "levels may change depending on the currently-selected Laundry Dryer mode.", + name: "SupportedDrynessLevels", id: 0x0, type: "list", access: "R V", conformance: "M", + constraint: "1 to 4", + details: "Indicates the list of supported dryness levels available to the appliance in the currently selected " + + "mode. The dryness level values are determined by the manufacturer. At least one dryness level value " + + "shall be provided in the SupportedDrynessLevels list. The list of dryness levels may change " + + "depending on the currently-selected Laundry Dryer mode.", xref: { document: "cluster", section: "8.9.5.1" } }, diff --git a/packages/model/src/standard/elements/LaundryDryerDT.ts b/packages/model/src/standard/elements/LaundryDryerDT.ts index 3f12a48f54..26f41f2011 100644 --- a/packages/model/src/standard/elements/LaundryDryerDT.ts +++ b/packages/model/src/standard/elements/LaundryDryerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/LaundryNS.ts b/packages/model/src/standard/elements/LaundryNS.ts index 5a5a3ca1a3..0c6ea415d0 100644 --- a/packages/model/src/standard/elements/LaundryNS.ts +++ b/packages/model/src/standard/elements/LaundryNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ export const LaundryNs = SemanticNamespace( name: "Laundry", id: 0xe, details: "The tags contained in this namespace are restricted for use in the laundry domain and shall NOT be " + "used in any other domain or context.", - xref: { document: "namespace", section: "11" } + xref: { document: "namespace", section: "14" } }, SemanticTag({ name: "Normal", id: 0x0 }), diff --git a/packages/model/src/standard/elements/LaundryWasherControls.ts b/packages/model/src/standard/elements/LaundryWasherControls.ts index 2f45fc5852..e28a765241 100644 --- a/packages/model/src/standard/elements/LaundryWasherControls.ts +++ b/packages/model/src/standard/elements/LaundryWasherControls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -22,20 +22,20 @@ export const LaundryWasherControls = Cluster( xref: { document: "cluster", section: "8.6" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.6.4" } }, Field({ - name: "SPIN", conformance: "O", constraint: "0", description: "Spin", + name: "SPIN", conformance: "O.a+", constraint: "0", description: "Spin", details: "This feature indicates multiple spin speeds are supported in at least one supported mode. Note that " + "some modes may not support multiple spin speeds even if this feature is supported.", xref: { document: "cluster", section: "8.6.4.1" } }), Field({ - name: "RINSE", conformance: "O", constraint: "1", description: "Rinse", + name: "RINSE", conformance: "O.a+", constraint: "1", description: "Rinse", details: "This feature indicates multiple rinse cycles are supported in at least one supported mode. Note " + "that some modes may not support selection of the number of rinse cycles even if this feature is " + "supported.", @@ -47,11 +47,11 @@ export const LaundryWasherControls = Cluster( { name: "SpinSpeeds", id: 0x0, type: "list", access: "R V", conformance: "SPIN", constraint: "max 16[max 64]", - details: "This attribute indicates the list of spin speeds available to the appliance in the currently " + - "selected mode. The spin speed values are determined by the manufacturer. At least one spin speed " + - "value shall be provided in the SpinSpeeds list. The list of spin speeds may change depending on the " + - "currently selected Laundry Washer mode. For example, Quick mode might have a completely different " + - "list of SpinSpeeds than Delicates mode.", + details: "Indicates the list of spin speeds available to the appliance in the currently selected mode. The " + + "spin speed values are determined by the manufacturer. At least one spin speed value shall be " + + "provided in the SpinSpeeds list. The list of spin speeds may change depending on the currently " + + "selected Laundry Washer mode. For example, Quick mode might have a completely different list of " + + "SpinSpeeds than Delicates mode.", xref: { document: "cluster", section: "8.6.6.1" } }, @@ -60,11 +60,11 @@ export const LaundryWasherControls = Cluster( Attribute({ name: "SpinSpeedCurrent", id: 0x1, type: "uint8", access: "RW VO", conformance: "SPIN", - constraint: "0 to 15", quality: "X", + constraint: "max 15", quality: "X", - details: "This attribute indicates the currently selected spin speed. It is the index into the SpinSpeeds " + - "list of the selected spin speed, as such, this attribute can be an integer between 0 and the number " + - "of entries in SpinSpeeds - 1. If a value is received that is outside of the defined constraints, a " + + details: "Indicates the currently selected spin speed. It is the index into the SpinSpeeds list of the " + + "selected spin speed, as such, this attribute can be an integer between 0 and the number of entries " + + "in SpinSpeeds - 1. If a value is received that is outside of the defined constraints, a " + "CONSTRAINT_ERROR shall be sent as the response. If a value is attempted to be written that doesn’t " + "match a valid index (e.g. an index of 5 when the list has 4 values), a CONSTRAINT_ERROR shall be " + "sent as the response. If null is written to this attribute, there will be no spin speed for the " + @@ -76,11 +76,14 @@ export const LaundryWasherControls = Cluster( Attribute({ name: "NumberOfRinses", id: 0x2, type: "NumberOfRinsesEnum", access: "RW VO", conformance: "RINSE", constraint: "desc", default: 1, - details: "This attribute represents how many times a rinse cycle shall be performed on a device for the " + - "current mode of operation. A value of None shall indicate that no rinse cycle will be performed. " + - "This value may be set by the client to adjust the number of rinses that are performed for the " + - "current mode of operation. If the device is not in a compatible state to accept the provided value, " + - "an INVALID_IN_STATE error shall be sent as the response.", + + details: "Indicates how many times a rinse cycle shall be performed on a device for the current mode of " + + "operation. A value of None shall indicate that no rinse cycle will be performed. This value may be " + + "set by the client to adjust the number of rinses that are performed for" + + "\n" + + "the current mode of operation. If the device is not in a compatible state to accept the provided " + + "value, an INVALID_IN_STATE error shall be sent as the response.", + xref: { document: "cluster", section: "8.6.6.3" } }), @@ -88,10 +91,9 @@ export const LaundryWasherControls = Cluster( { name: "SupportedRinses", id: 0x3, type: "list", access: "R V", conformance: "RINSE", constraint: "max 4", - details: "This attribute represents the amount of rinses allowed for a specific mode. Each entry shall " + - "indicate a NumberOfRinsesEnum value that is possible in the selected mode on the device. The value " + - "of this attribute may change at runtime based on the currently selected mode. Each entry shall be " + - "distinct.", + details: "Indicates the amount of rinses allowed for a specific mode. Each entry shall indicate a " + + "NumberOfRinsesEnum value that is possible in the selected mode on the device. The value of this " + + "attribute may change at runtime based on the currently selected mode. Each entry shall be distinct.", xref: { document: "cluster", section: "8.6.6.4" } }, diff --git a/packages/model/src/standard/elements/LaundryWasherDT.ts b/packages/model/src/standard/elements/LaundryWasherDT.ts index bd0312f05c..2e15ae7fe3 100644 --- a/packages/model/src/standard/elements/LaundryWasherDT.ts +++ b/packages/model/src/standard/elements/LaundryWasherDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/LaundryWasherMode.ts b/packages/model/src/standard/elements/LaundryWasherMode.ts index 98685ec0e3..09778bd9db 100644 --- a/packages/model/src/standard/elements/LaundryWasherMode.ts +++ b/packages/model/src/standard/elements/LaundryWasherMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,63 +10,77 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + DatatypeElement as Datatype } from "../../elements/index.js"; export const LaundryWasherMode = Cluster( { name: "LaundryWasherMode", id: 0x51, type: "ModeBase", classification: "application", pics: "LWM", - details: "This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced " + + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + "enumerated values for laundry washer as well as laundry dryer devices.", xref: { document: "cluster", section: "8.5" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), - Attribute({ name: "SupportedModes", id: 0x0, conformance: "M", xref: { document: "cluster", section: "8.5.5" } }), - Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.5.5" } }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.5.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), Attribute({ - name: "StartUpMode", id: 0x2, conformance: "P", - details: "If this attribute is supported, the device SHOULD initially set this to one of the supported modes " + - "that has the Normal tag associated with it. See the Mode Base cluster specification for full " + - "details about the StartUpMode attribute.", - xref: { document: "cluster", section: "8.5.5.1" } + name: "SupportedModes", id: 0x0, conformance: "M", + details: "At least one entry in the SupportedModes attribute shall include the Normal mode tag in the " + + "ModeTags field list.", + xref: { document: "cluster", section: "8.5.6.1" } }), - Attribute({ name: "OnMode", id: 0x3, conformance: "P", xref: { document: "cluster", section: "8.5.5" } }), + Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.5.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.5.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.5.6" } }), Datatype({ name: "ModeOptionStruct", type: "ModeOptionStruct", details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + - "ModeOptionStruct type. A blank field indicates no change." + - "\n" + - "At least one entry in the SupportedModes attribute shall include the Normal mode tag in the " + - "ModeTags field list.", - xref: { document: "cluster", section: "8.5.4.1" } + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "8.5.5.1" } }), Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.5.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.5.7.1" } }), Field({ name: "Normal", id: 0x4000, details: "The normal regime of operation.", - xref: { document: "cluster", section: "8.5.6.1.1" } + xref: { document: "cluster", section: "8.5.7.1.1" } }), Field({ name: "Delicate", id: 0x4001, details: "Mode optimized for washing delicate garments.", - xref: { document: "cluster", section: "8.5.6.1.2" } + xref: { document: "cluster", section: "8.5.7.1.2" } }), Field({ name: "Heavy", id: 0x4002, details: "Mode optimized for heavy washing.", - xref: { document: "cluster", section: "8.5.6.1.3" } + xref: { document: "cluster", section: "8.5.7.1.3" } }), Field({ name: "Whites", id: 0x4003, details: "Mode optimized for stain removal on white fabrics.", - xref: { document: "cluster", section: "8.5.6.1.4" } + xref: { document: "cluster", section: "8.5.7.1.4" } }) ) ); diff --git a/packages/model/src/standard/elements/LevelControl.ts b/packages/model/src/standard/elements/LevelControl.ts index e53f515474..3a90288523 100644 --- a/packages/model/src/standard/elements/LevelControl.ts +++ b/packages/model/src/standard/elements/LevelControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,7 @@ export const LevelControl = Cluster( xref: { document: "cluster", section: "1.6" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 5 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 6 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.6.4" } }, @@ -59,28 +59,55 @@ export const LevelControl = Cluster( Attribute({ name: "CurrentLevel", id: 0x0, type: "uint8", access: "R V", conformance: "M", - constraint: "minLevel to maxLevel", default: null, quality: "X N S", - details: "Indicates the current level of this device. The meaning of 'level' is device dependent.", + constraint: "minLevel to maxLevel", default: null, quality: "X N S Q", + + details: "Indicates the current level of this device. The meaning of 'level' is device dependent." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second, or" + + "\n" + + " • At the end of the movement/transition, or" + + "\n" + + " • When it changes from null to any other value and vice versa.", + xref: { document: "cluster", section: "1.6.6.2" } }), Attribute({ name: "RemainingTime", id: 0x1, type: "uint16", access: "R V", conformance: "LT", default: 0, + quality: "Q", + details: "Indicates the time remaining until the current command is complete - it is specified in 1/10ths of " + - "a second.", + "a second." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • When it changes from 0 to any value higher than 10, or" + + "\n" + + " • When it changes, with a delta larger than 10, caused by the invoke of a command, or" + + "\n" + + " • When it changes to 0." + + "\n" + + "For commands with a transition time or changes to the transition time less than 1 second, changes " + + "to this attribute shall NOT be reported." + + "\n" + + "As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the " + + "reporting of this attribute in order to keep track of the remaining duration.", + xref: { document: "cluster", section: "1.6.6.3" } }), Attribute({ name: "MinLevel", id: 0x2, type: "uint8", access: "R V", conformance: "[LT]", - constraint: "1 to maxLevel", default: 1, + constraint: "1 to 254", default: 1, details: "Indicates the minimum value of CurrentLevel that is capable of being assigned.", xref: { document: "cluster", section: "1.6.6.4" } }), Attribute({ name: "MinLevel", id: 0x2, type: "uint8", access: "R V", conformance: "[!LT]", - constraint: "0 to maxLevel", default: 0, + constraint: "max 254", default: 0, details: "Indicates the minimum value of CurrentLevel that is capable of being assigned.", xref: { document: "cluster", section: "1.6.6.4" } }), @@ -94,14 +121,23 @@ export const LevelControl = Cluster( Attribute({ name: "CurrentFrequency", id: 0x4, type: "uint16", access: "R V", conformance: "FQ", - constraint: "minFrequency to maxFrequency", default: 0, quality: "S P", - details: "Indicates the frequency at which the device is at CurrentLevel. A CurrentFrequency of 0 is unknown.", + constraint: "minFrequency to maxFrequency", default: 0, quality: "S P Q", + + details: "Indicates the frequency at which the device is at CurrentLevel. A CurrentFrequency of 0 is unknown." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once per second, or" + + "\n" + + " • At the start of the movement/transition, or" + + "\n" + + " • At the end of the movement/transition.", + xref: { document: "cluster", section: "1.6.6.6" } }), Attribute({ - name: "MinFrequency", id: 0x5, type: "uint16", access: "R V", conformance: "FQ", - constraint: "0 to maxFrequency", default: 0, + name: "MinFrequency", id: 0x5, type: "uint16", access: "R V", conformance: "FQ", default: 0, details: "Indicates the minimum value of CurrentFrequency that is capable of being assigned. MinFrequency " + "shall be less than or equal to MaxFrequency. A value of 0 indicates undefined.", xref: { document: "cluster", section: "1.6.6.7" } @@ -136,7 +172,7 @@ export const LevelControl = Cluster( details: "Indicates the value that the CurrentLevel attribute is set to when the OnOff attribute of an On/Off " + "cluster on the same endpoint is set to TRUE, as a result of processing an On/Off cluster command. " + "If the OnLevel attribute is not implemented, or is set to the null value, it has no effect. For " + - "more details see Effect of On/Off Commands on the CurrentLevel Attribute." + + "more details see Effect of On/Off Commands on the CurrentLevel attribute." + "\n" + "OnLevel represents a mandatory field that was previously not present or optional. Implementers " + "should be aware that older devices may not implement it.", @@ -165,7 +201,8 @@ export const LevelControl = Cluster( }), Attribute({ - name: "DefaultMoveRate", id: 0x14, type: "uint8", access: "RW VO", conformance: "O", quality: "X", + name: "DefaultMoveRate", id: 0x14, type: "uint8", access: "RW VO", conformance: "O", + constraint: "min 1", quality: "X", details: "Indicates the movement rate, in units per second, when a Move command is received with a null value " + "Rate parameter.", xref: { document: "cluster", section: "1.6.6.14" } @@ -219,7 +256,7 @@ export const LevelControl = Cluster( response: "status", xref: { document: "cluster", section: "1.6.7.1" } }, - Field({ name: "Level", id: 0x0, type: "uint8", conformance: "M", constraint: "0 to 254" }), + Field({ name: "Level", id: 0x0, type: "uint8", conformance: "M", constraint: "max 254" }), Field({ name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", quality: "X" }), Field({ name: "OptionsMask", id: 0x2, type: "Options", conformance: "M", constraint: "desc", default: 0 }), Field({ name: "OptionsOverride", id: 0x3, type: "Options", conformance: "M", constraint: "desc", default: 0 }) @@ -240,11 +277,13 @@ export const LevelControl = Cluster( name: "Rate", id: 0x1, type: "uint8", conformance: "M", quality: "X", details: "This field shall indicate the rate of movement in units per second. The actual rate of movement " + - "SHOULD be as close to this rate as the device is able. If the Rate field is equal to null, then the " + - "value in DefaultMoveRate attribute shall be used. However, if the Rate field is equal to null and " + - "the DefaultMoveRate attribute is not supported, or if the Rate field is equal to null and the value " + - "of the DefaultMoveRate attribute is equal to null, then the device SHOULD move as fast as it is " + - "able. If the device is not able to move at a variable rate, this field may be disregarded.", + "SHOULD be as close to this rate as the device is able. If the Rate field is null, then the value of " + + "the DefaultMoveRate attribute shall be used if that attribute is supported and its value is not " + + "null. If the Rate field is null and the DefaultMoveRate attribute is either not supported or set to " + + "null, then the device SHOULD move as fast as it is able. If the device is not able to move at a " + + "variable rate, this" + + "\n" + + "field may be disregarded.", xref: { document: "cluster", section: "1.6.7.2.2" } }), @@ -274,8 +313,10 @@ export const LevelControl = Cluster( details: "This field shall indicate the time that shall be taken to perform the step, in tenths of a second. " + "A step is a change in the CurrentLevel of StepSize units. The actual time taken SHOULD be as close " + - "to this as the device is able. If the TransitionTime field is equal to null, the device SHOULD move " + - "as fast as it is able." + + "to" + + "\n" + + "this as the device is able. If the TransitionTime field is equal to null, the device SHOULD move as " + + "fast as it is able." + "\n" + "If the device is not able to move at a variable rate, the TransitionTime field may be disregarded.", diff --git a/packages/model/src/standard/elements/LevelNS.ts b/packages/model/src/standard/elements/LevelNS.ts index 4c9bf03230..babb644752 100644 --- a/packages/model/src/standard/elements/LevelNS.ts +++ b/packages/model/src/standard/elements/LevelNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/LightSensorDT.ts b/packages/model/src/standard/elements/LightSensorDT.ts index 9b0c10aa06..f009ee48f1 100644 --- a/packages/model/src/standard/elements/LightSensorDT.ts +++ b/packages/model/src/standard/elements/LightSensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/LocalizationConfiguration.ts b/packages/model/src/standard/elements/LocalizationConfiguration.ts index f2c9dff954..9a82a9401f 100644 --- a/packages/model/src/standard/elements/LocalizationConfiguration.ts +++ b/packages/model/src/standard/elements/LocalizationConfiguration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -30,23 +30,20 @@ export const LocalizationConfiguration = Cluster( Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), - Attribute( - { - name: "ActiveLocale", id: 0x0, type: "string", access: "RW VM", conformance: "M", - constraint: "in supportedLocales", quality: "N", + Attribute({ + name: "ActiveLocale", id: 0x0, type: "string", access: "RW VM", conformance: "M", + constraint: "in SupportedLocales", quality: "N", - details: "The ActiveLocale attribute shall represent the locale that the Node is currently configured to use " + - "when conveying information. The ActiveLocale attribute shall be a Language Tag as defined by BCP47 " + - "[https://tools.ietf.org/rfc/bcp/bcp47.txt]. The ActiveLocale attribute shall have a default value " + - "assigned by the Vendor and shall be a value contained within the SupportedLocales attribute." + - "\n" + - "An attempt to write a value to ActiveLocale that is not present in SupportedLocales shall result in" + - "\n" + - "a CONSTRAINT_ERROR error.", + details: "The ActiveLocale attribute shall represent the locale that the Node is currently configured to use " + + "when conveying information. The ActiveLocale attribute shall be a Language Tag as defined by BCP47. " + + "The ActiveLocale attribute shall have a default value assigned by the Vendor and shall be a value " + + "contained within the SupportedLocales attribute." + + "\n" + + "An attempt to write a value to ActiveLocale that is not present in SupportedLocales shall result in " + + "a CONSTRAINT_ERROR error.", - xref: { document: "core", section: "11.3.4.1" } - } - ), + xref: { document: "core", section: "11.3.4.1" } + }), Attribute( { diff --git a/packages/model/src/standard/elements/LocationNS.ts b/packages/model/src/standard/elements/LocationNS.ts index c4b7bcf906..9a5d5fc31f 100644 --- a/packages/model/src/standard/elements/LocationNS.ts +++ b/packages/model/src/standard/elements/LocationNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/LowPower.ts b/packages/model/src/standard/elements/LowPower.ts index 695f6ce75a..5e004c0764 100644 --- a/packages/model/src/standard/elements/LowPower.ts +++ b/packages/model/src/standard/elements/LowPower.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/MeasurementAccuracyRangeStruct.ts b/packages/model/src/standard/elements/MeasurementAccuracyRangeStruct.ts index ea771e584e..d16e12bb3d 100644 --- a/packages/model/src/standard/elements/MeasurementAccuracyRangeStruct.ts +++ b/packages/model/src/standard/elements/MeasurementAccuracyRangeStruct.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/MeasurementAccuracyStruct.ts b/packages/model/src/standard/elements/MeasurementAccuracyStruct.ts index 457a6e580c..b8db05f680 100644 --- a/packages/model/src/standard/elements/MeasurementAccuracyStruct.ts +++ b/packages/model/src/standard/elements/MeasurementAccuracyStruct.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/MeasurementTypeEnum.ts b/packages/model/src/standard/elements/MeasurementTypeEnum.ts index a50200f1f5..a9f0277fe3 100644 --- a/packages/model/src/standard/elements/MeasurementTypeEnum.ts +++ b/packages/model/src/standard/elements/MeasurementTypeEnum.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/MediaInput.ts b/packages/model/src/standard/elements/MediaInput.ts index 8e14123200..cd51f5adc9 100644 --- a/packages/model/src/standard/elements/MediaInput.ts +++ b/packages/model/src/standard/elements/MediaInput.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -59,7 +59,8 @@ export const MediaInput = Cluster( { name: "SelectInput", id: 0x0, access: "O", conformance: "M", direction: "request", response: "status", - details: "Upon receipt, this command shall change the media input on the device to the input at a specific " + + details: "Upon receipt, this command shall change the media input on the device to the input at a specific" + + "\n" + "index in the Input List.", xref: { document: "cluster", section: "6.9.7.1" } }, diff --git a/packages/model/src/standard/elements/MediaPlayback.ts b/packages/model/src/standard/elements/MediaPlayback.ts index 6744f5fd80..76ed37b728 100644 --- a/packages/model/src/standard/elements/MediaPlayback.ts +++ b/packages/model/src/standard/elements/MediaPlayback.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -58,11 +58,14 @@ export const MediaPlayback = Cluster( Field({ name: "AA", constraint: "4", description: "AudioAdvance", - details: "This feature is for a device or app that supports playing audio during fast and slow advance and " + + + details: "This feature is for a device or app that supports playing audio during fast and slow advance and" + + "\n" + "rewind (e.g., while playback speed is not 1). A device that supports this feature may only support " + "playing audio during certain speeds." + "\n" + "A cluster implementing AA shall implement AS.", + xref: { document: "cluster", section: "6.10.4.5" } }) ), @@ -467,7 +470,7 @@ export const MediaPlayback = Cluster( xref: { document: "cluster", section: "6.10.7.12.1" } }), Field({ - name: "Data", id: 0x1, type: "string", conformance: "O", + name: "Data", id: 0x1, type: "string", conformance: "O", constraint: "any", details: "This field shall indicate Optional app-specific data.", xref: { document: "cluster", section: "6.10.7.12.2" } }) @@ -671,8 +674,8 @@ export const MediaPlayback = Cluster( details: "This field shall indicate the associated discrete position within the media stream, in milliseconds " + "from the beginning of the stream, being associated with the time indicated by the UpdatedAt field. " + - "The Position shall not be greater than the duration of the media if duration is specified. The " + - "Position shall not be greater than the time difference between current time and start time of the " + + "The Position shall NOT be greater than the duration of the media if duration is specified. The " + + "Position shall NOT be greater than the time difference between current time and start time of the " + "media when start time is specified." + "\n" + "A value of null shall indicate that playback position is not applicable for the current state of " + diff --git a/packages/model/src/standard/elements/Messages.ts b/packages/model/src/standard/elements/Messages.ts index 16ff545216..2d2d82fd12 100644 --- a/packages/model/src/standard/elements/Messages.ts +++ b/packages/model/src/standard/elements/Messages.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/MicrowaveOvenControl.ts b/packages/model/src/standard/elements/MicrowaveOvenControl.ts index c3e73d95e9..16e064888c 100644 --- a/packages/model/src/standard/elements/MicrowaveOvenControl.ts +++ b/packages/model/src/standard/elements/MicrowaveOvenControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -64,47 +64,52 @@ export const MicrowaveOvenControl = Cluster( name: "PowerSetting", id: 0x2, type: "uint8", access: "R V", conformance: "PWRNUM", constraint: "desc", - details: "Indicates the power level associated with the operation of the device." + + details: "Indicates the power level associated with the operation of the device. If the MinPower, MaxPower, " + + "and PowerStep attributes are not supported:" + "\n" + - "If the MinPower, MaxPower, and PowerStep attributes are not supported, the minimum value of this " + - "attribute shall be 10, the maximum value of this attribute shall be 100, the value shall be in even " + - "multiples of 10, and the default value shall be 100." + + " • The minimum value of this attribute shall be 10," + + "\n" + + " • The maximum value of this attribute shall be 100," + + "\n" + + " • The value shall be in even multiples of 10," + + "\n" + + " • The default value shall be 100." + "\n" + "If the MinPower, MaxPower, and PowerStep attributes are supported:" + "\n" + " • The value of this attribute shall be between MinPower and MaxPower inclusive." + "\n" + - " • The value of this attribute shall be an integer multiple of PowerStep.", + " • The value of this attribute shall be such that (PowerSetting - MinPower) % PowerStep == 0", xref: { document: "cluster", section: "8.13.5.3" } }), Attribute({ name: "MinPower", id: 0x3, type: "uint8", access: "R V", conformance: "PWRLMTS", - constraint: "1 to maxPower", default: 10, quality: "F", - details: "Indicates the minimum power level that can be set on the server. The value of this attribute shall " + - "be less than or equal to the value of MaxPower. The value of this attribute" + - "\n" + - "shall be an integer multiple of PowerStep.", + constraint: "1 to 99", default: 10, quality: "F", + details: "Indicates the minimum value to which the PowerSetting attribute that can be set on the server.", xref: { document: "cluster", section: "8.13.5.4" } }), Attribute({ name: "MaxPower", id: 0x4, type: "uint8", access: "R V", conformance: "PWRLMTS", - constraint: "minPower to 100", default: 100, quality: "F", - details: "Indicates the maximum power level that can be set on the server. The value of this attribute shall " + - "be greater than or equal to the value of MinPower. The value of this attribute shall be an integer " + - "multiple of PowerStep.", + constraint: "minPower + 1 to 100", default: 100, quality: "F", + details: "Indicates the maximum value to which the PowerSetting attribute that can be set on the server.", xref: { document: "cluster", section: "8.13.5.5" } }), Attribute({ name: "PowerStep", id: 0x5, type: "uint8", access: "R V", conformance: "PWRLMTS", - constraint: "1 to (MaxPower - MinPower)", default: 10, quality: "F", - details: "Indicates the increment of power that can be set on the server." + + constraint: "desc", default: 10, quality: "F", + + details: "Indicates the increment of power that can be set on the server. The value of this attribute shall " + + "be between 1 and MaxPower inclusive." + + "\n" + + "The value of this attribute shall be such that (MaxPower - MinPower) % PowerStep == 0" + "\n" + "For example, if MinPower is 1, MaxPower is 10, and PowerSetting can be set to any integer between " + "MinPower and MaxPower, PowerStep would be set to 1.", + xref: { document: "cluster", section: "8.13.5.6" } }), @@ -141,14 +146,13 @@ export const MicrowaveOvenControl = Cluster( { name: "SetCookingParameters", id: 0x0, access: "O", conformance: "M", direction: "request", response: "status", - details: "This command is used to set the cooking parameters associated with the operation of the device." + - "\n" + + details: "This command is used to set the cooking parameters associated with the operation of the device. " + "This command supports the following fields:", xref: { document: "cluster", section: "8.13.6.2" } }, Field({ - name: "CookMode", id: 0x0, type: "uint8", conformance: "O.a+", constraint: "desc", + name: "CookMode", id: 0x0, type: "uint8", conformance: "O.b+", constraint: "desc", details: "This field shall indicate the value to which the CurrentMode attribute of the Microwave Oven Mode " + "cluster should be set. The value of this field shall be one from the list of SupportedModes from " + @@ -161,7 +165,7 @@ export const MicrowaveOvenControl = Cluster( }), Field({ - name: "CookTime", id: 0x1, type: "elapsed-s", conformance: "O.a+", constraint: "1 to maxCookTime", + name: "CookTime", id: 0x1, type: "elapsed-s", conformance: "O.b+", constraint: "1 to maxCookTime", default: 30, details: "This field shall indicate the CookTime associated with the operation of the device. The value of " + "this field shall be subject to the constraints of the CookTime attribute of this cluster." + @@ -171,7 +175,7 @@ export const MicrowaveOvenControl = Cluster( }), Field({ - name: "PowerSetting", id: 0x2, type: "uint8", conformance: "[PWRNUM].a+", + name: "PowerSetting", id: 0x2, type: "uint8", conformance: "[PWRNUM].b+", constraint: "minPower to maxPower", default: { type: "reference", name: "MaxPower" }, details: "This field shall indicate the PowerSetting associated with the operation of the device. The value " + @@ -187,7 +191,7 @@ export const MicrowaveOvenControl = Cluster( }), Field({ - name: "WattSettingIndex", id: 0x3, type: "uint8", conformance: "[WATTS].a+", constraint: "desc", + name: "WattSettingIndex", id: 0x3, type: "uint8", conformance: "[WATTS].b+", constraint: "desc", details: "This field shall indicate the value to which the SelectedWattIndex attribute is set. If the value " + "of this field is greater than or equal to the length of the SupportedWatts attribute list, the " + diff --git a/packages/model/src/standard/elements/MicrowaveOvenDT.ts b/packages/model/src/standard/elements/MicrowaveOvenDT.ts index 3e634f9b27..9858e53752 100644 --- a/packages/model/src/standard/elements/MicrowaveOvenDT.ts +++ b/packages/model/src/standard/elements/MicrowaveOvenDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/MicrowaveOvenMode.ts b/packages/model/src/standard/elements/MicrowaveOvenMode.ts index 69e1a735c1..cc6f88d203 100644 --- a/packages/model/src/standard/elements/MicrowaveOvenMode.ts +++ b/packages/model/src/standard/elements/MicrowaveOvenMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,36 +10,66 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, + FieldElement as Field, CommandElement as Command, - DatatypeElement as Datatype, - FieldElement as Field + DatatypeElement as Datatype } from "../../elements/index.js"; export const MicrowaveOvenMode = Cluster( { name: "MicrowaveOvenMode", id: 0x5e, type: "ModeBase", classification: "application", pics: "MWOM", - details: "This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced " + - "enumerated values for Microwave Oven devices.", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for microwave oven devices.", xref: { document: "cluster", section: "8.12" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), - Attribute({ name: "SupportedModes", id: 0x0, xref: { document: "cluster", section: "8.12.4" } }), - Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "8.12.4" } }), - Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.12.4" } }), - Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.12.4" } }), - Command({ name: "ChangeToMode", id: 0x0, conformance: "X", xref: { document: "cluster", section: "8.12.5" } }), - Command({ name: "ChangeToModeResponse", id: 0x1, conformance: "X", xref: { document: "cluster", section: "8.12.5" } }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.12.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + details: "Exactly one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags " + + "field." + + "\n" + + "The Normal and Defrost mode tags are mutually exclusive and shall NOT both be used together in a " + + "mode’s ModeTags.", + xref: { document: "cluster", section: "8.12.5.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "8.12.5" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.12.5" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.12.5" } }), + Command({ name: "ChangeToMode", id: 0x0, conformance: "X", xref: { document: "cluster", section: "8.12.6" } }), + Command({ name: "ChangeToModeResponse", id: 0x1, conformance: "X", xref: { document: "cluster", section: "8.12.6" } }), Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.12.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.12.7.1" } }), Field({ - name: "Normal", id: 0x4000, description: "The normal mode of operation", - xref: { document: "cluster", section: "8.12.6.1" } + name: "Normal", id: 0x4000, + details: "This is the normal mode of operation for general cooking of food.", + xref: { document: "cluster", section: "8.12.7.1.1" } }), Field({ - name: "Defrost", id: 0x4001, description: "A mode optimized for defrosting foods", - xref: { document: "cluster", section: "8.12.6.1" } + name: "Defrost", id: 0x4001, + details: "This is a mode optimized for defrosting food.", + xref: { document: "cluster", section: "8.12.7.1.2" } }) ) ); diff --git a/packages/model/src/standard/elements/ModeBase.ts b/packages/model/src/standard/elements/ModeBase.ts index c94309f619..91872b2a20 100644 --- a/packages/model/src/standard/elements/ModeBase.ts +++ b/packages/model/src/standard/elements/ModeBase.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -69,7 +69,7 @@ export const ModeBase = Cluster( "Each entry in this list shall have a unique value for the Mode field. Each entry in this list shall " + "have a unique value for the Label field.", - xref: { document: "cluster", section: "1.10.6.2" } + xref: { document: "cluster", section: "1.10.6.1" } }, Field({ name: "entry", type: "ModeOptionStruct" }) @@ -77,7 +77,7 @@ export const ModeBase = Cluster( Attribute({ name: "CurrentMode", id: 0x1, type: "uint8", access: "R V", conformance: "M", constraint: "desc", - quality: "N S", + quality: "N", details: "Indicates the current mode of the server." + "\n" + @@ -89,7 +89,7 @@ export const ModeBase = Cluster( "progressing through a sequence of operations, on system time-outs or idle delays, or via " + "interactions coming from a fabric other than the one which last executed a ChangeToMode.", - xref: { document: "cluster", section: "1.10.6.3" } + xref: { document: "cluster", section: "1.10.6.2" } }), Attribute({ @@ -110,7 +110,7 @@ export const ModeBase = Cluster( "\n" + "If this attribute is not implemented, or is set to the null value, it shall have no effect.", - xref: { document: "cluster", section: "1.10.6.4" } + xref: { document: "cluster", section: "1.10.6.3" } }), Attribute({ @@ -124,7 +124,7 @@ export const ModeBase = Cluster( "The value of this field shall match the Mode field of one of the entries in the SupportedModes " + "attribute.", - xref: { document: "cluster", section: "1.10.6.5" } + xref: { document: "cluster", section: "1.10.6.4" } }), Command( @@ -149,7 +149,7 @@ export const ModeBase = Cluster( "is not able to transition as requested, the ChangeToModeResponse command shall:" + "\n" + " • Have the Status set to a product-specific Status value representing the error, or " + - " GenericFailure if a more specific error cannot be provided. See Status Field for details." + + " GenericFailure if a more specific error cannot be provided. See Status field for details." + "\n" + " • Provide a human readable string in the StatusText field." + "\n" + @@ -159,10 +159,9 @@ export const ModeBase = Cluster( "StatusText field may be supplied with a human readable string or include an empty string and the " + "CurrentMode field shall be set to the value of the NewMode field." + "\n" + - "If the NewMode field is the same as the value of the CurrentMode attribute the ChangeToModeRe" + - "\n" + - "sponse command shall have the Status field set to Success and the StatusText field may be supplied " + - "with a human readable string or include an empty string.", + "If the NewMode field is the same as the value of the CurrentMode attribute the ChangeToModeResponse " + + "command shall have the Status field set to Success and the StatusText field may be supplied with a " + + "human readable string or include an empty string.", xref: { document: "cluster", section: "1.10.7.1.1" } }) @@ -170,10 +169,13 @@ export const ModeBase = Cluster( Command( { - name: "ChangeToModeResponse", id: 0x1, access: "O", conformance: "M", direction: "response", - details: "This command is sent by the device on receipt of the ChangeToMode command.", + name: "ChangeToModeResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command is sent by the device on receipt of the ChangeToMode command. This command" + + "\n" + + "shall have the following data fields:", xref: { document: "cluster", section: "1.10.7.2" } }, + Field({ name: "Status", id: 0x0, type: "status", conformance: "M", constraint: "desc", xref: { document: "cluster", section: "1.10.7.2.1" } @@ -289,7 +291,7 @@ export const ModeBase = Cluster( }), Field({ name: "UnsupportedMode", id: 0x1, - description: "The value of the NewMode field doesn’t match any entries in the SupportedMode attribute.", + description: "The value of the NewMode field doesn’t match any entries in the SupportedModes attribute.", xref: { document: "cluster", section: "1.10.7.2.1.2" } }), Field({ @@ -306,51 +308,16 @@ export const ModeBase = Cluster( Datatype( { name: "ModeTag", type: "enum16" }, - Field({ - name: "Auto", id: 0x0, - description: "The device decides which options, features and setting values to use.", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "Quick", id: 0x1, description: "The mode of the device is optimizing for faster completion.", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "Quiet", id: 0x2, description: "The device is silent or barely audible while in this mode.", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "LowNoise", id: 0x3, - description: "Either the mode is inherently low noise or the device optimizes for that.", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "LowEnergy", id: 0x4, - description: "The device is optimizing for lower energy usage in this mode. Sometimes called \"Eco mode\".", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "Vacation", id: 0x5, - description: "A mode suitable for use during vacations or other extended absences.", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "Min", id: 0x6, description: "The mode uses the lowest available setting value.", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "Max", id: 0x7, description: "The mode uses the highest available setting value.", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "Night", id: 0x8, - description: "The mode is recommended or suitable for use during night time.", - xref: { document: "cluster", section: "1.10.8" } - }), - Field({ - name: "Day", id: 0x9, description: "The mode is recommended or suitable for use during day time.", - xref: { document: "cluster", section: "1.10.8" } - }) + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "1.10.8" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "1.10.8" } }) ) ); diff --git a/packages/model/src/standard/elements/ModeSelect.ts b/packages/model/src/standard/elements/ModeSelect.ts index 4415b3673f..76c811ad84 100644 --- a/packages/model/src/standard/elements/ModeSelect.ts +++ b/packages/model/src/standard/elements/ModeSelect.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -25,7 +25,9 @@ export const ModeSelect = Cluster( "\n" + "The server allows the client to set a mode on the server. A mode is one of a list of options that " + "may be presented by a client for a user choice, or understood by the client, via the semantic tags " + - "on the mode." + + "on the" + + "\n" + + "mode." + "\n" + "A semantic tag is either a standard tag within a standard category namespace, or a manufacturer " + "specific tag, within the namespace of the vendor ID of the manufacturer. If there is no semantic " + @@ -66,21 +68,18 @@ export const ModeSelect = Cluster( "have the description Milk and the second instance can have the description Sugar. This allows the " + "user to tell the purpose of each of the instances.", - xref: { document: "cluster", section: "1.9.6.2" } + xref: { document: "cluster", section: "1.9.6.1" } }), Attribute({ name: "StandardNamespace", id: 0x1, type: "enum16", access: "R V", conformance: "M", constraint: "desc", default: null, quality: "X F", - details: "This attribute, when not null, shall indicate a single standard namespace for any standard semantic " + - "tag value supported in this or any other cluster instance with the same value of this attribute. A" + - "\n" + + "tag value supported in this or any other cluster instance with the same value of this attribute. A " + "null value indicates no standard namespace, and therefore, no standard semantic tags are provided " + "in this cluster instance. Each standard namespace and corresponding values and value meanings shall " + "be defined in another document.", - - xref: { document: "cluster", section: "1.9.6.3" } + xref: { document: "cluster", section: "1.9.6.2" } }), Attribute( @@ -90,7 +89,7 @@ export const ModeSelect = Cluster( details: "This attribute is the list of supported modes that may be selected for the CurrentMode attribute. " + "Each item in this list represents a unique mode as indicated by the Mode field of the " + "ModeOptionStruct. Each entry in this list shall have a unique value for the Mode field.", - xref: { document: "cluster", section: "1.9.6.4" } + xref: { document: "cluster", section: "1.9.6.3" } }, Field({ name: "entry", type: "ModeOptionStruct" }) @@ -98,13 +97,13 @@ export const ModeSelect = Cluster( Attribute({ name: "CurrentMode", id: 0x3, type: "uint8", access: "R V", conformance: "M", constraint: "desc", - quality: "N S", + quality: "N", details: "This attribute represents the current mode of the server." + "\n" + "The value of this field must match the Mode field of one of the entries in the SupportedModes" + "\n" + "attribute.", - xref: { document: "cluster", section: "1.9.6.5" } + xref: { document: "cluster", section: "1.9.6.4" } }), Attribute({ @@ -127,7 +126,7 @@ export const ModeSelect = Cluster( "\n" + "If this attribute is not implemented, or is set to the null value, it shall have no effect.", - xref: { document: "cluster", section: "1.9.6.6" } + xref: { document: "cluster", section: "1.9.6.5" } }), Attribute({ @@ -138,10 +137,11 @@ export const ModeSelect = Cluster( "endpoint. If this attribute is not present or is set to null, it shall NOT have an effect, " + "otherwise the CurrentMode attribute shall depend on the OnOff attribute of the On/Off cluster" + "\n" + - "The value of this field shall match the Mode field of one of the entries in the SupportedModes " + + "The value of this field shall match the Mode field of one of the entries in the SupportedModes" + + "\n" + "attribute.", - xref: { document: "cluster", section: "1.9.6.7" } + xref: { document: "cluster", section: "1.9.6.6" } }), Command( diff --git a/packages/model/src/standard/elements/ModeSelectDT.ts b/packages/model/src/standard/elements/ModeSelectDT.ts index 2e450adb38..4a901780b1 100644 --- a/packages/model/src/standard/elements/ModeSelectDT.ts +++ b/packages/model/src/standard/elements/ModeSelectDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/MountedDimmableLoadControlDT.ts b/packages/model/src/standard/elements/MountedDimmableLoadControlDT.ts new file mode 100644 index 0000000000..91b303e702 --- /dev/null +++ b/packages/model/src/standard/elements/MountedDimmableLoadControlDT.ts @@ -0,0 +1,75 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const MountedDimmableLoadControlDt = DeviceType( + { + name: "MountedDimmableLoadControl", id: 0x110, category: "Smart Plugs/Outlets and other Actuators", + classification: "simple", + details: "A Mounted Dimmable Load Control is a fixed device that provides power to another device that is " + + "plugged into it, and is capable of being switched on or off and have its level adjusted. The " + + "Mounted Dimmable Load Control is typically used to control a conventional non-communicating light " + + "through its mains connection using phase cutting.", + xref: { document: "device", section: "5.4" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 272, revision: 1 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.4.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.4.4" } + }) +) + +MatterDefinition.children.push(MountedDimmableLoadControlDt); diff --git a/packages/model/src/standard/elements/MountedOnOffControlDT.ts b/packages/model/src/standard/elements/MountedOnOffControlDT.ts new file mode 100644 index 0000000000..f68d2fa5d7 --- /dev/null +++ b/packages/model/src/standard/elements/MountedOnOffControlDT.ts @@ -0,0 +1,73 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const MountedOnOffControlDt = DeviceType( + { + name: "MountedOnOffControl", id: 0x10f, category: "Smart Plugs/Outlets and other Actuators", + classification: "simple", + details: "A Mounted On/Off Control is a fixed device that provides power to another device that is plugged " + + "into it, and is capable of switching that provided power on or off.", + xref: { document: "device", section: "5.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 271, revision: 1 } ], element: "attribute" }) + ), + + Requirement( + { + name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }, + Requirement({ name: "TriggerEffect", conformance: "M", element: "command" }) + ), + + Requirement({ + name: "Groups", id: 0x4, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }), + + Requirement( + { + name: "ScenesManagement", id: 0x62, conformance: "P, M", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }, + Requirement({ name: "CopyScene", conformance: "P, M", element: "command" }) + ), + + Requirement( + { + name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }, + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }) + ), + + Requirement( + { + name: "LevelControl", id: 0x8, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "5.3.4" } + }, + Requirement({ name: "ONOFF", conformance: "M", element: "feature" }), + Requirement({ name: "LIGHTING", conformance: "M", element: "feature" }), + Requirement({ name: "CurrentLevel", constraint: "1 to 254", element: "attribute" }), + Requirement({ name: "MinLevel", constraint: "1", element: "attribute" }), + Requirement({ name: "MaxLevel", constraint: "254", element: "attribute" }) + ), + + Requirement({ + name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", + xref: { document: "device", section: "5.3.4" } + }) +) + +MatterDefinition.children.push(MountedOnOffControlDt); diff --git a/packages/model/src/standard/elements/NetworkCommissioning.ts b/packages/model/src/standard/elements/NetworkCommissioning.ts index 887ab60fd0..7391429319 100644 --- a/packages/model/src/standard/elements/NetworkCommissioning.ts +++ b/packages/model/src/standard/elements/NetworkCommissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -96,17 +96,21 @@ export const NetworkCommissioning = Cluster( details: "Indicates the maximum duration taken, in seconds, by the network interface on this cluster server " + "instance to provide scan results." + "\n" + - "See Section 11.9.7.1, “ScanNetworks Command” for usage.", + "See ScanNetworks for usage.", xref: { document: "core", section: "11.9.6.3" } }), Attribute({ name: "ConnectMaxTimeSeconds", id: 0x3, type: "uint8", access: "R V", conformance: "WI | TH", constraint: "desc", quality: "F", + details: "Indicates the maximum duration taken, in seconds, by the network interface on this cluster server " + "instance to report a successful or failed network connection indication. This maximum time shall " + - "account for all operations needed until a successful network connection is deemed to have occurred, " + - "including, for example, obtaining IP addresses, or the execution of necessary internal retries.", + "account for all operations needed until a successful network connection is" + + "\n" + + "deemed to have occurred, including, for example, obtaining IP addresses, or the execution of " + + "necessary internal retries.", + xref: { document: "core", section: "11.9.6.4" } }), @@ -120,8 +124,7 @@ export const NetworkCommissioning = Cluster( "It is undefined what happens if InterfaceEnabled is written to false on the same interface as that " + "which is used to write the value. In that case, it is possible that the Administrator would have to " + "await expiry of the fail-safe, and associated recovery of network configuration to prior safe " + - "values, before being able to communicate with the node again (see Section 11.10.6.2, “ArmFailSafe " + - "Command”)." + + "values, before being able to communicate with the node again (see ArmFailSafe)." + "\n" + "It may be possible to disable Ethernet interfaces but it is implementation-defined. If not " + "supported, a write to this attribute with a value of false shall fail with a status of " + @@ -173,11 +176,10 @@ export const NetworkCommissioning = Cluster( default: null, quality: "X", details: "Indicates the ErrorValue used in the last failed attempt to connect to an operational network, " + - "using this interface, whether by invocation of the ConnectNetwork command or by" + - "\n" + - "autonomous connection after loss of connectivity or during initial establishment. If no such " + - "attempt was made, or no network configurations exist in the Networks attribute, then this attribute " + - "shall be set to null." + + "using this interface, whether by invocation of the ConnectNetwork command or by autonomous " + + "connection after loss of connectivity or during initial establishment. If no such attempt was made, " + + "or no network configurations exist in the Networks attribute, then this attribute shall be set to " + + "null." + "\n" + "If the last connection succeeded, as indicated by a value of Success in the LastNetworkingStatus " + "attribute, then this field shall be set to null." + @@ -244,9 +246,8 @@ export const NetworkCommissioning = Cluster( "Wi-Fi SSID) is provided in the command arguments. Directed scanning shall restrict the result set " + "to the specified network only." + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + "\n" + "The client shall NOT expect the server to be done scanning and have responded with " + "ScanNetworksResponse before ScanMaxTimeSeconds seconds have elapsed. Enough transport time " + @@ -263,8 +264,7 @@ export const NetworkCommissioning = Cluster( "if a ConnectNetwork having the specified SSID were to take place. This command is useful for " + "clients to determine reachability capabilities as seen by the server’s own radios." + "\n" + - "For Wi-Fi-supporting servers the server shall always scan on all bands supported by the interface" + - "\n" + + "For Wi-Fi-supporting servers the server shall always scan on all bands supported by the interface " + "associated with the cluster instance on which the command was invoked." + "\n" + "If the command was invoked over the same link whose configuration is managed by a given server " + @@ -391,9 +391,8 @@ export const NetworkCommissioning = Cluster( details: "This command shall be used to add or modify Wi-Fi network configurations." + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + "\n" + "The Credentials associated with the network are not readable after execution of this command, as " + "they do not appear in the Networks attribute, for security reasons." + @@ -458,7 +457,7 @@ export const NetworkCommissioning = Cluster( Field({ name: "Breadcrumb", id: 0x2, type: "uint64", conformance: "O", - details: "See Section 11.9.7.1.2, “Breadcrumb Field” for usage.", + details: "See Breadcrumb for usage.", xref: { document: "core", section: "11.9.7.3.3" } }) ), @@ -470,9 +469,8 @@ export const NetworkCommissioning = Cluster( details: "This command shall be used to add or modify Thread network configurations." + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + "\n" + "See Section 11.9.7.5, “Common processing of AddOrUpdateWiFiNetwork and AddOrUpdateThreadNetwork” " + "for behavior of addition/update." + @@ -499,7 +497,7 @@ export const NetworkCommissioning = Cluster( Field({ name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", - details: "See Section 11.9.7.1.2, “Breadcrumb Field” for usage.", + details: "See Breadcrumb for usage.", xref: { document: "core", section: "11.9.7.4.2" } }) ), @@ -514,9 +512,8 @@ export const NetworkCommissioning = Cluster( "\n" + "attribute shall remain unchanged, except for the removal of the requested network configuration." + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + "\n" + "If the Networks attribute does not contain a matching entry, the command shall immediately respond " + "with NetworkConfigResponse having NetworkingStatus status field set to NetworkIdNotFound." + @@ -537,7 +534,7 @@ export const NetworkCommissioning = Cluster( Field({ name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", - details: "See Section 11.9.7.1.2, “Breadcrumb Field” for usage.", + details: "See Breadcrumb for usage.", xref: { document: "core", section: "11.9.7.6.2" } }) ), @@ -571,8 +568,7 @@ export const NetworkCommissioning = Cluster( "\n" + " • OutOfRange: Network identifier was invalid (e.g. empty, too long, etc)." + "\n" + - " • BoundsExceeded: Adding this network configuration would exceed the limit defined by Section " + - " 11.9.6.1, “MaxNetworks Attribute”." + + " • BoundsExceeded: Adding this network configuration would exceed the limit defined by MaxNetworks." + "\n" + " • NetworkIdNotFound: The network identifier was expected to be found, but was not found among the " + " added network configurations in Networks attribute." + @@ -584,13 +580,12 @@ export const NetworkCommissioning = Cluster( Field({ name: "DebugText", id: 0x1, type: "string", conformance: "O", constraint: "max 512", - details: "See Section 11.9.7.2.2, “DebugText Field” for usage.", + details: "See DebugText for usage.", xref: { document: "core", section: "11.9.7.7.2" } }), Field({ - name: "NetworkIndex", id: 0x2, type: "uint8", conformance: "O", - constraint: "0 to (MaxNetworks - 1)", + name: "NetworkIndex", id: 0x2, type: "uint8", conformance: "O", constraint: "max maxNetworks - 1", details: "When the NetworkingStatus is Success, this field shall be present. It shall contain the 0-based " + "index of the entry in the Networks attribute that was last added, updated or removed successfully " + "by the associated request command.", @@ -611,9 +606,17 @@ export const NetworkCommissioning = Cluster( "currently unable to proceed with such an operation, such as if it is currently attempting to " + "connect in the background, or is already proceeding with a prior ConnectNetwork." + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + + "\n" + + "Before connecting to the new network, the Node shall disconnect the operational network connections " + + "managed by any other Network Commissioning cluster instances (whether under the Root Node or a " + + "Secondary Network Interface), where those connections are not represented by an entry in the " + + "Networks attribute of the corresponding cluster instance. This ensures that an Administrator or " + + "Commissioner can reliably reconfigure the operational network connection of a device that has one " + + "or more Secondary Network interfaces, for example by removing the active network configuration from " + + "one cluster instance, followed by adding a new configuration and calling ConnectNetwork on a " + + "different cluster instance." + "\n" + "Success or failure of this command shall be communicated by the ConnectNetworkResponse command, " + "unless some data model validations caused a FAILURE status to be sent prior to finishing execution " + @@ -638,22 +641,22 @@ export const NetworkCommissioning = Cluster( "attribute." + "\n" + "Even after successfully connecting to a network, the configuration shall revert to the prior state " + - "of configuration if the CommissioningComplete command (see Section 11.10.6.6, " + - "“CommissioningComplete Command”) is not successfully invoked before expiry of the Fail-Safe timer." + - "\n" + - "When non-concurrent commissioning is being used by a Commissioner or Administrator, the " + - "ConnectNetworkResponse shall be sent with the NetworkingStatus field set to Success prior to " + - "closing the commissioning channel, even if not yet connected to the operational network, unless the " + - "device would be incapable of joining that network, in which case the usual failure path described " + - "in the prior paragraphs shall be followed. Once the commissioning channel is closed, the " + - "operational channel will be started. It is possible that the only method to determine success of " + - "the operation is operational discovery of the Node on the new operational network. Therefore, " + - "before invoking the ConnectNetwork command, the client SHOULD re-invoke the Arm Fail-Safe command " + - "with a duration that meets the following:" + - "\n" + - " 1. Sufficient time to meet the minimum required time (see Section 11.9.6.4, " + - " “ConnectMaxTimeSeconds Attribute”) that may be taken by the server to connect to the desired " + - " network." + + "of configuration if the CommissioningComplete command (see CommissioningComplete) is not " + + "successfully invoked before expiry of the Fail-Safe timer." + + "\n" + + "When non-concurrent commissioning is being used by a Commissioner or Administrator, the Con" + + "\n" + + "nectNetworkResponse shall be sent with the NetworkingStatus field set to Success prior to closing " + + "the commissioning channel, even if not yet connected to the operational network, unless the device " + + "would be incapable of joining that network, in which case the usual failure path described in the " + + "prior paragraphs shall be followed. Once the commissioning channel is closed, the operational " + + "channel will be started. It is possible that the only method to determine success of the operation " + + "is operational discovery of the Node on the new operational network. Therefore, before invoking the " + + "ConnectNetwork command, the client SHOULD re-invoke the Arm Fail-Safe command with a duration that " + + "meets the following:" + + "\n" + + " 1. Sufficient time to meet the minimum required time (see ConnectMaxTimeSeconds) that may be " + + " taken by the server to connect to the desired network." + "\n" + " 2. Sufficient time to account for possible message-layer retries when a response is requested." + "\n" + @@ -685,7 +688,7 @@ export const NetworkCommissioning = Cluster( Field({ name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", - details: "See Section 11.9.7.1.2, “Breadcrumb Field” for usage.", + details: "See Breadcrumb for usage.", xref: { document: "core", section: "11.9.7.8.2" } }) ), @@ -727,16 +730,15 @@ export const NetworkCommissioning = Cluster( "\n" + " • UnknownError: An internal error occurred during the operation." + "\n" + - " • Association errors (see also description of errors in Section 11.9.5.4, " + - " “NetworkCommissioningStatusEnum Type”): AuthFailure, UnsupportedSecurity, " + - " OtherConnectionFailure, IPV6Failed, IPBindFailed", + " • Association errors (see also description of errors in NetworkCommissioningStatusEnum): " + + " AuthFailure, UnsupportedSecurity, OtherConnectionFailure, IPV6Failed, IPBindFailed", xref: { document: "core", section: "11.9.7.9.1" } }), Field({ name: "DebugText", id: 0x1, type: "string", conformance: "O", - details: "See Section 11.9.7.2.2, “DebugText Field” for usage.", + details: "See DebugText for usage.", xref: { document: "core", section: "11.9.7.9.2" } }), @@ -794,7 +796,7 @@ export const NetworkCommissioning = Cluster( { name: "Breadcrumb", id: 0x2, type: "uint64", conformance: "O", - details: "See Section 11.9.7.1.2, “Breadcrumb Field” for usage." + + details: "See Breadcrumb for usage." + "\n" + "Effect when received" + "\n" + @@ -823,7 +825,7 @@ export const NetworkCommissioning = Cluster( "\n" + "On receiving ReorderNetwork with:" + "\n" + - " • NetworkId = Home-Guest" + + " • NetworkID = Home-Guest" + "\n" + " • NetworkIndex = 0" + "\n" + @@ -834,7 +836,7 @@ export const NetworkCommissioning = Cluster( "\n" + "On receiving ReorderNetwork with:" + "\n" + - " • NetworkId = FancyCat" + + " • NetworkID = FancyCat" + "\n" + " • NetworkIndex = 3" + "\n" + @@ -904,38 +906,44 @@ export const NetworkCommissioning = Cluster( xref: { document: "core", section: "11.9.5.3" } }, - Field({ name: "2G4", id: 0x0, conformance: "O.a+", description: "2.4GHz - 2.401GHz to2.495GHz(802.11b/g/n/ax)" }), - Field({ name: "3G65", id: 0x1, conformance: "O.a+", description: "3.65GHz - 3.655GHz to3.695GHz (802.11y)" }), - Field({ name: "5G", id: 0x2, conformance: "O.a+", description: "5GHz - 5.150GHz to5.895GHz(802.11a/n/ac/ax)" }), - Field({ name: "6G", id: 0x3, conformance: "O.a+", description: "6GHz - 5.925GHz to7.125GHz (802.11ax / Wi-Fi 6E)" }), - Field({ name: "60G", id: 0x4, conformance: "O.a+", description: "60GHz - 57.24GHz to70.20GHz (802.11ad/ay)" }), - Field({ name: "1G", id: 0x5, conformance: "O.a+", description: "Sub-1GHz - 755MHz to 931MHz (802.11ah)" }) + Field({ name: "2G4", id: 0x0, conformance: "O.b+", description: "2.4GHz - 2.401GHz to2.495GHz(802.11b/g/n/ax)" }), + Field({ name: "3G65", id: 0x1, conformance: "O.b+", description: "3.65GHz - 3.655GHz to3.695GHz (802.11y)" }), + Field({ name: "5G", id: 0x2, conformance: "O.b+", description: "5GHz - 5.150GHz to5.895GHz(802.11a/n/ac/ax)" }), + Field({ name: "6G", id: 0x3, conformance: "O.b+", description: "6GHz - 5.925GHz to7.125GHz (802.11ax / Wi-Fi 6E)" }), + Field({ name: "60G", id: 0x4, conformance: "O.b+", description: "60GHz - 57.24GHz to70.20GHz (802.11ad/ay)" }), + Field({ name: "1G", id: 0x5, conformance: "O.b+", description: "Sub-1GHz - 755MHz to 931MHz (802.11ah)" }) ), Datatype( { name: "NetworkCommissioningStatusEnum", type: "enum8", xref: { document: "core", section: "11.9.5.4" } }, - Field({ name: "Success", id: 0x0, description: "OK, no error" }), - Field({ name: "OutOfRange", id: 0x1, description: "Value Outside Range" }), - Field({ name: "BoundsExceeded", id: 0x2, description: "A collection would exceed its size limit" }), + Field({ name: "Success", id: 0x0, conformance: "M", description: "OK, no error" }), + Field({ name: "OutOfRange", id: 0x1, conformance: "M", description: "Value Outside Range" }), + Field({ name: "BoundsExceeded", id: 0x2, conformance: "M", description: "A collection would exceed its size limit" }), Field({ - name: "NetworkIdNotFound", id: 0x3, + name: "NetworkIdNotFound", id: 0x3, conformance: "M", description: "The NetworkID is not among the collection of added networks" }), Field({ - name: "DuplicateNetworkId", id: 0x4, + name: "DuplicateNetworkId", id: 0x4, conformance: "M", description: "The NetworkID is already among the collection of added networks" }), - Field({ name: "NetworkNotFound", id: 0x5, description: "Cannot find AP: SSID Not found" }), + Field({ name: "NetworkNotFound", id: 0x5, conformance: "M", description: "Cannot find AP: SSID Not found" }), + Field({ + name: "RegulatoryError", id: 0x6, conformance: "M", + description: "Cannot find AP: Mismatch on band/channels/regulatory domain/ 2.4GHz vs 5GHz" + }), + Field({ + name: "AuthFailure", id: 0x7, conformance: "M", + description: "Cannot associate due to authentication failure" + }), Field({ - name: "RegulatoryError", id: 0x6, - description: "Cannot find AP: Mismatch on band/channels/regulatory domain / 2.4GHz vs 5GHz" + name: "UnsupportedSecurity", id: 0x8, conformance: "M", + description: "Cannot associate due to unsupported security mode" }), - Field({ name: "AuthFailure", id: 0x7, description: "Cannot associate due to authentication failure" }), - Field({ name: "UnsupportedSecurity", id: 0x8, description: "Cannot associate due to unsupported security mode" }), - Field({ name: "OtherConnectionFailure", id: 0x9, description: "Other association failure" }), - Field({ name: "Ipv6Failed", id: 0xa, description: "Failure to generate an IPv6 address" }), - Field({ name: "IpBindFailed", id: 0xb, description: "Failure to bind Wi-Fi <-> IP interfaces" }), - Field({ name: "UnknownError", id: 0xc, description: "Unknown error" }) + Field({ name: "OtherConnectionFailure", id: 0x9, conformance: "M", description: "Other association failure" }), + Field({ name: "Ipv6Failed", id: 0xa, conformance: "M", description: "Failure to generate an IPv6 address" }), + Field({ name: "IpBindFailed", id: 0xb, conformance: "M", description: "Failure to bind Wi-Fi <-> IP interfaces" }), + Field({ name: "UnknownError", id: 0xc, conformance: "M", description: "Unknown error" }) ), Datatype( @@ -1017,7 +1025,7 @@ export const NetworkCommissioning = Cluster( details: "ThreadInterfaceScanResultStruct represents a single Thread network scan result.", xref: { document: "core", section: "11.9.5.7" } }, - Field({ name: "PanId", id: 0x0, type: "uint16", conformance: "TH", constraint: "0 to 65534" }), + Field({ name: "PanId", id: 0x0, type: "uint16", conformance: "TH", constraint: "max 65534" }), Field({ name: "ExtendedPanId", id: 0x1, type: "uint64", conformance: "TH" }), Field({ name: "NetworkName", id: 0x2, type: "string", conformance: "TH", constraint: "1 to 16" }), Field({ name: "Channel", id: 0x3, type: "uint16", conformance: "TH" }), diff --git a/packages/model/src/standard/elements/NetworkInfrastructureManagerDT.ts b/packages/model/src/standard/elements/NetworkInfrastructureManagerDT.ts new file mode 100644 index 0000000000..66b00c8b55 --- /dev/null +++ b/packages/model/src/standard/elements/NetworkInfrastructureManagerDT.ts @@ -0,0 +1,54 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const NetworkInfrastructureManagerDt = DeviceType( + { + name: "NetworkInfrastructureManager", id: 0x90, category: "Network Infrastructure", + classification: "simple", + + details: "A Network Infrastructure Manager provides interfaces that allow for the management of the Wi-Fi, " + + "Thread, and Ethernet networks underlying a Matter deployment, realizing the Star Network Topology " + + "described in [MatterCore]." + + "\n" + + "Examples of physical devices that implement the Matter Network Infrastructure Manager device type " + + "include Wi-Fi gateway routers." + + "\n" + + "Relevant hardware and software requirements for Network Infrastructure Manager devices are defined " + + "in Section 15.2.6, “Other Requirements” and within the clusters mandated by this device type." + + "\n" + + "A Network Infrastructure Manager device may be managed by a service associated with the device " + + "vendor, for example, an Internet Service Provider. Sometimes this managing service will have " + + "policies that require the use of the Managed Device feature of the Access Control Cluster (see " + + "Section 15.2.5.1, “Access Control MNGD Conformance”). Consequently, Commissioners of this device " + + "type should be aware of this feature and its use.", + + xref: { document: "device", section: "15.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 144, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "WiFiNetworkManagement", id: 0x451, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "15.2.4" } + }), + Requirement({ + name: "ThreadBorderRouterManagement", id: 0x452, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "15.2.4" } + }), + Requirement({ + name: "ThreadNetworkDirectory", id: 0x453, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "15.2.4" } + }) +) + +MatterDefinition.children.push(NetworkInfrastructureManagerDt); diff --git a/packages/model/src/standard/elements/NitrogenDioxideConcentrationMeasurement.ts b/packages/model/src/standard/elements/NitrogenDioxideConcentrationMeasurement.ts index f87fc4cf33..bb64000076 100644 --- a/packages/model/src/standard/elements/NitrogenDioxideConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/NitrogenDioxideConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/NumberNS.ts b/packages/model/src/standard/elements/NumberNS.ts index ed598e47b4..160afd141d 100644 --- a/packages/model/src/standard/elements/NumberNS.ts +++ b/packages/model/src/standard/elements/NumberNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/OccupancySensing.ts b/packages/model/src/standard/elements/OccupancySensing.ts index 63d99b2209..75c8ea0323 100644 --- a/packages/model/src/standard/elements/OccupancySensing.ts +++ b/packages/model/src/standard/elements/OccupancySensing.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,138 +10,251 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + EventElement as Event, + DatatypeElement as Datatype } from "../../elements/index.js"; export const OccupancySensing = Cluster( { name: "OccupancySensing", id: 0x406, classification: "application", pics: "OCC", - details: "The server cluster provides an interface to occupancy sensing functionality, including " + - "configuration and provision of notifications of occupancy status.", + details: "The server cluster provides an interface to occupancy sensing functionality based on one or more " + + "sensing modalities, including configuration and provision of notifications of occupancy status.", xref: { document: "cluster", section: "2.7" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 4 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 5 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "2.7.4" } }, + Field({ + name: "OTHER", conformance: "O.a+", constraint: "0", description: "Other", + details: "Supports sensing using a modality not listed in the other bits" + }), + Field({ + name: "PIR", conformance: "O.a+", constraint: "1", description: "PassiveInfrared", + details: "Supports sensing using PIR (Passive InfraRed)" + }), + Field({ + name: "US", conformance: "O.a+", constraint: "2", description: "Ultrasonic", + details: "Supports sensing using UltraSound" + }), + Field({ + name: "PHY", conformance: "O.a+", constraint: "3", description: "PhysicalContact", + details: "Supports sensing using a physical contact" + }), + Field({ + name: "AIR", conformance: "O.a+", constraint: "4", description: "ActiveInfrared", + details: "Supports sensing using Active InfraRed measurement (e.g. time-of- flight or " + + "transflective/reflective IR sensing)" + }), + Field({ + name: "RAD", conformance: "O.a+", constraint: "5", description: "Radar", + details: "Supports sensing using radar waves (microwave)" + }), + Field({ + name: "RFS", conformance: "O.a+", constraint: "6", description: "RfSensing", + details: "Supports sensing based on RF signal analysis" + }), + Field({ + name: "VIS", conformance: "O.a+", constraint: "7", description: "Vision", + details: "Supports sensing based on analyzing images" + }) + ), Attribute({ name: "Occupancy", id: 0x0, type: "OccupancyBitmap", access: "R V", conformance: "M", constraint: "0 to 1", quality: "P", - details: "This attribute indicates the sensed (processed) status of occupancy.", - xref: { document: "cluster", section: "2.7.5.1" } + details: "Indicates the sensed (processed) status of occupancy. For compatibility reasons this is expressed " + + "as a bitmap where the status is indicated in bit 0: a value of 1 means occupied, and 0 means " + + "unoccupied, with the other bits set to 0; this can be considered equivalent to a boolean.", + xref: { document: "cluster", section: "2.7.6.1" } }), Attribute({ name: "OccupancySensorType", id: 0x1, type: "OccupancySensorTypeEnum", access: "R V", - conformance: "M", constraint: "desc", - details: "This attribute specifies the type of the occupancy sensor.", - xref: { document: "cluster", section: "2.7.5.2" } + conformance: "M, D", constraint: "desc", quality: "F", + xref: { document: "cluster", section: "2.7.6" } }), - Attribute({ name: "OccupancySensorTypeBitmap", id: 0x2, type: "OccupancySensorTypeBitmap", access: "R V", - conformance: "M", constraint: "0 to 7", - details: "This attribute specifies the types of the occupancy sensor. Each bit position, if set, indicates " + - "the corresponding sensing capability is implemented." + + conformance: "M, D", constraint: "0 to 7", quality: "F", + xref: { document: "cluster", section: "2.7.6" } + }), + + Attribute({ + name: "HoldTime", id: 0x3, type: "uint16", access: "RW VM", conformance: "O", constraint: "desc", + quality: "N", + + details: "This attribute shall specify the time delay, in seconds, before the sensor changes to its " + + "unoccupied state after the last detection of occupancy in the sensed area. This is equivalent to " + + "the legacy *OccupiedToUnoccupiedDelay attributes." + + "\n" + + "The value of HoldTime shall be within the limits provided in the HoldTimeLimits attribute, i.e. " + + "HoldTimeMin <= HoldTime <= HoldTimeMax" + + "\n" + + "Low values of HoldTime SHOULD be avoided since they could lead to many reporting messages. A value " + + "0 for HoldTime shall NOT be used." + + "\n" + + "The figure below illustrates this with an example of how this attribute is used for a PIR sensor. " + + "It uses threshold detection to generate an \"internal detection\" signal, which needs post-processing " + + "to become usable for transmission (traffic shaping). The bit in the Occupancy attribute will be set " + + "to 1 when the internal detection signal goes high, and will stay at 1 for HoldTime after the (last) " + + "instance where the internal detection signal goes low." + "\n" + - "The value of the OccupancySensorType shall be aligned to the value of the OccupancySensorTypeBitmap " + - "attribute as defined below.", - xref: { document: "cluster", section: "2.7.5.3" } + "The top half of the figure shows the case of a single trigger: the bit in the Occupancy attribute " + + "will be 1 for the duration of the PIR signal exceeding the threshold plus HoldTime. The bottom half " + + "of the figure shows the case of multiple triggers: the second trigger starts before the HoldTime of " + + "the first trigger has expired; this results in a single period of the bit in the Occupancy " + + "attribute being 1. The bit in the Occupancy attribute will be set to 1 from the start of the first " + + "period where the PIR signal exceeds the threshold until HoldTime after the last moment where the " + + "PIR exceeded the threshold." + + "\n" + + "Figure 13. Processing of PIR signal towards Occupancy attribute using HoldTime", + + xref: { document: "cluster", section: "2.7.6.3" } }), Attribute({ - name: "PirOccupiedToUnoccupiedDelay", id: 0x10, type: "uint16", access: "RW VM", conformance: "O", - default: 0, - details: "This attribute specifies the time delay, in seconds, before the PIR sensor changes to its " + - "unoccupied state after the last detection of movement in the sensed area.", - xref: { document: "cluster", section: "2.7.5.4" } + name: "HoldTimeLimits", id: 0x4, type: "HoldTimeLimitsStruct", access: "R V", + conformance: "HoldTime", quality: "F", + details: "Indicates the server’s limits, and default value, for the HoldTime attribute.", + xref: { document: "cluster", section: "2.7.6.4" } + }), + + Attribute({ + name: "PirOccupiedToUnoccupiedDelay", id: 0x10, type: "uint16", access: "RW VM", + conformance: "[HoldTime & (PIR | !PIR & !US & !PHY)], D", default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the PIR sensor changes to its " + + "unoccupied state after the last detection of occupancy in the sensed area.", + xref: { document: "cluster", section: "2.7.6.6" } }), Attribute({ name: "PirUnoccupiedToOccupiedDelay", id: 0x11, type: "uint16", access: "RW VM", - conformance: "PirUnoccupiedToOccupiedThreshold, O", default: 0, - details: "This attribute specifies the time delay, in seconds, before the PIR sensor changes to its occupied " + - "state after the detection of movement in the sensed area.", - xref: { document: "cluster", section: "2.7.5.5" } + conformance: "HoldTime & (PIR | !PIR & !US & !PHY) & PirUnoccupiedToOccupiedThreshold, [HoldTime & (PIR | !PIR & !US & !PHY)], D", + default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the PIR sensor changes to its " + + "occupied state after the first detection of occupancy in the sensed area.", + xref: { document: "cluster", section: "2.7.6.7" } }), Attribute({ name: "PirUnoccupiedToOccupiedThreshold", id: 0x12, type: "uint8", access: "RW VM", - conformance: "PirUnoccupiedToOccupiedDelay, O", constraint: "1 to 254", default: 1, - details: "This attribute specifies the number of movement detection events that must occur in the period " + + conformance: "HoldTime & (PIR | !PIR & !US & !PHY) & PirUnoccupiedToOccupiedDelay, [HoldTime & (PIR | !PIR & !US & !PHY)], D", + constraint: "1 to 254", default: 1, quality: "N", + details: "This attribute shall specify the number of occupancy detection events that must occur in the period " + "PIRUnoccupiedToOccupiedDelay, before the PIR sensor changes to its occupied state.", - xref: { document: "cluster", section: "2.7.5.6" } + xref: { document: "cluster", section: "2.7.6.8" } }), Attribute({ name: "UltrasonicOccupiedToUnoccupiedDelay", id: 0x20, type: "uint16", access: "RW VM", - conformance: "O", default: 0, - details: "This attribute specifies the time delay, in seconds, before the Ultrasonic sensor changes to its " + - "unoccupied state after the last detection of movement in the sensed area.", - xref: { document: "cluster", section: "2.7.5.7" } + conformance: "[HoldTime & US], D", default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the Ultrasonic sensor changes to " + + "its unoccupied state after the last detection of occupancy in the sensed area.", + xref: { document: "cluster", section: "2.7.6.9" } }), Attribute({ name: "UltrasonicUnoccupiedToOccupiedDelay", id: 0x21, type: "uint16", access: "RW VM", - conformance: "UltrasonicUnoccupiedToOccupiedThreshold, O", default: 0, - details: "This attribute specifies the time delay, in seconds, before the Ultrasonic sensor changes to its " + - "occupied state after the detection of movement in the sensed area.", - xref: { document: "cluster", section: "2.7.5.8" } + conformance: "HoldTime & US & UltrasonicUnoccupiedToOccupiedThreshold, [HoldTime & US], D", + default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the Ultrasonic sensor changes to " + + "its occupied state after the first detection of occupancy in the sensed area.", + xref: { document: "cluster", section: "2.7.6.10" } }), Attribute({ name: "UltrasonicUnoccupiedToOccupiedThreshold", id: 0x22, type: "uint8", access: "RW VM", - conformance: "UltrasonicUnoccupiedToOccupiedDelay, O", constraint: "1 to 254", default: 1, - details: "This attribute specifies the number of movement detection events that must occur in the period " + + conformance: "HoldTime & US & UltrasonicUnoccupiedToOccupiedDelay, [HoldTime & US], D", + constraint: "1 to 254", default: 1, quality: "N", + details: "This attribute shall specify the number of occupancy detection events that must occur in the period " + "UltrasonicUnoccupiedToOccupiedDelay, before the Ultrasonic sensor changes to its occupied state.", - xref: { document: "cluster", section: "2.7.5.9" } + xref: { document: "cluster", section: "2.7.6.11" } }), Attribute({ name: "PhysicalContactOccupiedToUnoccupiedDelay", id: 0x30, type: "uint16", access: "RW VM", - conformance: "O", default: 0, - details: "This attribute specifies the time delay, in seconds, before the physical contact occupancy sensor " + - "changes to its unoccupied state after detecting the unoccupied event.", - xref: { document: "cluster", section: "2.7.5.10" } + conformance: "[HoldTime & PHY], D", default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the physical contact occupancy " + + "sensor changes to its unoccupied state after detecting the unoccupied event.", + xref: { document: "cluster", section: "2.7.6.12" } }), Attribute({ name: "PhysicalContactUnoccupiedToOccupiedDelay", id: 0x31, type: "uint16", access: "RW VM", - conformance: "O", default: 0, - details: "This attribute specifies the time delay, in seconds, before the physical contact sensor changes to " + - "its occupied state after the detection of the occupied event.", - xref: { document: "cluster", section: "2.7.5.11" } + conformance: "HoldTime & PHY & PhysicalContactUnoccupiedToOccupiedThreshold, [HoldTime & PHY], D", + default: 0, quality: "N", + details: "This attribute shall specify the time delay, in seconds, before the physical contact sensor changes " + + "to its occupied state after the first detection of the occupied event.", + xref: { document: "cluster", section: "2.7.6.13" } }), Attribute({ name: "PhysicalContactUnoccupiedToOccupiedThreshold", id: 0x32, type: "uint8", access: "RW VM", - conformance: "PhysicalContactUnoccupiedToOccupiedDelay, O", constraint: "1 to 254", default: 1, - details: "This attribute specifies the number of movement detection events that must occur in the period " + + conformance: "HoldTime & PHY & PhysicalContactUnoccupiedToOccupiedDelay, [HoldTime & PHY], D", + constraint: "1 to 254", default: 1, quality: "N", + details: "This attribute shall specify the number of occupancy detection events that must occur in the period " + "PhysicalContactUnoccupiedToOccupiedDelay, before the PhysicalContact sensor changes to its occupied " + "state.", - xref: { document: "cluster", section: "2.7.5.12" } + xref: { document: "cluster", section: "2.7.6.14" } }), + Event( + { + name: "OccupancyChanged", id: 0x0, access: "V", conformance: "O", priority: "info", + details: "If this event is supported, it shall be generated when the Occupancy attribute changes.", + xref: { document: "cluster", section: "2.7.7.1" } + }, + Field({ + name: "Occupancy", id: 0x0, type: "OccupancyBitmap", conformance: "M", + details: "This field shall indicate the new value of the Occupancy attribute.", + xref: { document: "cluster", section: "2.7.7.1.1" } + }) + ), + Datatype( - { name: "OccupancyBitmap", type: "map8", xref: { document: "cluster", section: "2.7.4.1" } }, + { name: "OccupancyBitmap", type: "map8", xref: { document: "cluster", section: "2.7.5.1" } }, Field({ name: "Occupied", constraint: "0", description: "Indicates the sensed occupancy state", details: "If this bit is set, it shall indicate the occupied state else if the bit if not set, it shall " + "indicate the unoccupied state.", - xref: { document: "cluster", section: "2.7.4.1.1" } + xref: { document: "cluster", section: "2.7.5.1.1" } }) ), Datatype( - { name: "OccupancySensorTypeBitmap", type: "map8", xref: { document: "cluster", section: "2.7.4.2" } }, + { + name: "OccupancySensorTypeBitmap", type: "map8", + details: "NOTE" + + "\n" + + "This enum is as defined in ClusterRevision 4 and its definition shall NOT be extended; the feature " + + "flags provide the sensor modality (or modalities) for later cluster revisions. See Backward " + + "Compatibility section.", + xref: { document: "cluster", section: "2.7.5.2" } + }, + Field({ name: "Pir", constraint: "0", description: "Indicates a passive infrared sensor." }), Field({ name: "Ultrasonic", constraint: "1", description: "Indicates a ultrasonic sensor." }), Field({ name: "PhysicalContact", constraint: "2", description: "Indicates a physical contact sensor." }) ), Datatype( - { name: "OccupancySensorTypeEnum", type: "enum8", xref: { document: "cluster", section: "2.7.4.3" } }, + { + name: "OccupancySensorTypeEnum", type: "enum8", + + details: "NOTE" + + "\n" + + "This enum is as defined in ClusterRevision 4 and its definition shall NOT be" + + "\n" + + "extended; the feature flags provide the sensor modality (or modalities) for later cluster " + + "revisions. See Backward Compatibility section.", + + xref: { document: "cluster", section: "2.7.5.3" } + }, + Field({ name: "Pir", id: 0x0, conformance: "M", description: "Indicates a passive infrared sensor." }), Field({ name: "Ultrasonic", id: 0x1, conformance: "M", description: "Indicates a ultrasonic sensor." }), Field({ @@ -149,6 +262,38 @@ export const OccupancySensing = Cluster( description: "Indicates a passive infrared and ultrasonic sensor." }), Field({ name: "PhysicalContact", id: 0x3, conformance: "M", description: "Indicates a physical contact sensor." }) + ), + + Datatype( + { + name: "HoldTimeLimitsStruct", type: "struct", + details: "This structure provides information on the server’s supported values for the HoldTime attribute.", + xref: { document: "cluster", section: "2.7.5.4" } + }, + + Field({ + name: "HoldTimeMin", id: 0x0, type: "uint16", conformance: "M", constraint: "min 1", + details: "This field shall specify the minimum value of the server’s supported value for the HoldTime " + + "attribute, in seconds.", + xref: { document: "cluster", section: "2.7.5.4.1" } + }), + + Field({ + name: "HoldTimeMax", id: 0x1, type: "uint16", conformance: "M", + constraint: "min holdTimeMin, min 10", + details: "This field shall specify the maximum value of the server’s supported value for the HoldTime " + + "attribute, in seconds.", + xref: { document: "cluster", section: "2.7.5.4.2" } + }), + + Field({ + name: "HoldTimeDefault", id: 0x2, type: "uint16", conformance: "M", + constraint: "holdTimeMin to holdTimeMax", + details: "This field shall specify the (manufacturer-determined) default value of the server’s HoldTime " + + "attribute, in seconds. This is the value that a client who wants to reset the settings to a valid " + + "default SHOULD use.", + xref: { document: "cluster", section: "2.7.5.4.3" } + }) ) ); diff --git a/packages/model/src/standard/elements/OccupancySensorDT.ts b/packages/model/src/standard/elements/OccupancySensorDT.ts index 3967cb159d..a83fbbab49 100644 --- a/packages/model/src/standard/elements/OccupancySensorDT.ts +++ b/packages/model/src/standard/elements/OccupancySensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,12 +19,16 @@ export const OccupancySensorDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 263, revision: 3 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 263, revision: 4 } ], element: "attribute" }) ), Requirement({ name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", xref: { document: "device", section: "7.3.4" } }), + Requirement({ + name: "BooleanStateConfiguration", id: 0x80, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "7.3.4" } + }), Requirement({ name: "OccupancySensing", id: 0x406, conformance: "M", element: "serverCluster", xref: { document: "device", section: "7.3.4" } diff --git a/packages/model/src/standard/elements/OnOff.ts b/packages/model/src/standard/elements/OnOff.ts index 87b6210251..614a60de9e 100644 --- a/packages/model/src/standard/elements/OnOff.ts +++ b/packages/model/src/standard/elements/OnOff.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -72,8 +72,7 @@ export const OnOff = Cluster( "\n" + "When this feature is supported, and any change of the \"dead front\" state leads to changes in " + "attributes of other clusters due to the \"dead front\" feature, these attribute changes shall NOT be " + - "skipped or omitted from the usual processing associated with attribute changes. For example, if an" + - "\n" + + "skipped or omitted from the usual processing associated with attribute changes. For example, if an " + "attribute changes from value 4 to null on \"dead front\" behavior due to an Off command being " + "received, this change shall be processed for reporting and subscriptions.", diff --git a/packages/model/src/standard/elements/OnOffLightDT.ts b/packages/model/src/standard/elements/OnOffLightDT.ts index 215db6a5d6..05494ad2d1 100644 --- a/packages/model/src/standard/elements/OnOffLightDT.ts +++ b/packages/model/src/standard/elements/OnOffLightDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/OnOffLightSwitchDT.ts b/packages/model/src/standard/elements/OnOffLightSwitchDT.ts index 8737f0cfc1..b981dc7eba 100644 --- a/packages/model/src/standard/elements/OnOffLightSwitchDT.ts +++ b/packages/model/src/standard/elements/OnOffLightSwitchDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/OnOffPlugInUnitDT.ts b/packages/model/src/standard/elements/OnOffPlugInUnitDT.ts index 43968f50d7..93bd5a8f17 100644 --- a/packages/model/src/standard/elements/OnOffPlugInUnitDT.ts +++ b/packages/model/src/standard/elements/OnOffPlugInUnitDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/OnOffSensorDT.ts b/packages/model/src/standard/elements/OnOffSensorDT.ts index 6a04a818e3..0cae228b52 100644 --- a/packages/model/src/standard/elements/OnOffSensorDT.ts +++ b/packages/model/src/standard/elements/OnOffSensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/OperationalCredentials.ts b/packages/model/src/standard/elements/OperationalCredentials.ts index a3475587d2..fda62cfe6a 100644 --- a/packages/model/src/standard/elements/OperationalCredentials.ts +++ b/packages/model/src/standard/elements/OperationalCredentials.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -92,8 +92,8 @@ export const OperationalCredentials = Cluster( name: "TrustedRootCertificates", id: 0x4, type: "list", access: "R V", conformance: "M", constraint: "max supportedFabrics[max 400]", quality: "N C", - details: "This attribute shall contain a read-only list of Trusted Root CA Certificates installed on the " + - "Node, as octet strings containing their Matter Certificate Encoding representation." + + details: "This attribute shall contain a read-only list of Trusted Root CA Certificates (RCAC) installed on " + + "the Node, as octet strings containing their Matter Certificate Encoding representation." + "\n" + "These certificates are installed through the AddTrustedRootCertificate command." + "\n" + @@ -215,9 +215,8 @@ export const OperationalCredentials = Cluster( "CSR shall be tagged as being for a subsequent AddNOC. See AddNOC and UpdateNOC for details about " + "the processing." + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + "\n" + "If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, " + "then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + @@ -335,9 +334,8 @@ export const OperationalCredentials = Cluster( "\n" + "### Effect When Received" + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + "\n" + "If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, " + "then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + @@ -352,9 +350,8 @@ export const OperationalCredentials = Cluster( "as the rest of the new fabric’s operational credentials, even if some other fabric already uses the " + "exact same root of trust certificate." + "\n" + - "If the NOC provided in the NOCValue encodes an Operational Identifier for a pair already present on the device, then the device shall process the error by responding " + + "If the NOC provided in the NOCValue encodes an Operational Identifier for a pair already present on the device, then the device shall process the error by responding " + "with a StatusCode of FabricConflict as described in Section 11.18.6.7.2, “Handling Errors”." + "\n" + "If the device already has the CommissionedFabrics attribute equal to the SupportedFabrics " + @@ -404,11 +401,14 @@ export const OperationalCredentials = Cluster( " that is currently invoking the AddNOC command, within another of the Fabrics of which it is a " + " member." + "\n" + + " a. If the Managed Device Feature is implemented by the ACL cluster, then one or more ARL " + + " entries with the new FabricIndex may be added to the ARL attribute." + + "\n" + " 8. The incoming IPKValue shall be stored in the Fabric-scoped slot within the Group Key " + " Management cluster (see KeySetWrite), for subsequent use during CASE." + "\n" + - " 9. The Fabric Index associated with the armed fail-safe context (see Section 11.10.6.2, " + - " “ArmFailSafe Command”) shall be updated to match the Fabric Index just allocated." + + " 9. The Fabric Index associated with the armed fail-safe context (see ArmFailSafe) shall be " + + " updated to match the Fabric Index just allocated." + "\n" + " 10. If the current secure session was established with PASE, the receiver shall:" + "\n" + @@ -444,9 +444,8 @@ export const OperationalCredentials = Cluster( "\n" + "Effect When Received" + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + "\n" + "If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, " + "then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + @@ -458,8 +457,7 @@ export const OperationalCredentials = Cluster( "If the prior CSRRequest state that preceded UpdateNOC had the IsForUpdateNOC field indicated as " + "false, then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator." + "\n" + - "If any of the following conditions arise, the Node shall process an error by responding with an" + - "\n" + + "If any of the following conditions arise, the Node shall process an error by responding with an " + "NOCResponse with a StatusCode of InvalidNOC as described in Section 11.18.6.7.2, “Handling Errors”:" + "\n" + " • The NOC provided in the NOCValue does not refer in its subject to the FabricID associated with " + @@ -623,41 +621,42 @@ export const OperationalCredentials = Cluster( "Effect on Receipt" + "\n" + "If the FabricIndex field does not match the FabricIndex of any entry within the Fabrics list, then " + - "an NOCResponse with a StatusCode of InvalidFabricIndex shall be returned for the command and there " + - "shall NOT be any permanent changes to any device data." + + "an NOCResponse with a StatusCode of InvalidFabricIndex shall be returned for the command and" + "\n" + - "Otherwise, one of the following outcomes shall occur:" + + "there shall NOT be any permanent changes to any device data. Otherwise, one of the following " + + "outcomes shall occur:" + "\n" + " 1. If the FabricIndex matches the last remaining entry in the Fabrics list, then the device shall " + - " delete all Matter related data on the node which was created since it was commissioned. This" + - "\n" + - "includes all Fabric-Scoped data, including Access Control List, bindings, scenes, group keys, " + - "operational certificates, etc. All Trusted Roots shall also be removed. If a time synchronization " + - "cluster is present on the Node, the TrustedTimeSource and DefaultNtp shall be set to null. Any " + - "Matter related data including logs, secure sessions, exchanges and interaction model constructs " + - "shall also be removed. Since this operation involves the removal of the secure session data that " + - "may underpin the current set of exchanges, the Node invoking the command SHOULD NOT expect a " + - "response before terminating its secure session with the target." + - "\n" + - "2. If the FabricIndex does not equal the accessing fabric index, then the device shall begin the " + - "process of irrevocably deleting all associated Fabric-Scoped data, including Access Control List, " + - "bindings, group keys, operational certificates, etc. Any remaining Trusted Roots no longer " + - "referenced by any operational certificate shall also be removed. If a time synchronization cluster " + - "is present on the Node, and the TrustedTimeSource FabricIndex matches the given FabricIndex, the " + - "TrustedTimeSource shall be set to null. All secure sessions, exchanges and interaction model " + - "constructs related to the Operational Identity under the given Fabric shall also be removed. " + - "Following the removal, an NOCResponse with a StatusCode of OK shall be returned." + - "\n" + - "3. If the FabricIndex equals the accessing fabric index, then the device shall begin the process of " + - "irrevocably deleting all associated Fabric-Scoped data, including Access Control Entries, bindings, " + - "group keys, operational certificates, etc. Any remaining Trusted Roots no longer referenced by any " + - "operational certificate shall also be removed. If a time synchronization cluster is present on the " + - "Node, and the TrustedTimeSource FabricIndex matches the given FabricIndex, the TrustedTimeSource " + - "shall be set to null. All secure sessions, exchanges and interaction model constructs related to " + - "the Operational Identity under the given Fabric shall also be removed. Since this operation " + - "involves the removal of the secure session data that may underpin the current set of exchanges, the " + - "Node invoking the command SHOULD NOT expect a response before terminating its secure session with " + - "the target.", + " delete all Matter related data on the node which was created since it was commissioned. This " + + " includes all Fabric-Scoped data, including Access Control List, Access Restriction List, " + + " bindings, scenes, group keys, operational certificates, etc. All Trusted Roots shall also be " + + " removed. If a time synchronization cluster is present on the Node, the TrustedTimeSource and " + + " DefaultNtp shall be set to null. Any Matter related data including logs, secure sessions, " + + " exchanges and interaction model constructs shall also be removed. Since this operation " + + " involves the removal of the secure session data that may underpin the current set of " + + " exchanges, the Node invoking the command SHOULD NOT expect a response before terminating its " + + " secure session with the target." + + "\n" + + " 2. If the FabricIndex does not equal the accessing fabric index, then the device shall begin the " + + " process of irrevocably deleting all associated Fabric-Scoped data, including Access Control " + + " Entries, Access Restriction Entries, bindings, group keys, operational certificates, etc. Any " + + " remaining Trusted Roots no longer referenced by any operational certificate shall also be " + + " removed. If a time synchronization cluster is present on the Node, and the TrustedTimeSource " + + " FabricIndex matches the given FabricIndex, the TrustedTimeSource shall be set to null. All " + + " secure sessions, exchanges and interaction model constructs related to the Operational " + + " Identity under the given Fabric shall also be removed. Following the removal, an NOCResponse " + + " with a StatusCode of OK shall be returned." + + "\n" + + " 3. If the FabricIndex equals the accessing fabric index, then the device shall begin the process " + + " of irrevocably deleting all associated Fabric-Scoped data, including Access Control Entries, " + + " Access Restriction Entries, bindings, group keys, operational certificates, etc. Any remaining " + + " Trusted Roots no longer referenced by any operational certificate shall also be removed. If a " + + " time synchronization cluster is present on the Node, and the TrustedTimeSource FabricIndex " + + " matches the given FabricIndex, the TrustedTimeSource shall be set to null. All secure " + + " sessions, exchanges and interaction model constructs related to the Operational Identity under " + + " the given Fabric shall also be removed. Since this operation involves the removal of the " + + " secure session data that may underpin the current set of exchanges, the Node invoking the " + + " command SHOULD NOT expect a response before terminating its secure session with the target.", xref: { document: "core", section: "11.18.6.12.1" } }) @@ -675,12 +674,12 @@ export const OperationalCredentials = Cluster( "If the certificate from the RootCACertificate field is already installed, based on exact " + "byte-for-byte equality, then this command shall succeed with no change to the list." + "\n" + - "If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe " + - "Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the " + - "initiator." + + "If this command is received without an armed fail-safe context (see ArmFailSafe), then this command " + + "shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator." + "\n" + "If a prior AddTrustedRootCertificate command was successfully invoked within the fail-safe timer " + - "period, which would cause the new invocation to add a second root certificate within a given fail- " + + "period, which would cause the new invocation to add a second root certificate within a given fail-" + + "\n" + "safe timer period, then this command shall fail with a CONSTRAINT_ERROR status code sent back to " + "the initiator." + "\n" + @@ -796,11 +795,16 @@ export const OperationalCredentials = Cluster( Field({ name: "VendorId", id: 0x2, type: "vendor-id", access: "F", conformance: "M", constraint: "desc", + details: "This field shall contain the value of AdminVendorID provided in the AddNOC command that led to the " + "creation of this FabricDescriptorStruct. The set of allowed values is defined in AdminVendorID." + "\n" + "The intent is to provide some measure of user transparency about which entities have Administer " + - "privileges on the Node.", + "privileges on the Node." + + "\n" + + "Clients shall consider the VendorID field value to be untrustworthy until the NOC chain associated " + + "with the fabric has passed the Vendor ID Validation Procedure against the associated RCAC.", + xref: { document: "core", section: "11.18.4.5.2" } }), diff --git a/packages/model/src/standard/elements/OperationalState.ts b/packages/model/src/standard/elements/OperationalState.ts index 08e728cf6f..cb2d7f031f 100644 --- a/packages/model/src/standard/elements/OperationalState.ts +++ b/packages/model/src/standard/elements/OperationalState.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -43,7 +43,7 @@ export const OperationalState = Cluster( xref: { document: "cluster", section: "1.14" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), Attribute( { @@ -69,7 +69,8 @@ export const OperationalState = Cluster( quality: "X", details: "This attribute represents the current phase of operation being performed by the server. This shall " + - "be the positional index representing the value from the set provided in the PhaseList Attribute, " + + "be the positional index representing the value from the set provided in the PhaseList Attribute," + + "\n" + "where the first item in that list is an index of 0. Thus, this attribute shall have a maximum value " + "that is \"length(PhaseList) - 1\"." + "\n" + @@ -80,18 +81,36 @@ export const OperationalState = Cluster( Attribute({ name: "CountdownTime", id: 0x2, type: "elapsed-s", access: "R V", conformance: "O", - constraint: "max 259200", default: null, quality: "X C", + constraint: "max 259200", default: null, quality: "X Q", - details: "Indicates the estimated time left before the operation is completed, in seconds. Changes to this " + - "value shall NOT be reported in a subscription (note the C Quality). A Client implementation may " + - "periodically poll this value to ensure alignment of any local rendering of the CountdownTime with " + - "the device provided value." + + details: "Indicates the estimated time left before the operation is completed, in seconds." + + "\n" + + "A value of 0 (zero) means that the operation has completed." + + "\n" + + "A value of null represents that there is no time currently defined until operation completion. This " + + "may happen, for example, because no operation is in progress or because the completion time is " + + "unknown." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • If it has changed due to a change in the CurrentPhase or OperationalState attributes, or" + + "\n" + + " • When it changes from 0 to any other value and vice versa, or" + "\n" + - "A value of 0 means that the operation has completed." + + " • When it changes from null to any other value and vice versa, or" + "\n" + - "When this attribute is null, that represents that there is no time currently defined until " + - "operation completion. This may happen, for example, because no operation is in progress or because " + - "the completion time is unknown.", + " • When it increases, or" + + "\n" + + " • When there is any increase or decrease in the estimated time remaining that was due to " + + " progressing insight of the server’s control logic, or" + + "\n" + + " • When it changes at a rate significantly different from one unit per second." + + "\n" + + "Changes to this attribute merely due to the normal passage of time with no other dynamic change of " + + "device state shall NOT be reported." + + "\n" + + "As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the " + + "reporting of this attribute in order to keep track of the remaining duration.", xref: { document: "cluster", section: "1.14.5.3" } }), @@ -149,12 +168,18 @@ export const OperationalState = Cluster( Event( { - name: "OperationCompletion", id: 0x1, access: "V", conformance: "P, O", priority: "info", - details: "This event is generated when the overall operation ends, successfully or otherwise. For example, " + - "the completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a wash cycle " + - "in a Washing Machine." + + name: "OperationCompletion", id: 0x1, access: "V", conformance: "O", priority: "info", + + details: "This event SHOULD be generated when the overall operation ends, successfully or otherwise. For " + + "example, the completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a " + + "wash cycle in a Washing Machine." + + "\n" + + "It is highly recommended that appliances device types employing the Operational State cluster " + + "support this event, even if it is optional. This assists clients in executing automations or " + + "issuing notifications at critical points in the device operation cycles." + "\n" + "This event shall contain the following fields:", + xref: { document: "cluster", section: "1.14.7.2" } }, @@ -168,10 +193,14 @@ export const OperationalState = Cluster( Field({ name: "TotalOperationalTime", id: 0x1, type: "elapsed-s", conformance: "O", quality: "X", + details: "The total operational time, in seconds, from when the operation was started via an initial Start " + - "command or manual action, until the operation completed. This includes any time spent while paused. " + - "There may be cases whereby the total operational time exceeds the maximum value that can be " + - "conveyed by this attribute, in such instances, this attribute shall be populated with null.", + "command or autonomous/manual starting action, until the operation completed. This includes any time" + + "\n" + + "spent while paused. There may be cases whereby the total operational time exceeds the maximum value " + + "that can be conveyed by this attribute, in such instances, this attribute shall be populated with " + + "null.", + xref: { document: "cluster", section: "1.14.7.2.2" } }), @@ -357,29 +386,36 @@ export const OperationalState = Cluster( }) ), - Datatype({ - name: "OperationalStateEnum", type: "enum8", + Datatype( + { + name: "OperationalStateEnum", type: "enum8", - details: "This type defines the set of known operational state values, and is derived from enum8. The " + - "following table defines the applicable ranges for values that are defined within this type. All " + - "values that are undefined shall be treated as reserved. As shown by the table, states that may be " + - "specific to a certain Device Type or other modality shall be defined in a derived cluster of this " + - "cluster." + - "\n" + - "The derived cluster-specific state definitions shall NOT duplicate any general state definitions. " + - "That is, a derived cluster specification of this cluster cannot define states with the same " + - "semantics as the general states defined below." + - "\n" + - "A manufacturer-specific state definition shall NOT duplicate the general state definitions or " + - "derived cluster state definitions. That is, a manufacturer-defined state defined for this cluster " + - "or a derived cluster thereof cannot define a state with the same semantics as the general states " + - "defined below or states defined in a derived cluster. Such manufacturer-specific state definitions " + - "shall be scoped in the context of the Vendor ID present in the Basic Information cluster." + - "\n" + - "The following table defines the generally applicable states.", + details: "This type defines the set of known operational state values, and is derived from enum8. The " + + "following table defines the applicable ranges for values that are defined within this type. All " + + "values that are undefined shall be treated as reserved. As shown by the table, states that may be " + + "specific to a certain Device Type or other modality shall be defined in a derived cluster of this " + + "cluster." + + "\n" + + "The derived cluster-specific state definitions shall NOT duplicate any general state definitions. " + + "That is, a derived cluster specification of this cluster cannot define states with the same " + + "semantics as the general states defined below." + + "\n" + + "A manufacturer-specific state definition shall NOT duplicate the general state definitions or " + + "derived cluster state definitions. That is, a manufacturer-defined state defined for this cluster " + + "or a derived cluster thereof cannot define a state with the same semantics as the general states " + + "defined below or states defined in a derived cluster. Such manufacturer-specific state definitions " + + "shall be scoped in the context of the Vendor ID present in the Basic Information cluster." + + "\n" + + "The following table defines the generally applicable states.", - xref: { document: "cluster", section: "1.14.4.1" } - }), + xref: { document: "cluster", section: "1.14.4.1" } + }, + + Field({ name: "Stopped", id: 0x0, conformance: "M", description: "The device is stopped" }), + Field({ name: "Running", id: 0x1, conformance: "M", description: "The device is operating" }), + Field({ name: "Paused", id: 0x2, conformance: "M", description: "The device is paused during an operation" }), + Field({ name: "Error", id: 0x3, conformance: "M", description: "The device is in an error state" }) + ), Datatype( { @@ -402,39 +438,34 @@ export const OperationalState = Cluster( }) ), - Datatype({ - name: "ErrorStateEnum", type: "enum8", - - details: "This type defines the set of known operational error values, and is derived from enum8. The " + - "following table defines the applicable ranges for values that are defined within this type. All " + - "values that" + - "\n" + - "are undefined shall be treated as reserved. As shown by the table, errors that may be specific to a " + - "certain Device Type or other modality shall be defined in a derived cluster of this cluster." + - "\n" + - "The derived cluster-specific error definitions shall NOT duplicate the general error definitions. " + - "That is, a derived cluster specification of this cluster cannot define errors with the same " + - "semantics as the general errors defined below." + - "\n" + - "The manufacturer-specific error definitions shall NOT duplicate the general error definitions or " + - "derived cluster-specific error definitions. That is, a manufacturer-defined error defined for this " + - "cluster or a derived cluster thereof cannot define errors with the same semantics as the general " + - "errors defined below or errors defined in a derived cluster. Such manufacturer-specific error " + - "definitions shall be scoped in the context of the Vendor ID present in the Basic Information " + - "cluster." + - "\n" + - "The set of ErrorStateID field values defined in each of the generic or derived Operational State " + - "cluster specifications is called ErrorState.", - - xref: { document: "cluster", section: "1.14.4.3" } - }), - Datatype( { - name: "GeneralErrorStateEnum", type: "enum8", - details: "The following table defines the generally applicable ErrorState values.", - xref: { document: "cluster", section: "1.14.4.3.1" } + name: "ErrorStateEnum", type: "enum8", + + details: "This type defines the set of known operational error values, and is derived from enum8. The " + + "following table defines the applicable ranges for values that are defined within this type. All " + + "values that are undefined shall be treated as reserved. As shown by the table, errors that may be " + + "specific to a certain Device Type or other modality shall be defined in a derived cluster of this " + + "cluster." + + "\n" + + "The derived cluster-specific error definitions shall NOT duplicate the general error definitions." + + "\n" + + "That is, a derived cluster specification of this cluster cannot define errors with the same " + + "semantics as the general errors defined below." + + "\n" + + "The manufacturer-specific error definitions shall NOT duplicate the general error definitions or " + + "derived cluster-specific error definitions. That is, a manufacturer-defined error defined for this " + + "cluster or a derived cluster thereof cannot define errors with the same semantics as the general " + + "errors defined below or errors defined in a derived cluster. Such manufacturer-specific error " + + "definitions shall be scoped in the context of the Vendor ID present in the Basic Information " + + "cluster." + + "\n" + + "The set of ErrorStateID field values defined in each of the generic or derived Operational State " + + "cluster specifications is called ErrorState.", + + xref: { document: "cluster", section: "1.14.4.3" } }, + Field({ name: "NoError", id: 0x0, conformance: "M", description: "The device is not in an error state" }), Field({ name: "UnableToStartOrResume", id: 0x1, conformance: "M", diff --git a/packages/model/src/standard/elements/OtaProviderDT.ts b/packages/model/src/standard/elements/OtaProviderDT.ts index a6a9cd1212..0d08cc76a6 100644 --- a/packages/model/src/standard/elements/OtaProviderDT.ts +++ b/packages/model/src/standard/elements/OtaProviderDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/OtaRequestorDT.ts b/packages/model/src/standard/elements/OtaRequestorDT.ts index c1ecede782..f87fe406ce 100644 --- a/packages/model/src/standard/elements/OtaRequestorDT.ts +++ b/packages/model/src/standard/elements/OtaRequestorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/OtaSoftwareUpdateProvider.ts b/packages/model/src/standard/elements/OtaSoftwareUpdateProvider.ts index 947872cd5d..0d021d3dc0 100644 --- a/packages/model/src/standard/elements/OtaSoftwareUpdateProvider.ts +++ b/packages/model/src/standard/elements/OtaSoftwareUpdateProvider.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -86,7 +86,8 @@ export const OtaSoftwareUpdateProvider = Cluster( Field({ name: "Location", id: 0x5, type: "string", conformance: "O", constraint: "2", - details: "The location, if present, shall provide the same value as the Basic Information Cluster Location " + + details: "The location, if present, shall provide the same value as the Basic Information Cluster Location" + + "\n" + "attribute for the OTA Requestor as configured. This may be used by the OTA Provider logic to allow " + "per-region selection of the Software Image.", xref: { document: "core", section: "11.20.6.5.1.6" } @@ -194,29 +195,28 @@ export const OtaSoftwareUpdateProvider = Cluster( "\n" + " a. The Operational Node ID in the host field shall match the NodeID of the OTA Provider " + " responding with the QueryImageResponse. The usage of a different Node ID than that of the " + - " provider is reserved for future use. This constraint reduces the number of independent" + - "\n" + - "CASE secure channel sessions that have to be maintained to proceed with OTA software updates, thus " + - "reducing energy and resource utilization for the software update process." + + " provider is reserved for future use. This constraint reduces the number of independent CASE " + + " secure channel sessions that have to be maintained to proceed with OTA software updates, " + + " thus reducing energy and resource utilization for the software update process." + "\n" + - "4. The user section of the authority field shall be absent, as there are no \"users\" to be " + - "considered." + + " 4. The user section of the authority field shall be absent, as there are no \"users\" to be " + + " considered." + "\n" + - "5. The port section of the authority field shall be absent, as the port for transport shall be " + - "determined through Operational Discovery of the target Node." + + " 5. The port section of the authority field shall be absent, as the port for transport shall be " + + " determined through Operational Discovery of the target Node." + "\n" + - "6. The URI shall not contain a query field." + + " 6. The URI shall NOT contain a query field." + "\n" + - "7. The URI shall not contain a fragment field." + + " 7. The URI shall NOT contain a fragment field." + "\n" + - "8. The path field shall employ absolute path representation and shall contain the file designator " + - "of the software image to download at the BDX server. When used with the BDX server, the leading / " + - "separating the URI authority from the path shall be omitted. When contacting the BDX server, " + - "further processing of the file designator shall NOT be done, including handling of URL-encoded " + - "escape sequences. Rather, the exact octets of the path, as received shall be the values used by " + - "both client and server in handling the file designator." + + " 8. The path field shall employ absolute path representation and shall contain the file designator " + + " of the software image to download at the BDX server. When used with the BDX server, the " + + " leading / separating the URI authority from the path shall be omitted. When contacting the BDX " + + " server, further processing of the file designator shall NOT be done, including handling of " + + " URL-encoded escape sequences. Rather, the exact octets of the path, as received shall be the " + + " values used by both client and server in handling the file designator." + "\n" + - " a. The path shall only contain valid URI characters." + + " a. The path shall only contain valid URI characters." + "\n" + "These rules above for BDX URIs simplify parsing for OTA Requestors receiving Image URIs. The " + "following example procedure shows how the format constraints simplify the extraction of the " + @@ -454,7 +454,7 @@ export const OtaSoftwareUpdateProvider = Cluster( "or a critical malfunction), an OTA Provider shall NOT expect every OTA Requestor to invoke this " + "command for correct operation of the OTA Provider." + "\n" + - "This command shall be considered optional and shall not result in reduced availability of the OTA " + + "This command shall be considered optional and shall NOT result in reduced availability of the OTA " + "Provider functionality if OTA Requestors never invoke this command." + "\n" + "Effect on Receipt" + @@ -496,8 +496,7 @@ export const OtaSoftwareUpdateProvider = Cluster( { name: "ApplyUpdateActionEnum", type: "enum8", details: "See Section 11.20.3.6, “Applying a software update” for the semantics of the values. This " + - "enumeration is used in the Action field of the ApplyUpdateResponse command. See (Section " + - "11.20.6.5.4.1, “Action Field”).", + "enumeration is used in the Action field of the ApplyUpdateResponse command. See (Action).", xref: { document: "core", section: "11.20.6.4.2" } }, @@ -512,9 +511,8 @@ export const OtaSoftwareUpdateProvider = Cluster( Datatype( { name: "DownloadProtocolEnum", type: "enum8", - details: "Note that only HTTP over TLS (HTTPS) is supported (see RFC 7230). Using HTTP without TLS shall" + - "\n" + - "NOT be supported, as there is no way to authenticate the involved participants.", + details: "Note that only HTTP over TLS (HTTPS) is supported (see RFC 7230). Using HTTP without TLS shall NOT " + + "be supported, as there is no way to authenticate the involved participants.", xref: { document: "core", section: "11.20.6.4.3" } }, diff --git a/packages/model/src/standard/elements/OtaSoftwareUpdateRequestor.ts b/packages/model/src/standard/elements/OtaSoftwareUpdateRequestor.ts index d3ada8c927..8341733702 100644 --- a/packages/model/src/standard/elements/OtaSoftwareUpdateRequestor.ts +++ b/packages/model/src/standard/elements/OtaSoftwareUpdateRequestor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,7 @@ export const OtaSoftwareUpdateRequestor = Cluster( Attribute( { name: "DefaultOtaProviders", id: 0x0, type: "list", access: "RW F VA", conformance: "M", - constraint: "desc", default: [], + constraint: "desc", default: [], quality: "N", details: "This field is a list of ProviderLocation whose entries shall be set by Administrators, either " + "during Commissioning or at a later time, to set the ProviderLocation for the default OTA Provider " + @@ -450,8 +450,7 @@ export const OtaSoftwareUpdateRequestor = Cluster( Field({ name: "Endpoint", id: 0x2, type: "endpoint-no", access: "F", conformance: "M", - details: "This field shall contain the endpoint number which has the OTA Provider device type and OTA" + - "\n" + + details: "This field shall contain the endpoint number which has the OTA Provider device type and OTA " + "Software Update Provider cluster server on the ProviderNodeID. This is provided to avoid having to " + "do discovery of the location of that endpoint by walking over all endpoints and checking their " + "Descriptor Cluster.", diff --git a/packages/model/src/standard/elements/OvenCavityOperationalState.ts b/packages/model/src/standard/elements/OvenCavityOperationalState.ts index 236e55dff8..cc41c4b34d 100644 --- a/packages/model/src/standard/elements/OvenCavityOperationalState.ts +++ b/packages/model/src/standard/elements/OvenCavityOperationalState.ts @@ -1,23 +1,33 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MatterDefinition } from "../MatterDefinition.js"; -import { ClusterElement as Cluster, AttributeElement as Attribute } from "../../elements/index.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + CommandElement as Command +} from "../../elements/index.js"; export const OvenCavityOperationalState = Cluster( { name: "OvenCavityOperationalState", id: 0x48, type: "OperationalState", classification: "application", pics: "OVENOPSTATE", - details: "This cluster provides an interface for monitoring the operational state of an oven.", + details: "This cluster is derived from the Operational State cluster and provides an interface for monitoring " + + "the operational state of an oven.", xref: { document: "cluster", section: "8.10" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }) + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + Command({ name: "Pause", id: 0x0, conformance: "X", xref: { document: "cluster", section: "8.10.5" } }), + Command({ name: "Stop", id: 0x1, xref: { document: "cluster", section: "8.10.5" } }), + Command({ name: "Start", id: 0x2, xref: { document: "cluster", section: "8.10.5" } }), + Command({ name: "Resume", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.10.5" } }), + Command({ name: "OperationalCommandResponse", id: 0x4, xref: { document: "cluster", section: "8.10.5" } }) ) MatterDefinition.children.push(OvenCavityOperationalState); diff --git a/packages/model/src/standard/elements/OvenDT.ts b/packages/model/src/standard/elements/OvenDT.ts index 316f9c8757..60c836dab1 100644 --- a/packages/model/src/standard/elements/OvenDT.ts +++ b/packages/model/src/standard/elements/OvenDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,7 +20,7 @@ export const OvenDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 123, revision: 1 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 123, revision: 2 } ], element: "attribute" }) ), Requirement({ name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", diff --git a/packages/model/src/standard/elements/OvenMode.ts b/packages/model/src/standard/elements/OvenMode.ts index dce19b511e..4b31bb6718 100644 --- a/packages/model/src/standard/elements/OvenMode.ts +++ b/packages/model/src/standard/elements/OvenMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,65 +10,101 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + DatatypeElement as Datatype } from "../../elements/index.js"; export const OvenMode = Cluster( { name: "OvenMode", id: 0x49, type: "ModeBase", classification: "application", pics: "OTCCM", - details: "This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced " + + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + "enumerated values for oven devices.", xref: { document: "cluster", section: "8.11" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.11.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + details: "At least one entry in the SupportedModes attribute shall include the Bake mode tag in the ModeTags " + + "field list.", + xref: { document: "cluster", section: "8.11.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "8.11.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.11.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.11.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "8.11.5.1" } + }), Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.11.7.1" } }), Field({ name: "Bake", id: 0x4000, details: "This mode sets the device into baking mode for baking food items.", - xref: { document: "cluster", section: "8.11.4.1.1" } + xref: { document: "cluster", section: "8.11.7.1.1" } }), Field({ name: "Convection", id: 0x4001, details: "This mode sets the device into convection mode which creates an airflow within the device during " + "the cooking duration.", - xref: { document: "cluster", section: "8.11.4.1.2" } + xref: { document: "cluster", section: "8.11.7.1.2" } }), Field({ name: "Grill", id: 0x4002, details: "This mode sets the device into grill mode for grilling food items. This is the same as Broil for " + "many regions.", - xref: { document: "cluster", section: "8.11.4.1.3" } + xref: { document: "cluster", section: "8.11.7.1.3" } }), Field({ name: "Roast", id: 0x4003, details: "This mode sets the device into roast mode for roasting food items.", - xref: { document: "cluster", section: "8.11.4.1.4" } + xref: { document: "cluster", section: "8.11.7.1.4" } }), Field({ name: "Clean", id: 0x4004, details: "This mode sets the device into cleaning mode to clean the internal components of the appliance.", - xref: { document: "cluster", section: "8.11.4.1.5" } + xref: { document: "cluster", section: "8.11.7.1.5" } }), - Field({ name: "ConvectionBake", id: 0x4005, xref: { document: "cluster", section: "8.11.4.1" } }), - Field({ name: "ConvectionRoast", id: 0x4006, xref: { document: "cluster", section: "8.11.4.1" } }), + Field({ name: "ConvectionBake", id: 0x4005, xref: { document: "cluster", section: "8.11.7.1" } }), + Field({ name: "ConvectionRoast", id: 0x4006, xref: { document: "cluster", section: "8.11.7.1" } }), Field({ name: "Warming", id: 0x4007, details: "This mode sets the device into a warming mode which begins warming the cavity.", - xref: { document: "cluster", section: "8.11.4.1.8" } + xref: { document: "cluster", section: "8.11.7.1.8" } }), Field({ name: "Proofing", id: 0x4008, details: "This mode sets the device into proofing mode which creates an environment ready for proofing.", - xref: { document: "cluster", section: "8.11.4.1.9" } + xref: { document: "cluster", section: "8.11.7.1.9" } }), - Field({ name: "Steam", id: 0x4009, xref: { document: "cluster", section: "8.11.4.1" } }) + Field({ name: "Steam", id: 0x4009, xref: { document: "cluster", section: "8.11.7.1" } }) ) ); diff --git a/packages/model/src/standard/elements/OzoneConcentrationMeasurement.ts b/packages/model/src/standard/elements/OzoneConcentrationMeasurement.ts index 9cd8ef62c4..f7d19ac967 100644 --- a/packages/model/src/standard/elements/OzoneConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/OzoneConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/Pm10ConcentrationMeasurement.ts b/packages/model/src/standard/elements/Pm10ConcentrationMeasurement.ts index c9c7d2e8ba..34623c11ef 100644 --- a/packages/model/src/standard/elements/Pm10ConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/Pm10ConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/Pm1ConcentrationMeasurement.ts b/packages/model/src/standard/elements/Pm1ConcentrationMeasurement.ts index e9b399a6b6..97cdca88ad 100644 --- a/packages/model/src/standard/elements/Pm1ConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/Pm1ConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/Pm25ConcentrationMeasurement.ts b/packages/model/src/standard/elements/Pm25ConcentrationMeasurement.ts index 8c439792e0..4a928f1b68 100644 --- a/packages/model/src/standard/elements/Pm25ConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/Pm25ConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/PositionNS.ts b/packages/model/src/standard/elements/PositionNS.ts index e6864c0a59..f9e0fdd3fd 100644 --- a/packages/model/src/standard/elements/PositionNS.ts +++ b/packages/model/src/standard/elements/PositionNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/PowerSource.ts b/packages/model/src/standard/elements/PowerSource.ts index d0820cec06..4ffa216625 100644 --- a/packages/model/src/standard/elements/PowerSource.ts +++ b/packages/model/src/standard/elements/PowerSource.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,17 +20,17 @@ export const PowerSource = Cluster( name: "PowerSource", id: 0x2f, classification: "node", pics: "PS", details: "This cluster is used to describe the configuration and capabilities of a physical power source that " + "provides power to one or more endpoints on a node. In case the node has multiple power sources, " + - "each is described by its own cluster instance. Each instance of this cluster may be associated with " + - "one or more endpoints or the entire node.", + "each shall be described by its own cluster instance. Each instance of this cluster may be " + + "associated with one or more endpoints or the entire node.", xref: { document: "core", section: "11.7" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.7.4" } }, - Field({ name: "WIRED", conformance: "O", constraint: "0", description: "Wired", details: "A wired power source" }), - Field({ name: "BAT", conformance: "O", constraint: "1", description: "Battery", details: "A battery power source" }), + Field({ name: "WIRED", conformance: "O.a", constraint: "0", description: "Wired", details: "A wired power source" }), + Field({ name: "BAT", conformance: "O.a", constraint: "1", description: "Battery", details: "A battery power source" }), Field({ name: "RECHG", conformance: "[BAT]", constraint: "2", description: "Rechargeable", details: "A rechargeable battery power source" @@ -161,19 +161,39 @@ export const PowerSource = Cluster( Attribute({ name: "BatPercentRemaining", id: 0xc, type: "uint8", access: "R V", conformance: "[BAT]", - constraint: "0 to 200", quality: "X C", + constraint: "max 200", quality: "X Q", + details: "Indicates the estimated percentage of battery charge remaining until the battery will no longer be " + "able to provide power to the Node. Values are expressed in half percent units, ranging from 0 to " + "200. E.g. a value of 48 is equivalent to 24%. A value of NULL shall indicate the Node is currently " + - "unable to assess the value.", + "unable to assess the value." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds, or" + + "\n" + + " • When it changes from null to any other value and vice versa." + + "\n" + + "Since reporting consumes power, devices SHOULD be careful not to over-report.", + xref: { document: "core", section: "11.7.7.13" } }), Attribute({ name: "BatTimeRemaining", id: 0xd, type: "uint32", access: "R V", conformance: "[BAT]", - quality: "X C", + quality: "X Q", + details: "Indicates the estimated time in seconds before the battery will no longer be able to provide power " + - "to the Node. A value of NULL shall indicate the Node is currently unable to assess the value.", + "to the Node. A value of NULL shall indicate the Node is currently unable to assess the value." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds, or" + + "\n" + + " • When it changes from null to any other value and vice versa." + + "\n" + + "Since reporting consumes power, devices SHOULD be careful not to over-report.", + xref: { document: "core", section: "11.7.7.14" } }), @@ -218,7 +238,9 @@ export const PowerSource = Cluster( "detects all conditions contributing to a fault have been cleared, the corresponding BatFaultEnum " + "value shall be removed from this list. An empty list shall indicate there are currently no active " + "faults. The order of this list SHOULD have no significance. Clients interested in monitoring " + - "changes in active faults may subscribe to this attribute, or they may subscribe to BatFaultChange.", + "changes in active faults may subscribe to this attribute, or they may subscribe to Bat" + + "\n" + + "FaultChange.", xref: { document: "core", section: "11.7.7.19" } }, @@ -290,9 +312,19 @@ export const PowerSource = Cluster( Attribute({ name: "BatTimeToFullCharge", id: 0x1b, type: "uint32", access: "R V", conformance: "[RECHG]", - quality: "X C", + quality: "X Q", + details: "Indicates the estimated time in seconds before the battery source will be at full charge. A value " + - "of NULL shall indicate the Node is currently unable to assess the value.", + "of NULL shall indicate the Node is currently unable to assess the value." + + "\n" + + "Changes to this attribute shall only be marked as reportable in the following cases:" + + "\n" + + " • At most once every 10 seconds, or" + + "\n" + + " • When it changes from null to any other value and vice versa." + + "\n" + + "Since reporting consumes power, devices SHOULD be careful not to over-report.", + xref: { document: "core", section: "11.7.7.28" } }), diff --git a/packages/model/src/standard/elements/PowerSourceConfiguration.ts b/packages/model/src/standard/elements/PowerSourceConfiguration.ts index 64a78df0da..9ccec9ede0 100644 --- a/packages/model/src/standard/elements/PowerSourceConfiguration.ts +++ b/packages/model/src/standard/elements/PowerSourceConfiguration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/PowerSourceDT.ts b/packages/model/src/standard/elements/PowerSourceDT.ts index 4c4eed7e06..85ea3c9dfa 100644 --- a/packages/model/src/standard/elements/PowerSourceDT.ts +++ b/packages/model/src/standard/elements/PowerSourceDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/PowerSourceNS.ts b/packages/model/src/standard/elements/PowerSourceNS.ts index c0d18c5583..cefc9c90a1 100644 --- a/packages/model/src/standard/elements/PowerSourceNS.ts +++ b/packages/model/src/standard/elements/PowerSourceNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ export const PowerSourceNs = SemanticNamespace( name: "PowerSource", id: 0xf, details: "The tags contained in this namespace are restricted for use in the power source domain and shall " + "NOT be used in any other domain or context.", - xref: { document: "namespace", section: "12" } + xref: { document: "namespace", section: "15" } }, SemanticTag({ @@ -29,28 +29,28 @@ export const PowerSourceNs = SemanticNamespace( name: "Grid", id: 0x1, description: "The Power Source cluster is related to power provided from the electrical grid", details: "Power Source clusters with this tag shall implement the WIRED feature.", - xref: { document: "namespace", section: "12.1" } + xref: { document: "namespace", section: "15.1" } }), SemanticTag({ name: "Solar", id: 0x2, description: "The Power Source cluster is related to power provided from a solar panel array", details: "Power Source clusters with this tag shall implement the WIRED feature.", - xref: { document: "namespace", section: "12.2" } + xref: { document: "namespace", section: "15.2" } }), SemanticTag({ name: "Battery", id: 0x3, description: "The Power Source cluster is related to power provided from a battery", details: "Power Source clusters with this tag shall implement the BAT feature.", - xref: { document: "namespace", section: "12.3" } + xref: { document: "namespace", section: "15.3" } }), SemanticTag({ name: "EV", id: 0x4, description: "The Power Source cluster is related to power provided from an electric vehicle", details: "Power Source clusters with this tag shall implement the BAT feature.", - xref: { document: "namespace", section: "12.4" } + xref: { document: "namespace", section: "15.4" } }) ); diff --git a/packages/model/src/standard/elements/PowerTopology.ts b/packages/model/src/standard/elements/PowerTopology.ts index 75652db465..c3a5c2aa99 100644 --- a/packages/model/src/standard/elements/PowerTopology.ts +++ b/packages/model/src/standard/elements/PowerTopology.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/PressureMeasurement.ts b/packages/model/src/standard/elements/PressureMeasurement.ts index 2b35480c75..dfa2e0eab4 100644 --- a/packages/model/src/standard/elements/PressureMeasurement.ts +++ b/packages/model/src/standard/elements/PressureMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -46,7 +46,7 @@ export const PressureMeasurement = Cluster( Attribute({ name: "MinMeasuredValue", id: 0x1, type: "int16", access: "R V", conformance: "M", - constraint: "-32767 to maxMeasuredValue1", quality: "X", + constraint: "max 32766", quality: "X", details: "Indicates the minimum value of MeasuredValue that can be measured. See Measured Value for more " + "details." + "\n" + @@ -56,7 +56,7 @@ export const PressureMeasurement = Cluster( Attribute({ name: "MaxMeasuredValue", id: 0x2, type: "int16", access: "R V", conformance: "M", - constraint: "minMeasuredValue1 to 32767", quality: "X", + constraint: "minMeasuredValue + 1 to 32767", quality: "X", details: "Indicates the maximum value of MeasuredValue that can be measured. See Measured Value for more " + "details." + "\n" + @@ -65,8 +65,8 @@ export const PressureMeasurement = Cluster( }), Attribute({ - name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", - constraint: "0 to 2048", default: 0, + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", + default: 0, details: "See Measured Value.", xref: { document: "cluster", section: "2.4.5.4" } }), @@ -86,7 +86,7 @@ export const PressureMeasurement = Cluster( Attribute({ name: "MinScaledValue", id: 0x11, type: "int16", access: "R V", conformance: "EXT", - constraint: "-32767 to maxScaledValue1", default: 0, quality: "X", + constraint: "max 32766", default: 0, quality: "X", details: "Indicates the minimum value of ScaledValue that can be measured. The null value indicates that the " + "value is not available.", xref: { document: "cluster", section: "2.4.5.6" } @@ -94,7 +94,7 @@ export const PressureMeasurement = Cluster( Attribute({ name: "MaxScaledValue", id: 0x12, type: "int16", access: "R V", conformance: "EXT", - constraint: "minScaledValue1 to 32767", default: 0, quality: "X", + constraint: "minScaledValue + 1 to 32767", default: 0, quality: "X", details: "Indicates the maximum value of ScaledValue that can be measured. The null value indicates that the " + "value is not available.", xref: { document: "cluster", section: "2.4.5.7" } @@ -102,7 +102,7 @@ export const PressureMeasurement = Cluster( Attribute({ name: "ScaledTolerance", id: 0x13, type: "uint16", access: "R V", conformance: "[EXT]", - constraint: "0 to 2048", default: 0, + constraint: "max 2048", default: 0, details: "Indicates the magnitude of the possible error that is associated with Scaled" + "\n" + "Value. The true value is located in the range" + @@ -112,7 +112,7 @@ export const PressureMeasurement = Cluster( }), Attribute({ - name: "Scale", id: 0x14, type: "int8", access: "R V", conformance: "EXT", constraint: "-127 to 127", + name: "Scale", id: 0x14, type: "int8", access: "R V", conformance: "EXT", constraint: "min -127", default: 0, details: "Indicates the base 10 exponent used to obtain ScaledValue (see ScaledValue).", xref: { document: "cluster", section: "2.4.5.9" } diff --git a/packages/model/src/standard/elements/PressureSensorDT.ts b/packages/model/src/standard/elements/PressureSensorDT.ts index ccef5dba44..3bcde3afe7 100644 --- a/packages/model/src/standard/elements/PressureSensorDT.ts +++ b/packages/model/src/standard/elements/PressureSensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ProxyConfiguration.ts b/packages/model/src/standard/elements/ProxyConfiguration.ts index d5b6ecfd4c..fc912c476f 100644 --- a/packages/model/src/standard/elements/ProxyConfiguration.ts +++ b/packages/model/src/standard/elements/ProxyConfiguration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/ProxyDiscovery.ts b/packages/model/src/standard/elements/ProxyDiscovery.ts index 161e5ab82a..d9e9346ec5 100644 --- a/packages/model/src/standard/elements/ProxyDiscovery.ts +++ b/packages/model/src/standard/elements/ProxyDiscovery.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/PulseWidthModulation.ts b/packages/model/src/standard/elements/PulseWidthModulation.ts deleted file mode 100644 index 85d7b98235..0000000000 --- a/packages/model/src/standard/elements/PulseWidthModulation.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * @license - * Copyright 2022-2024 Matter.js Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ - -import { MatterDefinition } from "../MatterDefinition.js"; -import { ClusterElement as Cluster } from "../../elements/index.js"; - -export const PulseWidthModulation = Cluster({ name: "PulseWidthModulation", id: 0x1c, type: "LevelControl", pics: "LVL" }); -MatterDefinition.children.push(PulseWidthModulation); diff --git a/packages/model/src/standard/elements/PumpConfigurationAndControl.ts b/packages/model/src/standard/elements/PumpConfigurationAndControl.ts index 16da41ea35..8658977e2d 100644 --- a/packages/model/src/standard/elements/PumpConfigurationAndControl.ts +++ b/packages/model/src/standard/elements/PumpConfigurationAndControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -18,9 +18,23 @@ import { export const PumpConfigurationAndControl = Cluster( { name: "PumpConfigurationAndControl", id: 0x200, classification: "application", pics: "PCC", + details: "The Pump Configuration and Control cluster provides an interface for the setup and control of pump " + "devices, and the automatic reporting of pump status information. Note that control of pump speed is " + - "not included – speed is controlled by the On/Off and Level Control clusters.", + "not included – speed is controlled by the On/Off and Level Control clusters." + + "\n" + + "### Pump controller Pump" + + "\n" + + "C Pump configuration and control S C Level control S" + + "\n" + + "C On/Off S" + + "\n" + + "C = Client S = Server" + + "\n" + + "Note: Device names are examples for illustration purposes only" + + "\n" + + "Figure 14. Typical Usage of Pump Configuration and Control Cluster", + xref: { document: "cluster", section: "4.2" } }, @@ -131,8 +145,9 @@ export const PumpConfigurationAndControl = Cluster( Attribute({ name: "MinConstSpeed", id: 0x7, type: "uint16", access: "R V", conformance: "SPD, [AUTO]", default: null, quality: "X F", - details: "This attribute specifies the minimum speed the pump can achieve when it is working with the " + - "ControlMode attribute set to ConstantSpeed." + + details: "This attribute specifies the minimum speed the pump can achieve when it is working with the Con" + + "\n" + + "trolMode attribute set to ConstantSpeed." + "\n" + "Valid range is 0 to 65,534 RPM (steps of 1 RPM). Null if the value is invalid.", xref: { document: "cluster", section: "4.2.7.8" } @@ -151,9 +166,8 @@ export const PumpConfigurationAndControl = Cluster( Attribute({ name: "MinConstFlow", id: 0x9, type: "uint16", access: "R V", conformance: "FLW, [AUTO]", default: null, quality: "X F", - details: "This attribute specifies the minimum flow the pump can achieve when it is working with the Con" + - "\n" + - "trolMode attribute set to ConstantFlow." + + details: "This attribute specifies the minimum flow the pump can achieve when it is working with the " + + "ControlMode attribute set to ConstantFlow." + "\n" + "Valid range is 0 m/h to 6,553.4 m/h (steps of 0.1 m/h). Null if the value is invalid.", xref: { document: "cluster", section: "4.2.7.10" } @@ -197,7 +211,8 @@ export const PumpConfigurationAndControl = Cluster( name: "PumpStatus", id: 0x10, type: "PumpStatusBitmap", access: "R V", conformance: "O", constraint: "desc", default: 0, quality: "P", details: "This attribute specifies the activity status of the pump functions as listed in PumpStatusBitmap. " + - "Where a pump controller function is active, the corresponding bit shall be set to 1. Where a pump " + + "Where a pump controller function is active, the corresponding bit shall be set to 1. Where a pump" + + "\n" + "controller function is not active, the corresponding bit shall be set to 0.", xref: { document: "cluster", section: "4.2.7.14" } }), @@ -276,7 +291,7 @@ export const PumpConfigurationAndControl = Cluster( "If the value is not available (the measurement or estimation of the speed is done in the pump), " + "this attribute will indicate the null value." + "\n" + - "Valid range is 0 to 65.534 RPM.", + "Valid range is 0 to 65,534 RPM.", xref: { document: "cluster", section: "4.2.7.18" } }), @@ -290,10 +305,10 @@ export const PumpConfigurationAndControl = Cluster( "cycles of the pump. If LifeTimeRunningHours rises above maximum value it “rolls over” and starts at " + "0 (zero)." + "\n" + - "This attribute is writeable, in order to allow setting to an appropriate value after maintenance. If" + + "This attribute is writeable, in order to allow setting to an appropriate value after maintenance. " + + "If the value is not available, this attribute will indicate the null value." + "\n" + - "the value is not available, this attribute will indicate the null value. Valid range is 0 to " + - "16,777,214 hrs.", + "Valid range is 0 to 16,777,214 hrs.", xref: { document: "cluster", section: "4.2.7.19" } }), @@ -370,9 +385,7 @@ export const PumpConfigurationAndControl = Cluster( details: "This attribute specifies the control mode of the pump as defined in ControlModeEnum." + "\n" + - "See the OperationMode attribute for a detailed description of the operation and control of the" + - "\n" + - "pump." + + "See the OperationMode attribute for a detailed description of the operation and control of the pump." + "\n" + "ControlMode may be changed at any time, even when the pump is running. The behavior of the pump at " + "the point of changing is vendor-specific." + @@ -384,11 +397,7 @@ export const PumpConfigurationAndControl = Cluster( xref: { document: "cluster", section: "4.2.7.23" } }), - Attribute({ - name: "AlarmMask", id: 0x22, type: "uint16", access: "R V", conformance: "D", constraint: "desc", - default: 0, quality: "N", - xref: { document: "cluster", section: "4.2.7" } - }), + Attribute({ name: "AlarmMask", id: 0x22, type: "uint16", conformance: "D", xref: { document: "cluster", section: "4.2.7" } }), Event({ name: "SupplyVoltageLow", id: 0x0, access: "V", conformance: "O", priority: "info", xref: { document: "cluster", section: "4.2.8" } @@ -567,9 +576,10 @@ export const PumpConfigurationAndControl = Cluster( Field({ name: "ProportionalPressure", id: 0x2, conformance: "PRSCOMP", description: "The pump will regulate its speed to maintain a constant differential pressure over its flanges.", - details: "The setpoint is interpreted as a percentage of the range derived of the [MinCompPressure – " + - "MaxCompPressure] attributes. The internal setpoint will be lowered (compensated) dependent on the " + - "flow in the pump (lower flow ⇒ lower internal setpoint).", + details: "The setpoint is interpreted as a percentage of the range derived of the [MinCompPressure – Max" + + "\n" + + "CompPressure] attributes. The internal setpoint will be lowered (compensated) dependent on the flow " + + "in the pump (lower flow ⇒ lower internal setpoint).", xref: { document: "cluster", section: "4.2.6.3.3" } }), diff --git a/packages/model/src/standard/elements/PumpControllerDT.ts b/packages/model/src/standard/elements/PumpControllerDT.ts index b42240b4dc..df59f400b8 100644 --- a/packages/model/src/standard/elements/PumpControllerDT.ts +++ b/packages/model/src/standard/elements/PumpControllerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,12 +17,8 @@ export const PumpControllerDt = DeviceType( }, Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 772, revision: 3 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 772, revision: 4 } ], element: "attribute" }) ), - Requirement({ - name: "Binding", id: 0x1e, conformance: "M", element: "clientCluster", - xref: { document: "device", section: "6.5.3" } - }), Requirement({ name: "OnOff", id: 0x6, conformance: "M", element: "clientCluster", xref: { document: "device", section: "6.5.3" } diff --git a/packages/model/src/standard/elements/PumpDT.ts b/packages/model/src/standard/elements/PumpDT.ts index c4ab3d6d01..0ecec9d086 100644 --- a/packages/model/src/standard/elements/PumpDT.ts +++ b/packages/model/src/standard/elements/PumpDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const PumpDt = DeviceType( classification: "simple", details: "A Pump device is a pump that may have variable speed. It may have optional built-in sensors and a " + "regulation mechanism. It is typically used for pumping fluids like water.", - xref: { document: "device", section: "5.3" } + xref: { document: "device", section: "5.5" } }, Requirement( @@ -24,55 +24,55 @@ export const PumpDt = DeviceType( ), Requirement({ name: "OnOff", id: 0x6, conformance: "M", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "PumpConfigurationAndControl", id: 0x200, conformance: "M", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "LevelControl", id: 0x8, conformance: "O", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "Groups", id: 0x4, conformance: "O", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "PressureMeasurement", id: 0x403, conformance: "O", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "FlowMeasurement", id: 0x404, conformance: "O", element: "serverCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "clientCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "PressureMeasurement", id: 0x403, conformance: "O", element: "clientCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "FlowMeasurement", id: 0x404, conformance: "O", element: "clientCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }), Requirement({ name: "OccupancySensing", id: 0x406, conformance: "O", element: "clientCluster", - xref: { document: "device", section: "5.3.4" } + xref: { document: "device", section: "5.5.4" } }) ) diff --git a/packages/model/src/standard/elements/RadonConcentrationMeasurement.ts b/packages/model/src/standard/elements/RadonConcentrationMeasurement.ts index 79f1c765c3..07b0bd2ce9 100644 --- a/packages/model/src/standard/elements/RadonConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/RadonConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/RainSensorDT.ts b/packages/model/src/standard/elements/RainSensorDT.ts index facb9b9052..8d4d15329a 100644 --- a/packages/model/src/standard/elements/RainSensorDT.ts +++ b/packages/model/src/standard/elements/RainSensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/RefrigeratorAlarm.ts b/packages/model/src/standard/elements/RefrigeratorAlarm.ts index a8f02cc9b8..1c8f78e6c6 100644 --- a/packages/model/src/standard/elements/RefrigeratorAlarm.ts +++ b/packages/model/src/standard/elements/RefrigeratorAlarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,8 @@ export const RefrigeratorAlarm = Cluster( { name: "RefrigeratorAlarm", id: 0x57, type: "AlarmBase", classification: "application", pics: "REFALM", - details: "This cluster is a derived cluster of Alarm Base cluster.", + details: "This cluster is a derived cluster of Alarm Base cluster and provides the alarm definition related " + + "to refrigerator and temperature controlled cabinet devices.", xref: { document: "cluster", section: "8.8" } }, diff --git a/packages/model/src/standard/elements/RefrigeratorAndTemperatureControlledCabinetMode.ts b/packages/model/src/standard/elements/RefrigeratorAndTemperatureControlledCabinetMode.ts index 78397d2ef0..828e6ded4b 100644 --- a/packages/model/src/standard/elements/RefrigeratorAndTemperatureControlledCabinetMode.ts +++ b/packages/model/src/standard/elements/RefrigeratorAndTemperatureControlledCabinetMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,46 +10,68 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + DatatypeElement as Datatype } from "../../elements/index.js"; export const RefrigeratorAndTemperatureControlledCabinetMode = Cluster( { name: "RefrigeratorAndTemperatureControlledCabinetMode", id: 0x52, type: "ModeBase", classification: "application", pics: "TCCM", - details: "This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced " + + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + "enumerated values for refrigerator and temperature controlled cabinet devices.", xref: { document: "cluster", section: "8.7" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), - Attribute({ name: "SupportedModes", id: 0x0, conformance: "M", xref: { document: "cluster", section: "8.7.5" } }), - Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.7.5" } }), - Attribute({ name: "StartUpMode", id: 0x2, conformance: "P", xref: { document: "cluster", section: "8.7.5" } }), - Attribute({ name: "OnMode", id: 0x3, conformance: "P", xref: { document: "cluster", section: "8.7.5" } }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "8.7.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, conformance: "M", + details: "At least one entry in the SupportedModes attribute shall include the Auto mode tag in the ModeTags " + + "field list.", + xref: { document: "cluster", section: "8.7.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, conformance: "M", xref: { document: "cluster", section: "8.7.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "8.7.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "8.7.6" } }), Datatype({ name: "ModeOptionStruct", type: "ModeOptionStruct", details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + - "ModeOptionStruct type. A blank field indicates no change." + - "\n" + - "At least one entry in the SupportedModes attribute shall include the Auto mode tag in the ModeTags " + - "field list.", - xref: { document: "cluster", section: "8.7.4.1" } + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "8.7.5.1" } }), Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "8.7.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "8.7.7.1" } }), Field({ name: "RapidCool", id: 0x4000, details: "This mode reduces the temperature rapidly, typically above freezing grade.", - xref: { document: "cluster", section: "8.7.6.1.1" } + xref: { document: "cluster", section: "8.7.7.1.1" } }), Field({ name: "RapidFreeze", id: 0x4001, details: "This mode reduces the temperature rapidly, below freezing grade.", - xref: { document: "cluster", section: "8.7.6.1.2" } + xref: { document: "cluster", section: "8.7.7.1.2" } }) ) ) diff --git a/packages/model/src/standard/elements/RefrigeratorDT.ts b/packages/model/src/standard/elements/RefrigeratorDT.ts index be6402bff8..04d8ce8825 100644 --- a/packages/model/src/standard/elements/RefrigeratorDT.ts +++ b/packages/model/src/standard/elements/RefrigeratorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,7 +20,7 @@ export const RefrigeratorDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 112, revision: 1 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 112, revision: 2 } ], element: "attribute" }) ), Requirement({ name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", diff --git a/packages/model/src/standard/elements/RefrigeratorNS.ts b/packages/model/src/standard/elements/RefrigeratorNS.ts index 6356e924d0..e68bf6ff05 100644 --- a/packages/model/src/standard/elements/RefrigeratorNS.ts +++ b/packages/model/src/standard/elements/RefrigeratorNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ export const RefrigeratorNs = SemanticNamespace( name: "Refrigerator", id: 0x41, details: "The tags contained in this namespace are restricted for use in the refrigerator domain and shall " + "NOT be used in any other domain or context.", - xref: { document: "namespace", section: "13" } + xref: { document: "namespace", section: "16" } }, SemanticTag({ name: "Refrigerator", id: 0x0 }), diff --git a/packages/model/src/standard/elements/RelativeHumidityMeasurement.ts b/packages/model/src/standard/elements/RelativeHumidityMeasurement.ts index 38a48880ad..07c04b7ec9 100644 --- a/packages/model/src/standard/elements/RelativeHumidityMeasurement.ts +++ b/packages/model/src/standard/elements/RelativeHumidityMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -45,7 +45,7 @@ export const RelativeHumidityMeasurement = Cluster( Attribute({ name: "MinMeasuredValue", id: 0x1, type: "uint16", access: "R V", conformance: "M", - constraint: "0 to maxMeasuredValue1", quality: "X", + constraint: "max 9999", quality: "X", details: "The MinMeasuredValue attribute indicates the minimum value of MeasuredValue that can be measured. " + "The null value means this attribute is not defined. See Measured Value for more details.", xref: { document: "cluster", section: "2.6.4.2" } @@ -53,15 +53,14 @@ export const RelativeHumidityMeasurement = Cluster( Attribute({ name: "MaxMeasuredValue", id: 0x2, type: "uint16", access: "R V", conformance: "M", - constraint: "minMeasuredValue1 to 10000", quality: "X", + constraint: "minMeasuredValue + 1 to 10000", quality: "X", details: "The MaxMeasuredValue attribute indicates the maximum value of MeasuredValue that can be measured. " + "The null value means this attribute is not defined. See Measured Value for more details.", xref: { document: "cluster", section: "2.6.4.3" } }), Attribute({ - name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", - constraint: "0 to 2048", + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", details: "See Measured Value.", xref: { document: "cluster", section: "2.6.4.4" } }) diff --git a/packages/model/src/standard/elements/RelativePositionNS.ts b/packages/model/src/standard/elements/RelativePositionNS.ts new file mode 100644 index 0000000000..cef9996195 --- /dev/null +++ b/packages/model/src/standard/elements/RelativePositionNS.ts @@ -0,0 +1,35 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + SemanticNamespaceElement as SemanticNamespace, + SemanticTagElement as SemanticTag +} from "../../elements/index.js"; + +export const RelativePositionNs = SemanticNamespace( + { + name: "RelativePosition", id: 0x12, + details: "The tags contained in this namespace may be used in any domain or context, to indicate an " + + "association with a position relative to some reference, which must be specified by the user of " + + "these tags. For example, the position may be relative to a household item, such as a dining table, " + + "and the user of these tags must indicate that. Note the difference with Chapter 9, Common Position " + + "Semantic Tag Namespace, which contains tags indicating the position relative to the device.", + xref: { document: "namespace", section: "11" } + }, + + SemanticTag({ name: "Under", id: 0x0 }), + SemanticTag({ name: "Next To", id: 0x1, description: "Area in proximity to the point of reference" }), + SemanticTag({ name: "Around", id: 0x2, description: "The area surrounding the point the reference" }), + SemanticTag({ name: "On", id: 0x3 }), + SemanticTag({ name: "Above", id: 0x4 }), + SemanticTag({ name: "Front Of", id: 0x5 }), + SemanticTag({ name: "Behind", id: 0x6 }) +); + +MatterDefinition.children.push(RelativePositionNs); diff --git a/packages/model/src/standard/elements/ResourceMonitoring.ts b/packages/model/src/standard/elements/ResourceMonitoring.ts index ba26f4adc9..5a1a534b09 100644 --- a/packages/model/src/standard/elements/ResourceMonitoring.ts +++ b/packages/model/src/standard/elements/ResourceMonitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,8 @@ export const ResourceMonitoring = Cluster( { name: "ResourceMonitoring", classification: "application", pics: "REPM", - details: "This generic cluster provides an interface to the current condition of a resource. A resource is a " + + details: "This generic cluster provides an interface to the current condition of a resource. A resource is a" + + "\n" + "component of a device that is designed to be replaced, refilled, or emptied when exhausted or full. " + "Examples of resources include filters, cartridges, and water tanks. While batteries fit this " + "definition they are not intended to be used with this cluster. Use the power source cluster for " + diff --git a/packages/model/src/standard/elements/RoboticVacuumCleanerDT.ts b/packages/model/src/standard/elements/RoboticVacuumCleanerDT.ts index 6d4914d98a..a2c9b1d5d9 100644 --- a/packages/model/src/standard/elements/RoboticVacuumCleanerDT.ts +++ b/packages/model/src/standard/elements/RoboticVacuumCleanerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ export const RoboticVacuumCleanerDt = DeviceType( }, Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 116, revision: 2 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 116, revision: 3 } ], element: "attribute" }) ), Requirement({ name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", @@ -34,6 +34,10 @@ export const RoboticVacuumCleanerDt = DeviceType( Requirement({ name: "RvcOperationalState", id: 0x61, conformance: "M", element: "serverCluster", xref: { document: "device", section: "12.1.4" } + }), + Requirement({ + name: "ServiceArea", id: 0x150, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "12.1.4" } }) ); diff --git a/packages/model/src/standard/elements/RoomAirConditionerDT.ts b/packages/model/src/standard/elements/RoomAirConditionerDT.ts index 6cd9585fdb..998e0ec157 100644 --- a/packages/model/src/standard/elements/RoomAirConditionerDT.ts +++ b/packages/model/src/standard/elements/RoomAirConditionerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/RoomAirConditionerNS.ts b/packages/model/src/standard/elements/RoomAirConditionerNS.ts index 9c65179301..de1d65224e 100644 --- a/packages/model/src/standard/elements/RoomAirConditionerNS.ts +++ b/packages/model/src/standard/elements/RoomAirConditionerNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ export const RoomAirConditionerNs = SemanticNamespace( name: "RoomAirConditioner", id: 0x42, details: "The tags contained in this namespace are restricted for use in the room air conditioner domain and " + "shall NOT be used in any other domain or context.", - xref: { document: "namespace", section: "14" } + xref: { document: "namespace", section: "17" } }, SemanticTag({ name: "Evaporator", id: 0x0 }), diff --git a/packages/model/src/standard/elements/RootNodeDT.ts b/packages/model/src/standard/elements/RootNodeDT.ts index 1b93811c07..2387098f85 100644 --- a/packages/model/src/standard/elements/RootNodeDT.ts +++ b/packages/model/src/standard/elements/RootNodeDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -34,16 +34,21 @@ export const RootNodeDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 22, revision: 2 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 22, revision: 3 } ], element: "attribute" }) ), Requirement({ name: "BasicInformation", id: 0x28, conformance: "M", element: "serverCluster", quality: "I", xref: { document: "device", section: "2.1.5" } }), - Requirement({ - name: "AccessControl", id: 0x1f, conformance: "M", element: "serverCluster", quality: "I", - xref: { document: "device", section: "2.1.5" } - }), + + Requirement( + { + name: "AccessControl", id: 0x1f, conformance: "M", element: "serverCluster", quality: "I", + xref: { document: "device", section: "2.1.5" } + }, + Requirement({ name: "MNGD", conformance: "[ManagedAclAllowed]", constraint: "desc", element: "feature" }) + ), + Requirement({ name: "PowerSourceConfiguration", id: 0x2e, conformance: "O, D", element: "serverCluster", quality: "I", @@ -104,26 +109,23 @@ export const RootNodeDt = DeviceType( }), Requirement({ name: "EthernetNetworkDiagnostics", id: 0x37, conformance: "[Ethernet]", element: "serverCluster", - quality: "I", xref: { document: "device", section: "2.1.5" } }), Requirement({ - name: "WiFiNetworkDiagnostics", id: 0x36, conformance: "[Wi, 0, i]", element: "serverCluster", - quality: "I", + name: "WiFiNetworkDiagnostics", id: 0x36, conformance: "[Wi, Fi]", element: "serverCluster", xref: { document: "device", section: "2.1.5" } }), Requirement({ name: "ThreadNetworkDiagnostics", id: 0x35, conformance: "[Thread]", element: "serverCluster", - quality: "I", xref: { document: "device", section: "2.1.5" } }), Requirement( { - name: "IcdManagement", id: 0x46, conformance: "SIT", element: "serverCluster", quality: "I", + name: "IcdManagement", id: 0x46, conformance: "SIT | LIT", element: "serverCluster", quality: "I", xref: { document: "device", section: "2.1.5" } }, - Requirement({ name: "LONGIDLETIMESUPPORT", conformance: "P, LIT", element: "feature" }) + Requirement({ name: "LONGIDLETIMESUPPORT", conformance: "LIT", element: "feature" }) ), Field( @@ -132,6 +134,11 @@ export const RootNodeDt = DeviceType( name: "CustomNetworkConfig", description: "The node only supports out-of-band-configured networking (e.g. rich user interface, manufacturer-specific means, custom commissioning flows, or future IP-compliant network technology not yet directly supported by NetworkCommissioning cluster).", xref: { document: "device", section: "2.1.3" } + }), + Field({ + name: "ManagedAclAllowed", + description: "The node has at least one endpoint where some Device Type present on the endpoint has a Device Library element requirement table entry that sets this condition to true.", + xref: { document: "device", section: "2.1.3" } }) ) ); diff --git a/packages/model/src/standard/elements/RvcCleanMode.ts b/packages/model/src/standard/elements/RvcCleanMode.ts index f67ade5599..e6465a14e8 100644 --- a/packages/model/src/standard/elements/RvcCleanMode.ts +++ b/packages/model/src/standard/elements/RvcCleanMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,31 +10,43 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + DatatypeElement as Datatype } from "../../elements/index.js"; export const RvcCleanMode = Cluster( { name: "RvcCleanMode", id: 0x55, type: "ModeBase", classification: "application", pics: "RVCCLEANM", - details: "This cluster is derived from the Mode Base cluster to define specifics for Robotic Vacuum Cleaner " + - "devices. It also defines a namespace for the cleaning type for these devices.", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for the cleaning type of robotic vacuum cleaner devices.", xref: { document: "cluster", section: "7.3" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), - Attribute({ name: "SupportedModes", id: 0x0, xref: { document: "cluster", section: "7.3.6" } }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "7.3.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + details: "At least one entry in the SupportedModes attribute shall include the Vacuum and/or the Mop mode tag " + + "in the ModeTags field list.", + xref: { document: "cluster", section: "7.3.6.1" } + }), + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "7.3.6" } }), Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "7.3.6" } }), - Attribute({ name: "OnMode", id: 0x3, conformance: "D", xref: { document: "cluster", section: "7.3.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "7.3.6" } }), Datatype({ name: "ModeOptionStruct", type: "ModeOptionStruct", details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + - "ModeOptionStruct type. A blank field indicates no change." + - "\n" + - "At least one entry in the SupportedModes attribute shall include the Vacuum and/or the Mop mode tag " + - "in the ModeTags field list.", + "ModeOptionStruct type. A blank field indicates no change.", xref: { document: "cluster", section: "7.3.5.1" } }), @@ -45,6 +57,16 @@ export const RvcCleanMode = Cluster( Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "7.3.7.2" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "7.3.7.2" } }), Field({ name: "DeepClean", id: 0x4000, xref: { document: "cluster", section: "7.3.7.2" } }), Field({ name: "Vacuum", id: 0x4001, diff --git a/packages/model/src/standard/elements/RvcOperationalState.ts b/packages/model/src/standard/elements/RvcOperationalState.ts index 3bbff067ea..97a4901a3c 100644 --- a/packages/model/src/standard/elements/RvcOperationalState.ts +++ b/packages/model/src/standard/elements/RvcOperationalState.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,19 +19,20 @@ export const RvcOperationalState = Cluster( { name: "RvcOperationalState", id: 0x61, type: "OperationalState", classification: "application", pics: "RVCOPSTATE", - details: "This cluster provides an interface for monitoring the operational state of a Robotic Vacuum Cleaner.", + details: "This cluster is derived from the Operational State cluster and provides an interface for monitoring " + + "the operational state of a robotic vacuum cleaner.", xref: { document: "cluster", section: "7.4" } }, Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), Command({ name: "Pause", id: 0x0, xref: { document: "cluster", section: "7.4.5" } }), - Command({ name: "Stop", id: 0x1, conformance: "D", xref: { document: "cluster", section: "7.4.5" } }), - Command({ name: "Start", id: 0x2, conformance: "D", xref: { document: "cluster", section: "7.4.5" } }), + Command({ name: "Stop", id: 0x1, conformance: "X", xref: { document: "cluster", section: "7.4.5" } }), + Command({ name: "Start", id: 0x2, conformance: "X", xref: { document: "cluster", section: "7.4.5" } }), Command({ name: "Resume", id: 0x3, xref: { document: "cluster", section: "7.4.5" } }), Command({ name: "OperationalCommandResponse", id: 0x4, xref: { document: "cluster", section: "7.4.5" } }), Command({ - name: "GoHome", id: 0x80, access: "O", conformance: "P, O", direction: "request", + name: "GoHome", id: 0x80, access: "O", conformance: "O", direction: "request", response: "OperationalCommandResponse", details: "On receipt of this command, the device shall start seeking the charging dock, if possible in the " + @@ -65,12 +66,12 @@ export const RvcOperationalState = Cluster( "RVC Pause Compatibility defines the compatibility of the states this cluster defines with the Pause " + "command." + "\n" + - "### Table 39. RVC Pause Compatibility" + + "### Table 13. RVC Pause Compatibility" + "\n" + "RVC Resume Compatibility defines the compatibility of the states this cluster defines with the " + "Resume command." + "\n" + - "### Table 40. RVC Resume Compatibility" + + "### Table 14. RVC Resume Compatibility" + "\n" + "While in the Charging or Docked states, the device shall NOT attempt to resume unless it " + "transitioned to those states while operating and can resume, such as, for example, if it is " + @@ -82,6 +83,10 @@ export const RvcOperationalState = Cluster( xref: { document: "cluster", section: "7.4.4.1" } }, + Field({ name: "Stopped", id: 0x0, conformance: "M", description: "The device is stopped" }), + Field({ name: "Running", id: 0x1, conformance: "M", description: "The device is operating" }), + Field({ name: "Paused", id: 0x2, conformance: "M", description: "The device is paused during an operation" }), + Field({ name: "Error", id: 0x3, conformance: "M", description: "The device is in an error state" }), Field({ name: "SeekingCharger", id: 0x40, conformance: "M", description: "The device is en route to the charging dock" @@ -98,6 +103,19 @@ export const RvcOperationalState = Cluster( xref: { document: "cluster", section: "7.4.4.2" } }, + Field({ name: "NoError", id: 0x0, conformance: "M", description: "The device is not in an error state" }), + Field({ + name: "UnableToStartOrResume", id: 0x1, conformance: "M", + description: "The device is unable to start or resume operation" + }), + Field({ + name: "UnableToCompleteOperation", id: 0x2, conformance: "M", + description: "The device was unable to complete the current operation" + }), + Field({ + name: "CommandInvalidInState", id: 0x3, conformance: "M", + description: "The device cannot process the command in its current state" + }), Field({ name: "FailedToFindChargingDock", id: 0x40, conformance: "M", description: "The device has failed to find or reach the charging dock" diff --git a/packages/model/src/standard/elements/RvcRunMode.ts b/packages/model/src/standard/elements/RvcRunMode.ts index 3cf46ef906..73078538de 100644 --- a/packages/model/src/standard/elements/RvcRunMode.ts +++ b/packages/model/src/standard/elements/RvcRunMode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,31 +10,32 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { ClusterElement as Cluster, AttributeElement as Attribute, - DatatypeElement as Datatype, - FieldElement as Field + FieldElement as Field, + DatatypeElement as Datatype } from "../../elements/index.js"; export const RvcRunMode = Cluster( { name: "RvcRunMode", id: 0x54, type: "ModeBase", classification: "application", pics: "RVCRUNM", - details: "This cluster is derived from the Mode Base cluster to define specifics for Robotic Vacuum Cleaner " + - "devices. It also defines a namespace for the running modes of these devices.", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for the running modes of robotic vacuum cleaner devices.", xref: { document: "cluster", section: "7.2" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), - Attribute({ name: "SupportedModes", id: 0x0, xref: { document: "cluster", section: "7.2.6" } }), - Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "7.2.6" } }), - Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "7.2.6" } }), - Attribute({ name: "OnMode", id: 0x3, conformance: "D", xref: { document: "cluster", section: "7.2.6" } }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), - Datatype({ - name: "ModeOptionStruct", type: "ModeOptionStruct", + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "7.2.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), - details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + - "ModeOptionStruct type. A blank field indicates no change." + - "\n" + - "At least one entry in the SupportedModes attribute shall include the Idle mode tag in the ModeTags " + + Attribute({ + name: "SupportedModes", id: 0x0, + + details: "At least one entry in the SupportedModes attribute shall include the Idle mode tag in the ModeTags " + "field." + "\n" + "At least one entry in the SupportedModes attribute (different from the one above) shall include the " + @@ -43,6 +44,17 @@ export const RvcRunMode = Cluster( "The Mapping, Cleaning, and Idle mode tags are mutually exclusive and shall NOT be used together in " + "a mode’s ModeTags.", + xref: { document: "cluster", section: "7.2.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "7.2.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "7.2.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "7.2.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", xref: { document: "cluster", section: "7.2.5.1" } }), @@ -60,6 +72,16 @@ export const RvcRunMode = Cluster( Datatype( { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "7.2.7.2" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "7.2.7.2" } }), Field({ name: "Idle", id: 0x4000, diff --git a/packages/model/src/standard/elements/ScenesManagement.ts b/packages/model/src/standard/elements/ScenesManagement.ts index a64b4e61a6..0682267f84 100644 --- a/packages/model/src/standard/elements/ScenesManagement.ts +++ b/packages/model/src/standard/elements/ScenesManagement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,7 @@ export const ScenesManagement = Cluster( "In most cases scenes are associated with a particular group identifier. Scenes may also exist " + "without a group, in which case the value 0 replaces the group identifier. Note that extra care is " + "required in these cases to avoid a scene identifier collision, and that commands related to scenes " + - "without a group may only be unicast, i.e., they may not be multicast or broadcast." + + "without a group may only be unicast, i.e., they shall NOT be multicast or broadcast." + "\n" + "NOTE Support for Scenes Management cluster is provisional.", @@ -480,8 +480,7 @@ export const ScenesManagement = Cluster( Field({ name: "SceneIdentifierFrom", id: 0x2, type: "uint8", conformance: "M", constraint: "max 254", - details: "This field shall be set to the same values as in the corresponding fields of the received CopyScene" + - "\n" + + details: "This field shall be set to the same values as in the corresponding fields of the received CopyScene " + "command.", xref: { document: "cluster", section: "1.4.9.16.3" } }) @@ -564,17 +563,19 @@ export const ScenesManagement = Cluster( details: "This field shall be present for all instances in a given ExtensionFieldSetStruct." + "\n" + - "The data type of AttributeValue shall be the data type of the attribute indicated by AttributeID." + + "Which Value* field is used shall be determined based on the data type of the attribute indicated by " + + "AttributeID, as described in the Value* Fields subsection." + "\n" + "The AttributeID field shall NOT refer to an attribute without the Scenes (\"S\") designation in the " + "Quality column of the cluster specification." + "\n" + - " 1.4.7.3.2. ValueUnsigned8, ValueSigned8, ValueUnsigned16, ValueSigned16, ValueUnsigned32, " + - " ValueSigned32, ValueUnsigned64, ValueSigned64 Fields" + + "### 1.4.7.3.2. ValueUnsigned8, ValueSigned8, ValueUnsigned16, ValueSigned16, ValueUnsigned32, " + + "ValueSigned32, ValueUnsigned64, ValueSigned64 Fields" + "\n" + "These fields shall indicate the attribute value as part of an extension field set, associated with " + - "a given AttributeID under an ExtensionFieldSetStruct’s ClusterID. The proper field shall be present " + - "that maps to the data type of the attribute indicated." + + "a given AttributeID under an ExtensionFieldSetStruct’s ClusterID. Which of the fields is used shall" + + "\n" + + "be determined by the type of the attribute indicated by AttributeID as follows:" + "\n" + " • Data types bool, map8, and uint8 shall map to ValueUnsigned8." + "\n" + @@ -588,33 +589,51 @@ export const ScenesManagement = Cluster( "\n" + " • Data types int24 and int32 shall map to ValueSigned32." + "\n" + - " • Data types map64, uint48, uint56 and uint64 shall map to ValueUnsigned64." + + " • Data types map64, uint40, uint48, uint56 and uint64 shall map to ValueUnsigned64." + + "\n" + + " • Data types int40, int48, int56 and int64 shall map to ValueSigned64." + + "\n" + + " • For derived types, the mapping shall be based on the base type. For example, an attribute of " + + " type percent shall be treated as if it were of type uint8, whereas an attribute of type " + + " percent100ths shall be treated as if it were of type uint16." + + "\n" + + " • For boolean nullable attributes, any value that is not 0 or 1 shall be considered to have the " + + " null value." + + "\n" + + " • For boolean non-nullable attributes, any value that is not 0 or 1 shall be considered to have " + + " the value FALSE." + + "\n" + + " • For non-boolean nullable attributes, any value that is not a valid numeric value for the " + + " attribute’s type after accounting for range reductions due to being nullable and constraints " + + " shall be considered to have the null value for the type." + "\n" + - " • Data types int48, int56 and int64 shall map to ValueSigned64." + + " • For non-boolean non-nullable attributes, any value that is not a valid numeric value for the " + + " attribute’s type after accounting for constraints shall be considered to be the valid attribute " + + " value that is closest to the provided value." + "\n" + - " • For nullable attributes, any value that is not a valid numeric value for the attribute’s type " + - " after accounting for range reductions due to being nullable and constraints shall be considered " + - " to have the null value for the type." + + " ◦ In the event that an invalid provided value is of equal numerical distance to the two closest " + + " valid values, the lowest of those values shall be considered the closest valid attribute " + + " value." + "\n" + - " • For non-nullable attributes, any value that is not a valid numeric value for the attribute’s " + - " type after accounting for constraints shall be considered to have the maximum legal value in " + - " the attribute’s constrained range." + + "If the used field does not match the data type of the attribute indicated by AttributeID, the " + + "AttributeValuePairStruct shall be considered invalid." + "\n" + "Examples of processing are:" + "\n" + " • ColorControl cluster CurrentX (AttributeID 0x0003) has a type of uint16 and is not nullable." + "\n" + - " ◦ AttributeValue of 0xAB12 would be used as-is, as it is in range." + + " ◦ ValueUnsigned16 of 0xAB12 would be used as-is, as it is in range." + "\n" + - " ◦ AttributeValue of 0xAA0011 is outside of the range of uint16, and would be saturated to the " + - " maximum of the attribute’s constraint range: 0xFEFF." + + " ◦ ValueUnsigned16 of 0xFF80 is outside of the range allowed for attribute CurrentX, and would " + + " be saturated to the closest valid value, which is the maximum of the attribute’s constraint " + + " range: 0xFEFF." + "\n" + " • LevelControl cluster CurrentLevel (AttributeID 0x0000) has a type of uint8 and is nullable." + "\n" + - " ◦ AttributeValue of 0xA1 would be used as-is, as it is in range." + + " ◦ ValueUnsigned8 of 0xA1 would be used as-is, as it is in range." + "\n" + - " ◦ AttributeValue of 0xBB12 is outside the range of nullable uint8, and would be considered as " + - " the null value.", + " ◦ ValueUnsigned8 of 0xFF is outside the range allowed for nullable attribute CurrentLevel, and " + + " would be considered as the null value.", xref: { document: "cluster", section: "1.4.7.3.1" } }), @@ -659,7 +678,7 @@ export const ScenesManagement = Cluster( Datatype( { - name: "Logical Scene Table", type: "struct", + name: "LogicalSceneTable", type: "struct", details: "The Scene Table is used to store information for each scene capable of being invoked on the server. " + "Each scene is defined for a particular group. The Scene Table is defined here as a conceptual " + diff --git a/packages/model/src/standard/elements/SecondaryNetworkInterfaceDT.ts b/packages/model/src/standard/elements/SecondaryNetworkInterfaceDT.ts new file mode 100644 index 0000000000..2078403951 --- /dev/null +++ b/packages/model/src/standard/elements/SecondaryNetworkInterfaceDT.ts @@ -0,0 +1,49 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const SecondaryNetworkInterfaceDt = DeviceType( + { + name: "SecondaryNetworkInterface", id: 0x19, category: "Utility", classification: "utility", + + details: "A Secondary Network Interface device provides an additional network interface supported by the " + + "Node, supplementing the primary interface hosted by the Root Node endpoint." + + "\n" + + "A Node supporting multiple network interfaces shall include the primary interface on the Root Node " + + "endpoint, along with secondary interfaces on other endpoints. The priorities of these network " + + "interfaces are determined by the order of their endpoints, where interfaces with smaller endpoint " + + "numbers are higher priority.", + + xref: { document: "device", section: "2.8" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 25, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "NetworkCommissioning", id: 0x31, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "2.8.3" } + }), + Requirement({ + name: "EthernetNetworkDiagnostics", id: 0x37, conformance: "[Ethernet]", element: "serverCluster", + xref: { document: "device", section: "2.8.3" } + }), + Requirement({ + name: "WiFiNetworkDiagnostics", id: 0x36, conformance: "[Wi, Fi]", element: "serverCluster", + xref: { document: "device", section: "2.8.3" } + }), + Requirement({ + name: "ThreadNetworkDiagnostics", id: 0x35, conformance: "[Thread]", element: "serverCluster", + xref: { document: "device", section: "2.8.3" } + }) +); + +MatterDefinition.children.push(SecondaryNetworkInterfaceDt); diff --git a/packages/model/src/standard/elements/ServiceArea.ts b/packages/model/src/standard/elements/ServiceArea.ts new file mode 100644 index 0000000000..0d1069023c --- /dev/null +++ b/packages/model/src/standard/elements/ServiceArea.ts @@ -0,0 +1,708 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + FieldElement as Field, + CommandElement as Command, + DatatypeElement as Datatype +} from "../../elements/index.js"; + +export const ServiceArea = Cluster( + { + name: "ServiceArea", id: 0x150, classification: "application", pics: "SEAR", + + details: "This cluster provides an interface for controlling the areas where a device should operate, for " + + "reporting the status at each area, and for querying the current area." + + "\n" + + "The device may operate at one area at a time, as in the case of a mobile device, such as a robot. " + + "Other devices may operate at (service) multiple areas simultaneously, as in the case of a sensor " + + "that can monitor multiple areas. This cluster specification uses the term \"operate\" to describe " + + "both the operating and servicing actions, regardless of the device type." + + "\n" + + "The cluster allows the client to select one or more areas on the server, to indicate where the " + + "device SHOULD attempt to operate. An area is one of a list of options that may be presented by a " + + "client for a user choice, or understood by the client, via the semantic data of the area." + + "\n" + + "The area semantic data is a combination of semantic tags, indicating one or more of the following: " + + "the building floor, area type, landmark, and relative position.", + + xref: { document: "cluster", section: "1.17" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.17.4" } }, + + Field({ + name: "SELRUN", constraint: "0", description: "SelectWhileRunning", + details: "This feature indicates whether this device allows changing the selected areas, by using the " + + "SelectAreas command, while operating.", + xref: { document: "cluster", section: "1.17.4.1" } + }), + + Field({ + name: "PROG", constraint: "1", description: "ProgressReporting", + details: "The device implements the progress reporting feature" + }), + Field({ name: "MAPS", constraint: "2", description: "Maps", details: "The device has map support" }) + ), + + Attribute( + { + name: "SupportedAreas", id: 0x0, type: "list", access: "R V", conformance: "M", + constraint: "max 255", + + details: "This attribute shall contain the list of areas that can be included in the SelectedAreas " + + "attribute’s list. Each item in this list represents a unique area, as indicated by the AreaID field " + + "of AreaStruct." + + "\n" + + "Each entry in this list shall have a unique value for the AreaID field." + + "\n" + + "If the SupportedMaps attribute is not empty, each entry in this list shall have a unique value for " + + "the combination of the MapID and AreaInfo fields." + + "\n" + + "If the SupportedMaps attribute is empty, each entry in this list shall have a unique value for the " + + "AreaInfo field and shall have the MapID field set to null." + + "\n" + + "An empty value indicates that the device is currently unable to provide the list of supported areas." + + "\n" + + "NOTE" + + "\n" + + "due to the maximum size of this list and to the fact that the entries may include strings (see " + + "LocationName), care must be taken by implementers to avoid creating a data structure that is overly " + + "large, which can result in significant latency in accessing this attribute." + + "\n" + + "The value of this attribute may change at any time via an out-of-band interaction outside of the " + + "server, such as interactions with a user interface, or due to internal device changes." + + "\n" + + "When removing entries in the SupportedAreas attribute list the server shall adjust the values of " + + "the SelectedAreas, CurrentArea, and Progress attributes such that they only reference valid entries " + + "in the updated SupportedAreas attribute list. These changes to the SelectedAreas, CurrentArea, and " + + "Progress attributes may result in the server setting some or all of them to empty (for " + + "SelectedAreas and Progress) or null (for CurrentArea), or updating them with data that matches the " + + "constraints from the description of the respective attributes. These actions are required to ensure " + + "having a consistent representation of the maps and locations available to the clients." + + "\n" + + "The SupportedAreas attribute list changes mentioned above SHOULD NOT be allowed while the device is " + + "operating, to reduce the impact on the clients, and the potential confusion for the users." + + "\n" + + "A few examples are provided below. Valid list of areas:" + + "\n" + + " • AreaID=0, LocationName=\"yellow bedroom\", MapID=null" + + "\n" + + " • AreaID=1, LocationName=\"orange bedroom\", MapID=null Valid list of areas:" + + "\n" + + " • AreaID=5, LocationName=\"hallway\", MapID=1" + + "\n" + + " • AreaID=3, LocationName=\"hallway\", MapID=2", + + xref: { document: "cluster", section: "1.17.6.1" } + }, + + Field({ name: "entry", type: "AreaStruct" }) + ), + + Attribute( + { + name: "SupportedMaps", id: 0x1, type: "list", access: "R V", conformance: "MAPS", + constraint: "max 255", + + details: "This attribute shall contain the list of supported maps." + + "\n" + + "A map is a full or a partial representation of a home, known to the device. For example:" + + "\n" + + " • a single level home may be represented using a single map" + + "\n" + + " • a two level home may be represented using two maps, one for each level" + + "\n" + + " • a single level home may be represented using two maps, each including a different set of rooms, " + + " such as \"map of living room and kitchen\" and \"map of bedrooms and hallway\"" + + "\n" + + " • a single level home may be represented using one map for the indoor areas (living room, " + + " bedrooms etc.) and one for the outdoor areas (garden, swimming pool etc.)" + + "\n" + + "Each map includes one or more areas - see the SupportedAreas attribute. In the context of this " + + "cluster specification, a map is effectively a group label for a set of areas, rather than a " + + "graphical representation that the clients can display to the users. The clients that present the " + + "list of available areas for user selection (see the SelectAreas command) may choose to filter the " + + "SupportedAreas list based on the associated map. For example, the clients may allow the user to " + + "indicate that the device is to operate on the first floor, and allow the user to choose only from " + + "the areas situated on that level." + + "\n" + + "If empty, that indicates that the device is currently unable to provide this information. Each " + + "entry in this list shall have a unique value for the MapID field." + + "\n" + + "Each entry in this list shall have a unique value for the Name field." + + "\n" + + "NOTE" + + "\n" + + "due to the maximum size of this list and to the fact that the entries may include strings (see the " + + "Name field of the MapStruct data type), care must be taken by implementers to avoid creating a data " + + "structure that is overly large, which can result in significant latency in accessing this attribute." + + "\n" + + "The value of this attribute may change at any time via an out-of-band interaction outside of the " + + "server, such as interactions with a user interface." + + "\n" + + "When updating the SupportedMaps attribute list by deleting entries, or by setting the attribute to " + + "an empty list, the SupportedLocations attribute shall be updated such that all entries in that list " + + "meet the constraints indicated in the description of the SupportedLocations attribute. This may " + + "result in" + + "\n" + + "the server removing entries from the SupportedAreas attribute list. See the SupportedAreas " + + "attribute description for the implications of changing that attribute." + + "\n" + + "The SupportedMaps attribute list changes mentioned above SHOULD NOT be allowed while the device is " + + "operating, to reduce the impact on the clients, and the potential confusion for the users.", + + xref: { document: "cluster", section: "1.17.6.2" } + }, + + Field({ name: "entry", type: "MapStruct" }) + ), + + Attribute( + { + name: "SelectedAreas", id: 0x2, type: "list", access: "R V", conformance: "M", constraint: "desc", + default: [], + + details: "Indicates the set of areas where the device SHOULD attempt to operate." + + "\n" + + "The mobile devices may travel without operating across any areas while attempting to reach the " + + "areas indicated by the SelectedAreas attribute. For example, a robotic vacuum cleaner may drive " + + "without cleaning when traveling without operating." + + "\n" + + "If this attribute is empty, the device is not constrained to operate in any specific areas. If this " + + "attribute is not empty:" + + "\n" + + " • each item in this list shall match the AreaID field of an entry in the SupportedAreas " + + " attribute’s list" + + "\n" + + " • each entry in this list shall have a unique value", + + xref: { document: "cluster", section: "1.17.6.3" } + }, + + Field({ name: "entry", type: "uint32" }) + ), + + Attribute({ + name: "CurrentArea", id: 0x3, type: "uint32", access: "R V", conformance: "desc", + constraint: "desc", default: null, quality: "X", + + details: "If the device is mobile, this attribute shall indicate the area where the device is currently " + + "located, regardless of whether it is operating or not, such as while traveling between areas." + + "\n" + + "If the device is not mobile and can operate at multiple areas sequentially, this attribute shall " + + "indicate the area which is currently being serviced, or the area which is currently traversed by " + + "the device. For example, a camera device may use this attribute to indicate which area it currently " + + "takes video of (serviced area) or which area it currently has in view but not taking video of (e.g. " + + "an area which is traversed while panning)." + + "\n" + + "NOTE" + + "\n" + + "A device may traverse an area regardless of the status of the area (pending, skipped, or completed)." + + "\n" + + "If a device can simultaneously operate at multiple areas, such as in the case of a sensor that can " + + "monitor multiple areas at the same time, the CurrentArea attribute shall NOT be implemented, since " + + "it doesn’t apply. Else this attribute shall be optionally implemented." + + "\n" + + "A null value indicates that the device is currently unable to provide this information. For " + + "example, the device is traversing an unknown area, or the SupportedAreas attribute was updated and " + + "the area where the device is located was removed from that list." + + "\n" + + "If not null, the value of this attribute shall match the AreaID field of an entry on the " + + "SupportedAreas attribute’s list.", + + xref: { document: "cluster", section: "1.17.6.4" } + }), + + Attribute({ + name: "EstimatedEndTime", id: 0x4, type: "epoch-s", access: "R V", conformance: "[CurrentArea]", + default: null, quality: "X Q", + + details: "Indicates the estimated Epoch time for completing operating at the area indicated by the " + + "CurrentArea attribute, in seconds." + + "\n" + + "A value of 0 means that the operation has completed." + + "\n" + + "When this attribute is null, that represents that there is no time currently defined until " + + "operation completion. This may happen, for example, because no operation is in progress or because " + + "the completion time is unknown." + + "\n" + + "Null if the CurrentArea attribute is null." + + "\n" + + "If the Progress attribute is available, and it contains an entry matching CurrentArea, the server " + + "may use the time estimate provided in the InitialTimeEstimate field of that entry to compute the " + + "EstimatedEndTime attribute." + + "\n" + + "The value of this attribute shall only be reported in the following cases:" + + "\n" + + " • when it changes to or from 0" + + "\n" + + " • when it decreases" + + "\n" + + " • when it changes to or from null" + + "\n" + + "NOTE" + + "\n" + + "If the device is capable of pausing its operation, this attribute may be set to null, to indicate " + + "that completion time is unknown, or increment the value while being in the paused state.", + + xref: { document: "cluster", section: "1.17.6.5" } + }), + + Attribute( + { + name: "Progress", id: 0x5, type: "list", access: "R V", conformance: "PROG", constraint: "max 255", + default: [], + + details: "Indicates the operating status at one or more areas. Each entry in this list shall have a unique " + + "value for the AreaID field." + + "\n" + + "For each entry in this list, the AreaID field shall match an entry on the SupportedAreas " + + "attribute’s list." + + "\n" + + "When this attribute is empty, that represents that no progress information is currently available." + + "\n" + + "If the SelectedAreas attribute is empty, indicating the device is not constrained to operate in any " + + "specific areas, the Progress attribute list may change while the device operates, due to the device " + + "adding new entries dynamically, when it determines which ones it can attempt to operate at." + + "\n" + + "If the SelectedAreas attribute is not empty, and the device starts operating:" + + "\n" + + " • the Progress attribute list shall be updated so each entry of SelectedAreas has a matching " + + " Progress list entry, based on the AreaID field" + + "\n" + + " • the length of the Progress and SelectedAreas list shall be the same" + + "\n" + + " • the entries in the Progress list shall be initialized by the server, by having their status set " + + " to Pending or Operating, and the TotalOperationalTime field set to null" + + "\n" + + "When the device ends operation unexpectedly, such as due to an error, the server shall update all " + + "Progress list entries with the Status field set to Operating or Pending to Skipped." + + "\n" + + "When the device finishes operating, successfully or not, it shall NOT change the Progress " + + "attribute, except in the case of an unexpected end of operation as described above, or due to " + + "changes to the SupportedMaps or SupportedAreas attributes, so the clients can retrieve the progress " + + "information at that time." + + "\n" + + "NOTE" + + "\n" + + "if the device implements the Operational Status cluster, or a derivation of it, in case the device " + + "fails to service any locations in the SelectedAreas list before ending the operation, it SHOULD use " + + "the Operational Status cluster to indicate that the device was unable to complete the operation " + + "(see the UnableToCompleteOperation error from that cluster specification). The clients SHOULD then " + + "read the Progress attribute, and indicate which areas have been successfully serviced (marked as " + + "completed).", + + xref: { document: "cluster", section: "1.17.6.6" } + }, + + Field({ name: "entry", type: "ProgressStruct" }) + ), + + Command( + { + name: "SelectAreas", id: 0x0, access: "O", conformance: "M", direction: "request", + response: "SelectAreasResponse", + details: "This command is used to select a set of device areas, where the device is to operate." + + "\n" + + "On receipt of this command the device shall respond with a SelectAreasResponse command.", + xref: { document: "cluster", section: "1.17.7.1" } + }, + + Field( + { + name: "NewAreas", id: 0x0, type: "list", conformance: "M", constraint: "desc", + + details: "This field indicates which areas the device is to operate at." + + "\n" + + "If this field is empty, that indicates that the device is to operate without being constrained to " + + "any specific areas, and the operation will not allow skipping using the SkipArea Command, otherwise " + + "the field shall be a list of unique values that match the AreaID field of entries on the " + + "SupportedAreas list.", + + xref: { document: "cluster", section: "1.17.7.1.1" } + }, + + Field({ name: "entry", type: "uint32" }) + ) + ), + + Command( + { + name: "SelectAreasResponse", id: 0x1, access: "O", conformance: "M", direction: "response", + details: "This command is sent by the device on receipt of the SelectAreas command.", + xref: { document: "cluster", section: "1.17.7.2" } + }, + + Field({ + name: "Status", id: 0x0, type: "SelectAreasStatus", conformance: "M", + + details: "If the Status field is set to Success or UnsupportedArea, the server may use a non-empty string for " + + "the StatusText field to provide additional information. For example, if Status is set to Unsupport" + + "\n" + + "edArea, the server may use StatusText to indicate which areas are unsupported." + + "\n" + + "If the Status field is not set to Success, or UnsupportedArea, the StatusText field shall include a " + + "vendor-defined error description which can be used to explain the error to the user. For example, " + + "if the Status field is set to InvalidInMode, the StatusText field SHOULD indicate why the request " + + "is not allowed, given the current mode of the device, which may involve other clusters.", + + xref: { document: "cluster", section: "1.17.7.2.1" } + }), + + Field({ name: "StatusText", id: 0x1, type: "string", conformance: "M", constraint: "max 256" }) + ), + + Command( + { + name: "SkipArea", id: 0x2, access: "O", conformance: "desc", direction: "request", + response: "SkipAreaResponse", + + details: "This command is used to skip the given area, and to attempt operating at other areas on the " + + "SupportedAreas attribute list." + + "\n" + + "This command shall NOT be implemented if the CurrentArea attribute and the Progress attribute are " + + "both not implemented. Else, this command shall be optionally implemented." + + "\n" + + "On receipt of this command the device shall respond with a SkipAreaResponse command.", + + xref: { document: "cluster", section: "1.17.7.3" } + }, + + Field({ + name: "SkippedArea", id: 0x0, type: "uint32", conformance: "M", constraint: "desc", + details: "The SkippedArea field indicates the area to be skipped." + + "\n" + + "The SkippedArea field shall match an entry in the SupportedAreas list.", + xref: { document: "cluster", section: "1.17.7.3.1" } + }) + ), + + Command( + { + name: "SkipAreaResponse", id: 0x3, access: "O", conformance: "SkipArea", direction: "response", + details: "This command is sent by the device on receipt of the SkipArea command.", + xref: { document: "cluster", section: "1.17.7.4" } + }, + + Field({ + name: "Status", id: 0x0, type: "SkipAreaStatus", conformance: "M", + + details: "If the Status field is set to Success or InvalidAreaList, the server may use a non-empty string for " + + "the StatusText field to provide additional information. For example, if Status is set to " + + "InvalidAreaList, the server may use StatusText to indicate why this list is invalid." + + "\n" + + "If the Status field is not set to Success or InvalidAreaList, the StatusText field shall include a " + + "vendor defined error description which can be used to explain the error to the user. For example, " + + "if the Status field is set to InvalidInMode, the StatusText field SHOULD indicate why the request " + + "is not allowed, given the current mode of the device, which may involve other clusters.", + + xref: { document: "cluster", section: "1.17.7.4.1" } + }), + + Field({ name: "StatusText", id: 0x1, type: "string", conformance: "M", constraint: "max 256" }) + ), + + Datatype( + { + name: "LandmarkInfoStruct", type: "struct", + details: "The data from this structure indicates a landmark and position relative to the landmark.", + xref: { document: "cluster", section: "1.17.5.1" } + }, + + Field({ + name: "LandmarkTag", id: 0x0, type: "tag", conformance: "M", + details: "This field shall indicate that the area is associated with a landmark." + + "\n" + + "This field shall be the ID of a landmark semantic tag, located within the Common Landmark " + + "Namespace. For example, this tag may indicate that the area refers to an area next to a table.", + xref: { document: "cluster", section: "1.17.5.1.1" } + }), + + Field({ + name: "RelativePositionTag", id: 0x1, type: "tag", conformance: "M", quality: "X", + + details: "This field shall identify the position of the area relative to a landmark. This is a static " + + "description of a zone known to the server, and this field never reflects the device’s own proximity " + + "or position relative to the landmark, but that of the zone." + + "\n" + + "This field shall be the ID of a relative position semantic tag, located within the Common Relative " + + "Position Namespace." + + "\n" + + "If the RelativePositionTag field is null, this field indicates proximity to the landmark. " + + "Otherwise, the RelativePositionTag field indicates the position of the area relative to the " + + "landmark indicated by the LandmarkTag field. For example, this tag, in conjunction with the " + + "LandmarkTag field, may indicate that the area refers to a zone under a table.", + + xref: { document: "cluster", section: "1.17.5.1.2" } + }) + ), + + Datatype( + { + name: "AreaInfoStruct", type: "struct", + + details: "The data from this structure indicates the name and/or semantic data describing an area, as " + + "detailed below." + + "\n" + + "This data type includes the LocationInfo field, with the following fields: LocationName, " + + "FloorNumber, AreaType. Additional semantic data may be available in the LandmarkInfo field." + + "\n" + + "For an area description to be meaningful, it shall have at least one of the following:" + + "\n" + + " • a non-empty name (LocationInfo’s LocationName field) OR" + + "\n" + + " • some semantic data (one or more of these: FloorNumber, AreaType or LandmarkTag) The normative " + + " text from the remainder of this section describes these constraints." + + "\n" + + "If the LocationInfo field is null, the LandmarkInfo field shall NOT be null. If the LandmarkInfo " + + "field is null, the LocationInfo field shall NOT be null." + + "\n" + + "If LocationInfo is not null, and its LocationName field is an empty string, at least one of the " + + "following shall NOT be null:" + + "\n" + + " • LocationInfo’s FloorNumber field" + + "\n" + + " • LocationInfo’s AreaType field" + + "\n" + + " • LandmarkInfo field" + + "\n" + + "If all three of the following are null, LocationInfo’s LocationName field shall NOT be an empty " + + "string:" + + "\n" + + " • LocationInfo’s FloorNumber field" + + "\n" + + " • LocationInfo’s AreaType field" + + "\n" + + " • LandmarkInfo field", + + xref: { document: "cluster", section: "1.17.5.2" } + }, + + Field({ + name: "LocationInfo", id: 0x0, type: "locationdesc", conformance: "M", quality: "X", + + details: "This field shall indicate the name of the area, floor number and/or area type. A few examples are " + + "provided below." + + "\n" + + " • An area can have LocationInfo’s LocationName field set to \"blue room\", and the AreaType field " + + " set to the ID of a \"Living Room\" semantic tag. Clients wishing to direct the device to operate " + + " in (or service) the living room can use this area." + + "\n" + + " • An area can have LocationInfo set to null, the LandmarkInfo’s LandmarkTag field set to the ID " + + " of the \"Table\" landmark semantic tag, and the RelativePositionTag field set to the ID of the " + + " \"Under\" position semantic tag. With such an area indication, the client can request the device " + + " to operate in (or service) the area located under the table.", + + xref: { document: "cluster", section: "1.17.5.2.1" } + }), + + Field({ + name: "LandmarkInfo", id: 0x1, type: "LandmarkInfoStruct", conformance: "M", quality: "X", + + details: "This field shall indicate an association with a landmark. A value of null indicates that the " + + "information is not available or known. For example, this may indicate that the area refers to a " + + "zone next to a table." + + "\n" + + "If this field is not null, that indicates that the area is restricted to the zone where the " + + "landmark is located, as indicated by the LandmarkTag and, if not null, by the RelativePositionTag " + + "fields, rather than to the entire room or floor where the landmark is located, if those are " + + "indicated by the LocationInfo field.", + + xref: { document: "cluster", section: "1.17.5.2.2" } + }) + ), + + Datatype( + { + name: "MapStruct", type: "struct", + details: "This is a struct representing a map.", + xref: { document: "cluster", section: "1.17.5.3" } + }, + Field({ + name: "MapId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall represent the map’s identifier.", + xref: { document: "cluster", section: "1.17.5.3.1" } + }), + + Field({ + name: "Name", id: 0x1, type: "string", conformance: "M", constraint: "max 64", + details: "This field shall represent a human understandable map description. For example: \"Main Floor\", or " + + "\"Second Level\".", + xref: { document: "cluster", section: "1.17.5.3.2" } + }) + ), + + Datatype( + { + name: "AreaStruct", type: "struct", + details: "This is a struct representing an area known to the server.", + xref: { document: "cluster", section: "1.17.5.4" } + }, + Field({ + name: "AreaId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall represent the identifier of the area.", + xref: { document: "cluster", section: "1.17.5.4.1" } + }), + + Field({ + name: "MapId", id: 0x1, type: "uint32", conformance: "M", constraint: "desc", quality: "X", + + details: "This field shall indicate the map identifier which the area is associated with. A value of null " + + "indicates that the area is not associated with a map." + + "\n" + + "If the SupportedMaps attribute is not empty, this field shall match the MapID field of an entry " + + "from the SupportedMaps attribute’s list. If the SupportedMaps attribute is empty, this field shall " + + "be null.", + + xref: { document: "cluster", section: "1.17.5.4.2" } + }), + + Field({ + name: "AreaInfo", id: 0x2, type: "AreaInfoStruct", conformance: "M", + + details: "This field shall contain data describing the area." + + "\n" + + "This SHOULD be used by clients to determine the name and/or the full, or the partial, semantics of " + + "a certain area." + + "\n" + + "NOTE" + + "\n" + + "If any entries on the SupportedAreas attribute’s list have the AreaInfo field missing the semantic " + + "data, the client may remind the user to assign the respective data.", + + xref: { document: "cluster", section: "1.17.5.4.3" } + }) + ), + + Datatype( + { + name: "ProgressStruct", type: "struct", + details: "This is a struct indicating the progress.", + xref: { document: "cluster", section: "1.17.5.5" } + }, + + Field({ + name: "AreaId", id: 0x0, type: "uint32", conformance: "M", + details: "This field shall indicate the identifier of the area, and the identifier shall be an entry in the " + + "SupportedAreas attribute’s list.", + xref: { document: "cluster", section: "1.17.5.5.1" } + }), + + Field({ + name: "Status", id: 0x1, type: "OperationalStatusEnum", conformance: "M", + details: "This field shall indicate the operational status of the device regarding the area indicated by the " + + "AreaID field.", + xref: { document: "cluster", section: "1.17.5.5.2" } + }), + + Field({ + name: "TotalOperationalTime", id: 0x2, type: "elapsed-s", conformance: "O", quality: "X", + + details: "This field shall indicate the total operational time, in seconds, from when the device started to " + + "operate at the area indicated by the AreaID field, until the operation finished, due to completion " + + "or due to skipping, including any time spent while paused." + + "\n" + + "A value of null indicates that the total operational time is unknown." + + "\n" + + "There may be cases where the total operational time exceeds the maximum value that can be conveyed " + + "by this attribute, and in such instances this attribute shall be populated with null." + + "\n" + + "Null if the Status field is not set to Completed or Skipped.", + + xref: { document: "cluster", section: "1.17.5.5.3" } + }), + + Field({ + name: "InitialTimeEstimate", id: 0x3, type: "elapsed-s", conformance: "O", quality: "X", + + details: "This field shall indicate the estimated time for the operation, in seconds, from when the device " + + "will start operating at the area indicated by the AreaID field, until the operation completes, " + + "excluding any time spent while not operating in the area." + + "\n" + + "A value of null indicates that the estimated time is unknown. If the estimated time is unknown, or " + + "if it exceeds the maximum value that can be conveyed by this attribute, this attribute shall be " + + "null." + + "\n" + + "After initializing the ProgressStruct instance, the server SHOULD NOT change the value of this " + + "field, except when repopulating the entire instance, to avoid excessive reporting of the Progress " + + "attribute changes.", + + xref: { document: "cluster", section: "1.17.5.5.4" } + }) + ), + + Datatype( + { + name: "OperationalStatusEnum", type: "enum8", + details: "The following table defines the status values.", + xref: { document: "cluster", section: "1.17.5.6" } + }, + Field({ + name: "Pending", id: 0x0, conformance: "M", + description: "The device has not yet started operating at the given area, or has not finished operating at that area but it is not currently operating at the area" + }), + Field({ + name: "Operating", id: 0x1, conformance: "M", + description: "The device is currently operating at the given area" + }), + Field({ + name: "Skipped", id: 0x2, conformance: "M", + description: "The device has skipped the given area, before or during operating at it, due to a SkipArea command, due an out of band command (e.g. from the vendor’s application), due to a vendor specific reason, such as a time limit used by the device, or due the device ending operating unsuccessfully" + }), + Field({ + name: "Completed", id: 0x3, conformance: "M", + description: "The device has completed operating at the given area" + }) + ), + + Datatype( + { name: "SelectAreasStatus", type: "enum8", xref: { document: "cluster", section: "1.17.5.6.1" } }, + Field({ + name: "Success", id: 0x0, conformance: "M", + description: "Attempting to operate in the areas identified by the entries of the NewAreas field is allowed and possible. The SelectedAreas attribute is set to the value of the NewAreas field." + }), + Field({ + name: "UnsupportedArea", id: 0x1, conformance: "M", + description: "The value of at least one of the entries of the NewAreas field doesn’t match any entries in the SupportedAreas attribute." + }), + Field({ + name: "InvalidInMode", id: 0x2, conformance: "M", + description: "The received request cannot be handled due to the current mode of the device." + }), + Field({ + name: "InvalidSet", id: 0x3, conformance: "M", + description: "The set of values is invalid. For example, areas on different floors, that a robot knows it can’t reach on its own." + }) + ), + + Datatype( + { name: "SkipAreaStatus", type: "enum8", xref: { document: "cluster", section: "1.17.5.6.2" } }, + Field({ + name: "Success", id: 0x0, conformance: "M", + description: "Skipping the area is allowed and possible, or the device was operating at the last available area and has stopped." + }), + Field({ name: "InvalidAreaList", id: 0x1, conformance: "M", description: "The SelectedAreas attribute is empty." }), + Field({ + name: "InvalidInMode", id: 0x2, conformance: "M", + description: "The received request cannot be handled due to the current mode of the device. For example, the CurrentArea attribute is null or the device is not operating." + }), + Field({ + name: "InvalidSkippedArea", id: 0x3, conformance: "M", + description: "The SkippedArea field doesn’t match an entry in the SupportedAreas list." + }) + ) +); + +MatterDefinition.children.push(ServiceArea); diff --git a/packages/model/src/standard/elements/SmokeCoAlarm.ts b/packages/model/src/standard/elements/SmokeCoAlarm.ts index 975a578dea..ab541eb31f 100644 --- a/packages/model/src/standard/elements/SmokeCoAlarm.ts +++ b/packages/model/src/standard/elements/SmokeCoAlarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -260,9 +260,8 @@ export const SmokeCoAlarm = Cluster( details: "This command shall initiate a device self-test. The return status shall indicate whether the test " + "was successfully initiated. Only one SelfTestRequest may be processed at a time. When the value of " + - "the ExpressedState attribute is any of SmokeAlarm, COAlarm, Testing, InterconnectSmoke, Inter" + - "\n" + - "connectCO, the device shall NOT execute the self-test, and shall return status code BUSY." + + "the ExpressedState attribute is any of SmokeAlarm, COAlarm, Testing, InterconnectSmoke, " + + "InterconnectCO, the device shall NOT execute the self-test, and shall return status code BUSY." + "\n" + "Upon successful acceptance of SelfTestRequest, the TestInProgress attribute shall be set to True " + "and ExpressedState attribute shall be set to Testing. Any faults identified during the test shall " + @@ -304,12 +303,12 @@ export const SmokeCoAlarm = Cluster( ), Datatype( - { name: "ExpressedStateEnum", type: "enum8", xref: { document: "cluster", section: "2.11.5.3" } }, - Field({ - name: "Normal", id: 0x0, conformance: "M", description: "Nominal state, the device is not alarming", + { + name: "ExpressedStateEnum", type: "enum8", details: "This value shall indicate that this alarm is not alarming.", - xref: { document: "cluster", section: "2.11.5.3.1" } - }), + xref: { document: "cluster", section: "2.11.5.3" } + }, + Field({ name: "Normal", id: 0x0, conformance: "M", description: "Nominal state, the device is not alarming" }), Field({ name: "SmokeAlarm", id: 0x1, conformance: "SMOKE", description: "Smoke Alarm state", @@ -410,15 +409,14 @@ export const SmokeCoAlarm = Cluster( ), Datatype( - { name: "ContaminationStateEnum", type: "enum8", xref: { document: "cluster", section: "2.11.5.6" } }, - - Field({ - name: "Normal", id: 0x0, conformance: "M", - description: "Nominal state, the sensor is not contaminated", + { + name: "ContaminationStateEnum", type: "enum8", details: "This value shall indicate that the smoke sensor has nominal contamination levels, no customer " + "action is required.", - xref: { document: "cluster", section: "2.11.5.6.1" } - }), + xref: { document: "cluster", section: "2.11.5.6" } + }, + + Field({ name: "Normal", id: 0x0, conformance: "M", description: "Nominal state, the sensor is not contaminated" }), Field({ name: "Low", id: 0x1, conformance: "O", description: "Low contamination", diff --git a/packages/model/src/standard/elements/SmokeCoAlarmDT.ts b/packages/model/src/standard/elements/SmokeCoAlarmDT.ts index 9e68279a35..875b0d6be6 100644 --- a/packages/model/src/standard/elements/SmokeCoAlarmDT.ts +++ b/packages/model/src/standard/elements/SmokeCoAlarmDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/SoftwareDiagnostics.ts b/packages/model/src/standard/elements/SoftwareDiagnostics.ts index 012a811373..ea2936e68b 100644 --- a/packages/model/src/standard/elements/SoftwareDiagnostics.ts +++ b/packages/model/src/standard/elements/SoftwareDiagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/SoftwareVersionCertificationStatusEnum.ts b/packages/model/src/standard/elements/SoftwareVersionCertificationStatusEnum.ts index 79dc74d1a0..17c499ce9d 100644 --- a/packages/model/src/standard/elements/SoftwareVersionCertificationStatusEnum.ts +++ b/packages/model/src/standard/elements/SoftwareVersionCertificationStatusEnum.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ export const SoftwareVersionCertificationStatusEnum = Datatype( name: "SoftwareVersionCertificationStatusEnum", type: "enum8", details: "The values 0 through 2 shall correspond to the values 0 through 2 used in certification_type in the " + "Certification Declaration.", - xref: { document: "core", section: "11.23.7.2" } + xref: { document: "core", section: "11.23.8.2" } }, Field({ diff --git a/packages/model/src/standard/elements/SolarPowerDT.ts b/packages/model/src/standard/elements/SolarPowerDT.ts new file mode 100644 index 0000000000..5528481e1d --- /dev/null +++ b/packages/model/src/standard/elements/SolarPowerDT.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const SolarPowerDt = DeviceType( + { + name: "SolarPower", id: 0x17, category: "Energy", classification: "simple", + details: "A Solar Power device is a device that allows a solar panel array, which can optionally be comprised " + + "of a set parallel strings of solar panels, and its associated controller and, if appropriate, " + + "inverter, to be monitored and controlled by an Energy Management System.", + xref: { document: "device", section: "14.3" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 23, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.3.6" } + }) +); + +MatterDefinition.children.push(SolarPowerDt); diff --git a/packages/model/src/standard/elements/SpeakerDT.ts b/packages/model/src/standard/elements/SpeakerDT.ts index eb293c694f..69fb8f393d 100644 --- a/packages/model/src/standard/elements/SpeakerDT.ts +++ b/packages/model/src/standard/elements/SpeakerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/Switch.ts b/packages/model/src/standard/elements/Switch.ts index 1532c2168f..d08662c5b8 100644 --- a/packages/model/src/standard/elements/Switch.ts +++ b/packages/model/src/standard/elements/Switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -34,43 +34,50 @@ export const Switch = Cluster( xref: { document: "cluster", section: "1.13" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "1.13.4" } }, Field({ name: "LS", conformance: "O.a", constraint: "0", description: "LatchingSwitch", - details: "This feature is for a switch that maintains its position after being pressed (or turned).", + details: "This feature flag is for a switch that maintains its position after being pressed (or turned).", xref: { document: "cluster", section: "1.13.4.1" } }), Field({ name: "MS", conformance: "O.a", constraint: "1", description: "MomentarySwitch", - details: "This feature is for a switch that does not maintain its position after being pressed (or turned). " + - "After releasing, it goes back to its idle position.", + details: "This feature flag is for a switch that does not maintain its position after being pressed (or " + + "turned). After releasing, it goes back to its idle position.", xref: { document: "cluster", section: "1.13.4.2" } }), Field({ - name: "MSR", conformance: "[MS]", constraint: "2", description: "MomentarySwitchRelease", - details: "This feature is for a momentary switch that can distinguish and report release events. When this " + - "feature flag MSR is present, MS shall be present as well.", + name: "MSR", conformance: "[MS & !AS]", constraint: "2", description: "MomentarySwitchRelease", + details: "This feature flag is for a momentary switch that can distinguish and report release events.", xref: { document: "cluster", section: "1.13.4.3" } }), Field({ - name: "MSL", conformance: "[MS & MSR]", constraint: "3", description: "MomentarySwitchLongPress", - details: "This feature is for a momentary switch that can distinguish and report long presses from short " + - "presses. When this feature flag MSL is present, MS and MSR shall be present as well.", + name: "MSL", conformance: "[MS & (MSR | AS)]", constraint: "3", + description: "MomentarySwitchLongPress", + details: "This feature flag is for a momentary switch that can distinguish and report long presses from short " + + "presses.", xref: { document: "cluster", section: "1.13.4.4" } }), Field({ - name: "MSM", conformance: "[MS & MSR]", constraint: "4", description: "MomentarySwitchMultiPress", - details: "This feature is for a momentary switch that can distinguish and report double press and potentially " + - "multiple presses with more events, such as triple press, etc. When this feature flag MSM is " + - "present, MS and MSR shall be present as well.", + name: "MSM", conformance: "AS, [MS & MSR]", constraint: "4", + description: "MomentarySwitchMultiPress", + details: "This feature flag is for a momentary switch that can distinguish and report double press and " + + "potentially multiple presses with more events, such as triple press, etc.", xref: { document: "cluster", section: "1.13.4.5" } + }), + + Field({ + name: "AS", conformance: "[MS]", constraint: "5", description: "ActionSwitch", + details: "This feature flag indicates simplified handling of events for multi-press-capable switches. See " + + "Multi Press Details.", + xref: { document: "cluster", section: "1.13.4.6" } }) ), @@ -84,8 +91,9 @@ export const Switch = Cluster( Attribute({ name: "CurrentPosition", id: 0x1, type: "uint8", access: "R V", conformance: "M", - constraint: "max numberOfPositions1", default: 0, quality: "N", - details: "Indicates the position of the switch. The valid range is zero to NumberOfPositions-1. " + + constraint: "max numberOfPositions - 1", default: 0, quality: "N", + details: "Indicates the position of the switch. The valid range is zero to NumberOfPositions - 1." + + "\n" + "CurrentPosition value 0 shall be assigned to the default position of the switch: for example the " + "\"open\" state of a rocker switch, or the \"idle\" state of a push button switch.", xref: { document: "cluster", section: "1.13.5.2" } @@ -94,9 +102,30 @@ export const Switch = Cluster( Attribute({ name: "MultiPressMax", id: 0x2, type: "uint8", access: "R V", conformance: "MSM", constraint: "min 2", default: 2, quality: "F", + details: "Indicates how many consecutive presses can be detected and reported by a momentary switch which " + - "supports multi-press (e.g. it will report the value 3 if it can detect single press, double press " + - "and triple press, but not quad press and beyond).", + "supports multi-press (MSM feature flag set)." + + "\n" + + "For example, a momentary switch supporting single press, double press and triple press, but not " + + "quad press and beyond, would return the value 3." + + "\n" + + "When more than MultiPressMax presses are detected within a multi-press sequence:" + + "\n" + + " • The server for cluster revision < 2 SHOULD generate a MultiPressComplete event with the " + + " TotalNumberOfPressesCounted field set to the value of the MultiPressMax attribute, and avoid " + + " generating any further InitialPress and MultiPressOngoing events until the switch has become " + + " fully idle (i.e. no longer in the process of counting presses within the multipress)." + + "\n" + + " • The server for cluster revision >= 2 shall generate a MultiPressComplete event with the " + + " TotalNumberOfPressesCounted field set to zero (indicating an aborted sequence), and shall NOT " + + " generate any further InitialPress and MultiPressOngoing events until the switch has become " + + " fully idle (i.e. no longer in the process of counting presses within the multipress)." + + "\n" + + "This approach avoids unintentionally causing intermediate actions where there is a very long " + + "sequence of presses beyond MultiPressMax that may be taken in account specially by switches (e.g. " + + "to trigger special behavior such as factory reset for which generating events towards the client is " + + "not appropriate).", + xref: { document: "cluster", section: "1.13.5.3" } }), @@ -110,7 +139,7 @@ export const Switch = Cluster( Field({ name: "NewPosition", id: 0x0, type: "uint8", conformance: "M", - constraint: "0 to numberOfPositions1", + constraint: "0 to numberOfPositions - 1", details: "This field shall indicate the new value of the CurrentPosition attribute, i.e. after the move.", xref: { document: "cluster", section: "1.13.6.1.1" } }) @@ -125,7 +154,7 @@ export const Switch = Cluster( Field({ name: "NewPosition", id: 0x0, type: "uint8", conformance: "M", - constraint: "0 to numberOfPositions1", + constraint: "0 to numberOfPositions - 1", details: "This field shall indicate the new value of the CurrentPosition attribute, i.e. while pressed.", xref: { document: "cluster", section: "1.13.6.2.1" } }) @@ -134,14 +163,46 @@ export const Switch = Cluster( Event( { name: "LongPress", id: 0x2, access: "V", conformance: "MSL", priority: "info", - details: "This event shall be generated, when the momentary switch has been pressed for a \"long\" time (this " + - "time interval is manufacturer determined (e.g. since it depends on the switch physics)).", + + details: "This event shall be generated when the momentary switch has been pressed for a \"long\" time. The " + + "time interval constituting a \"long\" time is manufacturer-determined, since it depends on the switch " + + "physics." + + "\n" + + " • When the AS feature flag is set, this event:" + + "\n" + + " ◦ shall NOT be generated during a multi-press sequence (since a long press is a separate cycle " + + " from any multi-press cycles);" + + "\n" + + " ◦ shall only be generated after the first InitialPress following a MultiPressComplete when a " + + " long press is detected after the idle time." + + "\n" + + " • Else, when the MSM feature flag is set, this event:" + + "\n" + + " ◦ shall NOT be generated during a multi-press sequence (since a long press is a separate cycle " + + " from any multi-press cycles);" + + "\n" + + " ◦ shall only be generated after the first InitialPress following a MultiPressComplete when a " + + " long press is detected after the idle time;" + + "\n" + + " ◦ shall NOT be generated after a MultiPressOngoing event without an intervening " + + " MultiPressComplete event." + + "\n" + + "The above constraints imply that for a given activity detection cycle of a switch having MSM and/or " + + "MSL feature flags set, the entire activity is either a single long press detection cycle of " + + "(InitialPress, LongPress, LongRelease), or a single multi-press detection cycle (ending in " + + "MultiPressComplete), where presses that would otherwise be reported as long presses are instead " + + "reported as a counted press in the MultiPressComplete event, and as InitialPress/ShortRelease pairs " + + "otherwise (where applicable)." + + "\n" + + "The rationale for this constraint is the ambiguity of interpretation of events when mixing long " + + "presses and multi-press events.", + xref: { document: "cluster", section: "1.13.6.3" } }, Field({ name: "NewPosition", id: 0x0, type: "uint8", conformance: "M", - constraint: "0 to numberOfPositions1", + constraint: "0 to numberOfPositions - 1", details: "This field shall indicate the new value of the CurrentPosition attribute, i.e. while pressed.", xref: { document: "cluster", section: "1.13.6.3.1" } }) @@ -151,14 +212,20 @@ export const Switch = Cluster( { name: "ShortRelease", id: 0x3, access: "V", conformance: "MSR", priority: "info", - details: "This event shall be generated, when the momentary switch has been released (after debouncing)." + + details: "If the server has the Action Switch (AS) feature flag set, this event shall NOT be generated at " + + "all, since setting the Action Switch feature flag forbids the Momentary Switch ShortRelease (MSR) " + + "feature flag from being set. Otherwise, the following paragraphs describe the situations where this " + + "event is generated." + + "\n" + + "This event shall be generated, when the momentary switch has been released (after debouncing)." + "\n" + - " • If the server supports the Momentary Switch LongPress (MSL) feature, this event shall be " + - " generated when the switch is released if no LongPress event had been generated since the " + + " • If the server has the Momentary Switch LongPress (MSL) feature flag set, then this event shall " + + " be generated when the switch is released if no LongPress event had been generated since the " + " previous InitialPress event." + "\n" + - " • If the server does not support the Momentary Switch LongPress (MSL) feature, this event shall " + - " be generated when the switch is released - even when the switch was pressed for a long time." + + " • If the server does not have the Momentary Switch LongPress (MSL) feature flag set, this event " + + " shall be generated when the switch is released - even when the switch was pressed for a long " + + " time." + "\n" + " • Also see Section 1.13.7, “Sequence of generated events”.", @@ -167,7 +234,7 @@ export const Switch = Cluster( Field({ name: "PreviousPosition", id: 0x0, type: "uint8", conformance: "M", - constraint: "0 to numberOfPositions1", + constraint: "0 to numberOfPositions - 1", details: "This field shall indicate the previous value of the CurrentPosition attribute, i.e. just prior to " + "release.", xref: { document: "cluster", section: "1.13.6.4.1" } @@ -186,7 +253,7 @@ export const Switch = Cluster( Field({ name: "PreviousPosition", id: 0x0, type: "uint8", conformance: "M", - constraint: "0 to numberOfPositions1", + constraint: "0 to numberOfPositions - 1", details: "This field shall indicate the previous value of the CurrentPosition attribute, i.e. just prior to " + "release.", xref: { document: "cluster", section: "1.13.6.5.1" } @@ -195,15 +262,18 @@ export const Switch = Cluster( Event( { - name: "MultiPressOngoing", id: 0x5, access: "V", conformance: "MSM", priority: "info", - details: "This event shall be generated to indicate how many times the momentary switch has been pressed in a " + + name: "MultiPressOngoing", id: 0x5, access: "V", conformance: "MSM & !AS", priority: "info", + details: "If the server has the Action Switch (AS) feature flag set, this event shall NOT be generated at " + + "all. Otherwise, the following paragraphs describe the situations where this event is generated." + + "\n" + + "This event shall be generated to indicate how many times the momentary switch has been pressed in a " + "multi-press sequence, during that sequence. See Multi Press Details below.", xref: { document: "cluster", section: "1.13.6.6" } }, Field({ name: "NewPosition", id: 0x0, type: "uint8", conformance: "M", - constraint: "0 to numberOfPositions1", + constraint: "0 to numberOfPositions - 1", details: "This field shall indicate the new value of the CurrentPosition attribute, i.e. while pressed.", xref: { document: "cluster", section: "1.13.6.6.1" } }), @@ -237,9 +307,11 @@ export const Switch = Cluster( "\n" + "The TotalNumberOfPressesCounted field shall contain:" + "\n" + - " • a value of 1 when there was one press in a multi-press sequence (and the sequence has ended)," + + " • a value of 0 when there was an aborted multi-press sequence, where the number of presses goes " + + " beyond MultiPressMax presses," + "\n" + - " i.e. there was no double press (or more)," + + " • a value of 1 when there was exactly one press in a multi-press sequence (and the sequence has " + + " ended), i.e. there was no double press (or more)," + "\n" + " • a value of 2 when there were exactly two presses in a multi-press sequence (and the sequence " + " has ended)," + @@ -248,15 +320,26 @@ export const Switch = Cluster( " has ended)," + "\n" + " • a value of N when there were exactly N presses in a multi-press sequence (and the sequence has " + - " ended).", + " ended)." + + "\n" + + "NOTE" + + "\n" + + "The introduction of TotalNumberOfPressesCounted supporting the value 0 may impact clients of " + + "switches using cluster revision 1 since such servers would not use this value of " + + "TotalNumberOfPressesCounted to indicate an aborted sequence. Clients SHOULD always act using the " + + "TotalNumberOfPressesCounted field taken into account since for values from 1 to MultiPressMax, the " + + "user action that led to the event was different depending on the count.", xref: { document: "cluster", section: "1.13.6.7" } }, - Field({ name: "PreviousPosition", id: 0x0, type: "uint8", conformance: "M", constraint: "0 to numberOfPositions1" }), + Field({ + name: "PreviousPosition", id: 0x0, type: "uint8", conformance: "M", + constraint: "0 to numberOfPositions - 1" + }), Field({ name: "TotalNumberOfPressesCounted", id: 0x1, type: "uint8", conformance: "M", - constraint: "1 to multiPressMax" + constraint: "max multiPressMax" }) ) ); diff --git a/packages/model/src/standard/elements/SwitchesNS.ts b/packages/model/src/standard/elements/SwitchesNS.ts index 594621d8de..54fa6edaf5 100644 --- a/packages/model/src/standard/elements/SwitchesNS.ts +++ b/packages/model/src/standard/elements/SwitchesNS.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -25,7 +25,7 @@ export const SwitchesNs = SemanticNamespace( "Position Namespace and the Common Number Namespace in the Generic Switch device type section in the " + "Device Library.", - xref: { document: "namespace", section: "15" } + xref: { document: "namespace", section: "18" } }, SemanticTag({ name: "On", id: 0x0 }), @@ -42,7 +42,7 @@ export const SwitchesNs = SemanticNamespace( details: "When this value is used, the Label field in the same Semantic Tag structure shall be filled with a " + "textual description of the function indicated on the button, such as a label or icon printed on the " + "button, e.g. \"dining\".", - xref: { document: "namespace", section: "15.1" } + xref: { document: "namespace", section: "18.1" } }) ); diff --git a/packages/model/src/standard/elements/TargetNavigator.ts b/packages/model/src/standard/elements/TargetNavigator.ts index 2cda7b75af..92bb72a3ea 100644 --- a/packages/model/src/standard/elements/TargetNavigator.ts +++ b/packages/model/src/standard/elements/TargetNavigator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -42,7 +42,7 @@ export const TargetNavigator = Cluster( { name: "TargetList", id: 0x0, type: "list", access: "R V", conformance: "M", details: "Indicates a list of targets that can be navigated to within the experience presented to the user by " + - "the Endpoint (Video Player or Content App). The list shall not contain any entries with the same " + + "the Endpoint (Video Player or Content App). The list shall NOT contain any entries with the same " + "Identifier in the TargetInfoStruct object.", xref: { document: "cluster", section: "6.11.5.1" } }, @@ -111,7 +111,7 @@ export const TargetNavigator = Cluster( xref: { document: "cluster", section: "6.11.6.2.1" } }), Field({ - name: "Data", id: 0x1, type: "string", conformance: "O", + name: "Data", id: 0x1, type: "string", conformance: "O", constraint: "any", details: "This field shall indicate Optional app-specific data.", xref: { document: "cluster", section: "6.11.6.2.2" } }) diff --git a/packages/model/src/standard/elements/TemperatureControl.ts b/packages/model/src/standard/elements/TemperatureControl.ts index 0a35eccb15..c581058e35 100644 --- a/packages/model/src/standard/elements/TemperatureControl.ts +++ b/packages/model/src/standard/elements/TemperatureControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -70,7 +70,7 @@ export const TemperatureControl = Cluster( Attribute({ name: "MinTemperature", id: 0x1, type: "temperature", access: "R V", conformance: "TN", - constraint: "max (MaxTemperature - 1)", quality: "F", + constraint: "max maxTemperature - 1", quality: "F", details: "Indicates the minimum temperature to which the TemperatureSetpoint attribute may be set.", xref: { document: "cluster", section: "8.2.5.2" } }), @@ -90,7 +90,7 @@ export const TemperatureControl = Cluster( Attribute({ name: "Step", id: 0x3, type: "temperature", access: "R V", conformance: "STEP", - constraint: "max (MaxTemperature - MinTemperature)", quality: "F", + constraint: "max maxTemperature - minTemperature", quality: "F", details: "Indicates the discrete value by which the TemperatureSetpoint attribute can be changed via the " + "SetTemperature command." + @@ -104,7 +104,7 @@ export const TemperatureControl = Cluster( Attribute({ name: "SelectedTemperatureLevel", id: 0x4, type: "uint8", access: "R V", conformance: "TL", - constraint: "0 to 31", + constraint: "max 31", details: "Indicates the currently selected temperature level setting of the server. This attribute shall be " + "the positional index of the list item in the SupportedTemperatureLevels list that represents the " + "currently selected temperature level setting of the server.", diff --git a/packages/model/src/standard/elements/TemperatureControlledCabinetDT.ts b/packages/model/src/standard/elements/TemperatureControlledCabinetDT.ts index 42ebbd6e2d..3a8b682941 100644 --- a/packages/model/src/standard/elements/TemperatureControlledCabinetDT.ts +++ b/packages/model/src/standard/elements/TemperatureControlledCabinetDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,7 @@ export const TemperatureControlledCabinetDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 113, revision: 2 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 113, revision: 3 } ], element: "attribute" }) ), Requirement({ name: "TemperatureControl", id: 0x56, conformance: "M", element: "serverCluster", diff --git a/packages/model/src/standard/elements/TemperatureMeasurement.ts b/packages/model/src/standard/elements/TemperatureMeasurement.ts index d47c501bb6..f6c04bef03 100644 --- a/packages/model/src/standard/elements/TemperatureMeasurement.ts +++ b/packages/model/src/standard/elements/TemperatureMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -28,7 +28,7 @@ export const TemperatureMeasurement = Cluster( Attribute({ name: "MinMeasuredValue", id: 0x1, type: "temperature", access: "R V", conformance: "M", - constraint: "-27315 to maxMeasuredValue1", default: -27315, quality: "X", + constraint: "-27315 to maxMeasuredValue - 1", default: -27315, quality: "X", details: "Indicates the minimum value of MeasuredValue that is capable of being measured. See Measured Value " + "for more details." + "\n" + @@ -38,7 +38,7 @@ export const TemperatureMeasurement = Cluster( Attribute({ name: "MaxMeasuredValue", id: 0x2, type: "temperature", access: "R V", conformance: "M", - constraint: "minMeasuredValue1 to 32767", default: 32767, quality: "X", + constraint: "minMeasuredValue + 1 to 32767", default: 32767, quality: "X", details: "This attribute indicates the maximum value of MeasuredValue that is capable of being measured. See " + "Measured Value for more details." + "\n" + @@ -47,8 +47,8 @@ export const TemperatureMeasurement = Cluster( }), Attribute({ - name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", - constraint: "0 to 2048", default: 0, + name: "Tolerance", id: 0x3, type: "uint16", access: "R V", conformance: "O", constraint: "max 2048", + default: 0, details: "See Measured Value.", xref: { document: "cluster", section: "2.3.4.4" } }) diff --git a/packages/model/src/standard/elements/TemperatureSensorDT.ts b/packages/model/src/standard/elements/TemperatureSensorDT.ts index f0b4ebbddd..c9bb1f98bf 100644 --- a/packages/model/src/standard/elements/TemperatureSensorDT.ts +++ b/packages/model/src/standard/elements/TemperatureSensorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/Thermostat.ts b/packages/model/src/standard/elements/Thermostat.ts index 4014997727..a10188d0fa 100644 --- a/packages/model/src/standard/elements/Thermostat.ts +++ b/packages/model/src/standard/elements/Thermostat.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -18,10 +18,51 @@ import { export const Thermostat = Cluster( { name: "Thermostat", id: 0x201, asOf: "1.3", classification: "application", pics: "TSTAT", - details: "This cluster provides an interface to the functionality of a thermostat.", + + details: "This cluster provides an interface to the functionality of a thermostat." + + "\n" + + "Optional temperature, humidity and occupancy sensors" + + "\n" + + "Thermostat" + + "\n" + + "Heating / cooling control panel" + + "\n" + + "C" + + "\n" + + "Dehumidification configuration" + + "\n" + + "Dehumidification notification" + + "\n" + + "ThermostatS" + + "\n" + + "Heating / cooling device (e.g. indoor air handler)" + + "\n" + + "S" + + "\n" + + "user interface S" + + "\n" + + "configuration" + + "\n" + + "C" + + "\n" + + "Configuration tool" + + "\n" + + "Thermostat configuration" + + "\n" + + "C C Fan control S" + + "\n" + + "ThermostatS notification C" + + "\n" + + "C = Client S = Server" + + "\n" + + "Note: Device names are examples for illustration purposes only" + + "\n" + + "Figure 15. Example Usage of the Thermostat and Related Clusters\"", + xref: { document: "cluster", section: "4.3" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 6 }), + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 8 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "4.3.4" } }, @@ -57,6 +98,15 @@ export const Thermostat = Cluster( "which does not offer a view into the currently measured temperature, but allows setpoints to be " + "provided.", xref: { document: "cluster", section: "4.3.4.1" } + }), + + Field({ + name: "MSCH", conformance: "O", constraint: "7", description: "MatterScheduleConfiguration", + details: "Supports enhanced schedules" + }), + Field({ + name: "PRES", conformance: "O", constraint: "8", description: "Presets", + details: "Thermostat supports setpoint presets" }) ), @@ -77,43 +127,42 @@ export const Thermostat = Cluster( " LocalTemperatureCalibration. In that case, the LocalTemperature attribute shall always report " + " null.", - xref: { document: "cluster", section: "4.3.9.3" } + xref: { document: "cluster", section: "4.3.9.2" } }), Attribute({ name: "OutdoorTemperature", id: 0x1, type: "temperature", access: "R V", conformance: "O", default: null, quality: "X", details: "Indicates the outdoor temperature, as measured locally or remotely (over the network).", - xref: { document: "cluster", section: "4.3.9.4" } + xref: { document: "cluster", section: "4.3.9.3" } }), Attribute({ - name: "Occupancy", id: 0x2, type: "OccupancyBitmap", access: "R V", conformance: "OCC", - constraint: "desc", default: 1, + name: "Occupancy", id: 0x2, type: "OccupancyBitmap", access: "R V", conformance: "OCC", default: 1, details: "Indicates whether the heated/cooled space is occupied or not, as measured locally or remotely (over " + "the network).", - xref: { document: "cluster", section: "4.3.9.5" } + xref: { document: "cluster", section: "4.3.9.4" } }), Attribute({ name: "AbsMinHeatSetpointLimit", id: 0x3, type: "temperature", access: "R V", conformance: "[HEAT]", constraint: "desc", default: { type: "celsius", value: 7 }, quality: "F", - xref: { document: "cluster", section: "4.3.9" } + details: "Indicates the absolute minimum level that the heating setpoint may be set to. This is a limitation " + + "imposed by the manufacturer." + + "\n" + + "Refer to Setpoint Limits for constraints", + xref: { document: "cluster", section: "4.3.9.5" } }), + Attribute({ name: "AbsMaxHeatSetpointLimit", id: 0x4, type: "temperature", access: "R V", conformance: "[HEAT]", constraint: "desc", default: { type: "celsius", value: 30 }, quality: "F", xref: { document: "cluster", section: "4.3.9" } }), - Attribute({ name: "AbsMinCoolSetpointLimit", id: 0x5, type: "temperature", access: "R V", conformance: "[COOL]", constraint: "desc", default: { type: "celsius", value: 16 }, quality: "F", - details: "Indicates the absolute minimum level that the cooling setpoint may be set to. This is a limitation " + - "imposed by the manufacturer." + - "\n" + - "Refer to Setpoint Limits for constraints", - xref: { document: "cluster", section: "4.3.9.8" } + xref: { document: "cluster", section: "4.3.9" } }), Attribute({ @@ -123,44 +172,44 @@ export const Thermostat = Cluster( "imposed by the manufacturer." + "\n" + "Refer to Setpoint Limits for constraints", - xref: { document: "cluster", section: "4.3.9.9" } + xref: { document: "cluster", section: "4.3.9.8" } }), Attribute({ name: "PiCoolingDemand", id: 0x7, type: "uint8", access: "R V", conformance: "[COOL]", - constraint: "0 to 100", quality: "P", + constraint: "0% to 100%", quality: "P", details: "Indicates the level of cooling demanded by the PI (proportional integral) control loop in use by " + "the thermostat (if any), in percent. This value is 0 when the thermostat is in “off” or “heating” " + "mode." + "\n" + "This attribute is reported regularly and may be used to control a cooling device.", - xref: { document: "cluster", section: "4.3.9.10" } + xref: { document: "cluster", section: "4.3.9.9" } }), Attribute({ name: "PiHeatingDemand", id: 0x8, type: "uint8", access: "R V", conformance: "[HEAT]", - constraint: "0 to 100", quality: "P", + constraint: "0% to 100%", quality: "P", details: "Indicates the level of heating demanded by the PI loop in percent. This value is 0 when the " + "thermostat is in “off” or “cooling” mode." + "\n" + "This attribute is reported regularly and may be used to control a heating device.", - xref: { document: "cluster", section: "4.3.9.11" } + xref: { document: "cluster", section: "4.3.9.10" } }), Attribute({ name: "HvacSystemTypeConfiguration", id: 0x9, type: "HVACSystemTypeBitmap", access: "R[W] VM", conformance: "D", constraint: "desc", default: 0, quality: "N", details: "Indicates the HVAC system type controlled by the thermostat. If the thermostat uses physical DIP " + - "switches to set these parameters, this information shall be available read-only from the DIP " + - "switches. If these parameters are set via software, there shall be read/write access in order to " + - "provide remote programming capability.", - xref: { document: "cluster", section: "4.3.9.12" } + "switches to set these parameters, this information shall be available read-only" + + "\n" + + "from the DIP switches. If these parameters are set via software, there shall be read/write access " + + "in order to provide remote programming capability.", + xref: { document: "cluster", section: "4.3.9.11" } }), Attribute({ name: "LocalTemperatureCalibration", id: 0x10, type: "SignedTemperature", access: "RW VM", - conformance: "[!LTNE]", constraint: "-2.5°C to 2.5°C", default: { type: "celsius", value: 0 }, - quality: "N", + conformance: "[!LTNE]", default: { type: "celsius", value: 0 }, quality: "N", details: "Indicates the offset the Thermostat server shall make to the measured temperature (locally or " + "remotely) to adjust the Calculated Local Temperature prior to using, displaying or reporting it." + @@ -172,39 +221,63 @@ export const Thermostat = Cluster( "If a Thermostat client attempts to write LocalTemperatureCalibration attribute to an unsupported " + "value (e.g., out of the range supported by the Thermostat server), the Thermostat server shall " + "respond with a status of SUCCESS and set the value of LocalTemperatureCalibration to the upper or " + - "lower limit reached.", + "lower limit reached." + + "\n" + + "NOTE" + + "\n" + + "Prior to revision 8 of this cluster specification the value of this attribute was constrained to a " + + "range of -2.5°C to 2.5°C.", - xref: { document: "cluster", section: "4.3.9.13" } + xref: { document: "cluster", section: "4.3.9.12" } }), Attribute({ name: "OccupiedCoolingSetpoint", id: 0x11, type: "temperature", access: "RW VO", - conformance: "COOL", constraint: "desc", default: { type: "celsius", value: 26 }, quality: "N S", + conformance: "COOL", constraint: "desc", default: { type: "celsius", value: 26 }, quality: "N", - details: "Indicates the cooling mode setpoint when the room is occupied." + + details: "Indicates the cooling mode setpoint when the room is occupied. Refer to Setpoint Limits for " + + "constraints." + "\n" + - "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute such that " + - "these constraints are violated, a response with the status code CONSTRAINT_ERROR shall be returned." + + "If an attempt is made to set this attribute to a value greater than MaxCoolSetpointLimit or less " + + "than MinCoolSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If this attribute is set to a value that is less than (OccupiedHeatingSetpoint + " + + "MinSetpointDeadBand), the value of OccupiedHeatingSetpoint shall be adjusted to " + + "(OccupiedCoolingSetpoint - MinSetpointDeadBand)." + "\n" + "If the occupancy status of the room is unknown, this attribute shall be used as the cooling mode " + - "setpoint.", + "setpoint." + + "\n" + + "If a client changes the value of this attribute, the server supports the PRES feature, and the " + + "server either does not support the OCC feature or the Occupied bit is set on the Occupancy " + + "attribute, the value of the ActivePresetHandle attribute shall be set to null.", - xref: { document: "cluster", section: "4.3.9.14" } + xref: { document: "cluster", section: "4.3.9.13" } }), Attribute({ name: "OccupiedHeatingSetpoint", id: 0x12, type: "temperature", access: "RW VO", - conformance: "HEAT", constraint: "desc", default: { type: "celsius", value: 20 }, quality: "N S", + conformance: "HEAT", constraint: "desc", default: { type: "celsius", value: 20 }, quality: "N", - details: "Indicates the heating mode setpoint when the room is occupied." + + details: "Indicates the heating mode setpoint when the room is occupied. Refer to Setpoint Limits for " + + "constraints." + "\n" + - "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute such that " + - "these constraints are violated, a response with the status code CONSTRAINT_ERROR shall be returned." + + "If an attempt is made to set this attribute to a value greater than MaxHeatSetpointLimit or less " + + "than MinHeatSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If this attribute is set to a value that is greater than" + + "\n" + + "Band), the value of OccupiedCoolingSetpoint shall be adjusted to (OccupiedHeatingSetpoint + " + + "MinSetpointDeadBand)." + "\n" + "If the occupancy status of the room is unknown, this attribute shall be used as the heating mode " + - "setpoint.", + "setpoint." + + "\n" + + "If a client changes the value of this attribute, the server supports the PRES feature, and the " + + "server either does not support the OCC feature or the Occupied bit is set on the Occupancy " + + "attribute, the value of the ActivePresetHandle attribute shall be set to null.", - xref: { document: "cluster", section: "4.3.9.15" } + xref: { document: "cluster", section: "4.3.9.14" } }), Attribute({ @@ -212,14 +285,23 @@ export const Thermostat = Cluster( conformance: "COOL & OCC", constraint: "desc", default: { type: "celsius", value: 26 }, quality: "N", - details: "Indicates the cooling mode setpoint when the room is unoccupied." + + details: "Indicates the cooling mode setpoint when the room is unoccupied. Refer to Setpoint Limits for " + + "constraints." + + "\n" + + "If an attempt is made to set this attribute to a value greater than MaxCoolSetpointLimit or less " + + "than MinCoolSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned." + "\n" + - "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute such that " + - "these constraints are violated, a response with the status code CONSTRAINT_ERROR shall be returned." + + "If this attribute is set to a value that is less than (UnoccupiedHeatingSetpoint + " + + "MinSetpointDeadBand), the value of UnoccupiedHeatingSetpoint shall be adjusted to " + + "(UnoccupiedCoolingSetpoint - MinSetpointDeadBand)." + "\n" + - "If the occupancy status of the room is unknown, this attribute shall NOT be used.", + "If the occupancy status of the room is unknown, this attribute shall NOT be used." + + "\n" + + "If a client changes the value of this attribute, the server supports the PRES and OCC features, and " + + "the Occupied bit is not set on the Occupancy attribute, the value of the ActivePresetHandle " + + "attribute shall be set to null.", - xref: { document: "cluster", section: "4.3.9.16" } + xref: { document: "cluster", section: "4.3.9.15" } }), Attribute({ @@ -227,14 +309,24 @@ export const Thermostat = Cluster( conformance: "HEAT & OCC", constraint: "desc", default: { type: "celsius", value: 20 }, quality: "N", - details: "Indicates the heating mode setpoint when the room is unoccupied." + + details: "Indicates the heating mode setpoint when the room is unoccupied. Refer to Setpoint Limits for " + + "constraints." + + "\n" + + "If an attempt is made to set this attribute to a value greater than MaxHeatSetpointLimit or less " + + "than MinHeatSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + "If this attribute is set to a value that is greater than (UnoccupiedCoolingSetpoint - " + + "MinSetpointDeadBand), the value of UnoccupiedCoolingSetpoint shall be adjusted to" + "\n" + - "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute such that " + - "these constraints are violated, a response with the status code CONSTRAINT_ERROR shall be returned." + + "+ MinSetpointDeadBand)." + "\n" + - "If the occupancy status of the room is unknown, this attribute shall NOT be used.", + "If the occupancy status of the room is unknown, this attribute shall NOT be used." + + "\n" + + "If a client changes the value of this attribute, the server supports the PRES and OCC features, and " + + "the Occupied bit is not set on the Occupancy attribute, the value of the ActivePresetHandle " + + "attribute shall be set to null.", - xref: { document: "cluster", section: "4.3.9.17" } + xref: { document: "cluster", section: "4.3.9.16" } }), Attribute({ @@ -253,7 +345,7 @@ export const Thermostat = Cluster( "attribute to a value which is not consistent with the constraints and cannot be resolved by " + "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", - xref: { document: "cluster", section: "4.3.9.18" } + xref: { document: "cluster", section: "4.3.9.17" } }), Attribute({ @@ -268,7 +360,7 @@ export const Thermostat = Cluster( "attribute to a value which is not consistent with the constraints and cannot be resolved by " + "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", - xref: { document: "cluster", section: "4.3.9.19" } + xref: { document: "cluster", section: "4.3.9.18" } }), Attribute({ @@ -283,7 +375,7 @@ export const Thermostat = Cluster( "attribute to a value which is not consistent with the constraints and cannot be resolved by " + "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", - xref: { document: "cluster", section: "4.3.9.20" } + xref: { document: "cluster", section: "4.3.9.19" } }), Attribute({ @@ -298,24 +390,30 @@ export const Thermostat = Cluster( "attribute to a value which is not consistent with the constraints and cannot be resolved by " + "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", - xref: { document: "cluster", section: "4.3.9.21" } + xref: { document: "cluster", section: "4.3.9.20" } }), Attribute({ name: "MinSetpointDeadBand", id: 0x19, type: "SignedTemperature", access: "R[W] VM", - conformance: "AUTO", constraint: "0°C to 2.5°C", default: { type: "celsius", value: 2 }, + conformance: "AUTO", constraint: "0 to 12.7°C", default: { type: "celsius", value: 2 }, quality: "N", details: "On devices which support the AUTO feature, this attribute shall indicate the minimum difference " + "between the Heat Setpoint and the Cool Setpoint." + "\n" + - "Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute to a value " + - "which conflicts with setpoint values then those setpoints shall be adjusted by the minimum amount " + - "to permit this attribute to be set to the desired value. If an attempt is made to set this " + - "attribute to a value which is not consistent with the constraints and cannot be resolved by " + - "modifying setpoints then a response with the status code CONSTRAINT_ERROR shall be returned.", + "Refer to Setpoint Limits for constraints." + + "\n" + + "NOTE" + + "\n" + + "Prior to revision 8 of this cluster specification the value of this attribute was constrained to a " + + "range of 0°C to 2.5°C." + + "\n" + + "NOTE" + + "\n" + + "For backwards compatibility, this attribute is optionally writeable. However any writes to this " + + "attribute shall be silently ignored.", - xref: { document: "cluster", section: "4.3.9.22" } + xref: { document: "cluster", section: "4.3.9.21" } }), Attribute({ @@ -331,23 +429,29 @@ export const Thermostat = Cluster( "If the LocalTemperature RemoteSensing bit is written with a value of 1 when the LTNE feature is " + "present, the write shall fail and the server shall report a CONSTRAINT_ERROR.", - xref: { document: "cluster", section: "4.3.9.23" } + xref: { document: "cluster", section: "4.3.9.22" } }), Attribute({ name: "ControlSequenceOfOperation", id: 0x1b, type: "ControlSequenceOfOperationEnum", access: "RW VM", conformance: "M", constraint: "desc", quality: "N", + details: "Indicates the overall operating environment of the thermostat, and thus the possible system modes " + - "that the thermostat can operate in.", - xref: { document: "cluster", section: "4.3.9.24" } + "that the thermostat can operate in." + + "\n" + + "If an attempt is made to write to this attribute, the server shall silently ignore the write and " + + "the value of this attribute shall remain unchanged. This behavior is in place for backwards " + + "compatibility with existing thermostats.", + + xref: { document: "cluster", section: "4.3.9.23" } }), Attribute({ name: "SystemMode", id: 0x1c, type: "SystemModeEnum", access: "RW VM", conformance: "M", - constraint: "desc", default: 1, quality: "N S", + constraint: "desc", default: 1, quality: "N", details: "Indicates the current operating mode of the thermostat. Its value shall be limited by the " + "ControlSequenceOfOperation attribute.", - xref: { document: "cluster", section: "4.3.9.25" } + xref: { document: "cluster", section: "4.3.9.24" } }), Attribute({ @@ -356,7 +460,7 @@ export const Thermostat = Cluster( details: "Indicates the running mode of the thermostat. This attribute uses the same values as SystemModeEnum " + "but can only be Off, Cool or Heat. This attribute is intended to provide additional information " + "when the thermostat’s system mode is in auto mode.", - xref: { document: "cluster", section: "4.3.9.27" } + xref: { document: "cluster", section: "4.3.9.26" } }), Attribute({ @@ -370,41 +474,64 @@ export const Thermostat = Cluster( "scheduling by reading the attribute. Successful response means that the weekly scheduling is " + "supported.", - xref: { document: "cluster", section: "4.3.9.28" } + xref: { document: "cluster", section: "4.3.9.27" } }), Attribute({ name: "NumberOfWeeklyTransitions", id: 0x21, type: "uint8", access: "R V", conformance: "SCH", default: 0, quality: "F", details: "Indicates how many weekly schedule transitions the thermostat is capable of handling.", - xref: { document: "cluster", section: "4.3.9.29" } + xref: { document: "cluster", section: "4.3.9.28" } }), Attribute({ name: "NumberOfDailyTransitions", id: 0x22, type: "uint8", access: "R V", conformance: "SCH", default: 0, quality: "F", details: "Indicates how many daily schedule transitions the thermostat is capable of handling.", - xref: { document: "cluster", section: "4.3.9.30" } + xref: { document: "cluster", section: "4.3.9.29" } }), Attribute({ name: "TemperatureSetpointHold", id: 0x23, type: "TemperatureSetpointHoldEnum", access: "RW VM", conformance: "O", constraint: "desc", default: 0, quality: "N", + details: "Indicates the temperature hold status on the thermostat. If hold status is on, the thermostat " + "SHOULD maintain the temperature setpoint for the current mode until a system mode change. If hold " + "status is off, the thermostat SHOULD follow the setpoint transitions specified by its internal " + "scheduling program. If the thermostat supports setpoint hold for a specific duration, it SHOULD " + - "also implement the TemperatureSetpointHoldDuration attribute.", - xref: { document: "cluster", section: "4.3.9.31" } + "also implement the TemperatureSetpointHoldDuration attribute." + + "\n" + + "If the server supports a setpoint hold for a specific duration, it SHOULD also implement the " + + "SetpointHoldExpiryTimestamp attribute." + + "\n" + + "If this attribute is updated to SetpointHoldOn and the TemperatureSetpointHoldDuration has a non- " + + "null value and the SetpointHoldExpiryTimestamp is supported, the server shall update the " + + "SetpointHoldExpiryTimestamp with a value of current UTC timestamp, in seconds, plus the value in " + + "TemperatureSetpointHoldDuration multiplied by 60." + + "\n" + + "If this attribute is updated to SetpointHoldOff and the SetpointHoldExpiryTimestamp is supported, " + + "the server shall set the SetpointHoldExpiryTimestamp to null.", + + xref: { document: "cluster", section: "4.3.9.30" } }), Attribute({ name: "TemperatureSetpointHoldDuration", id: 0x24, type: "uint16", access: "RW VM", conformance: "O", constraint: "max 1440", default: null, quality: "X N", + details: "Indicates the period in minutes for which a setpoint hold is active. Thermostats that support hold " + "for a specified duration SHOULD implement this attribute. The null value indicates the field is " + - "unused. All other values are reserved.", - xref: { document: "cluster", section: "4.3.9.32" } + "unused. All other values are reserved." + + "\n" + + "If this attribute is updated to a non-null value and the TemperatureSetpointHold is set to " + + "SetpointHoldOn and the SetpointHoldExpiryTimestamp is supported, the server shall update " + + "SetpointHoldExpiryTimestamp with a value of current UTC timestamp, in seconds, plus the new value " + + "of this attribute multiplied by 60." + + "\n" + + "If this attribute is set to null and the SetpointHoldExpiryTimestamp is supported, the server shall " + + "set the SetpointHoldExpiryTimestamp to null.", + + xref: { document: "cluster", section: "4.3.9.31" } }), Attribute({ @@ -428,7 +555,7 @@ export const Thermostat = Cluster( "Modifying the ScheduleActive bit does not clear or delete previous weekly schedule programming " + "configurations.", - xref: { document: "cluster", section: "4.3.9.33" } + xref: { document: "cluster", section: "4.3.9.32" } }), Attribute({ @@ -436,7 +563,7 @@ export const Thermostat = Cluster( constraint: "desc", details: "Indicates the current relay state of the heat, cool, and fan relays. Unimplemented outputs shall be " + "treated as if they were Off.", - xref: { document: "cluster", section: "4.3.9.34" } + xref: { document: "cluster", section: "4.3.9.33" } }), Attribute({ @@ -451,7 +578,7 @@ export const Thermostat = Cluster( "other service provider). Because automation services may initiate frequent setpoint changes, this " + "attribute clearly differentiates the source of setpoint changes made at the thermostat.", - xref: { document: "cluster", section: "4.3.9.35" } + xref: { document: "cluster", section: "4.3.9.34" } }), Attribute({ @@ -462,14 +589,14 @@ export const Thermostat = Cluster( "attribute; devices implementing SetpointChangeAmount SHOULD also implement SetpointChangeSource." + "\n" + "The null value indicates that the previous setpoint was unknown.", - xref: { document: "cluster", section: "4.3.9.36" } + xref: { document: "cluster", section: "4.3.9.35" } }), Attribute({ name: "SetpointChangeSourceTimestamp", id: 0x32, type: "epoch-s", access: "R V", conformance: "O", default: 0, details: "Indicates the time in UTC at which the SetpointChangeAmount attribute change was recorded.", - xref: { document: "cluster", section: "4.3.9.37" } + xref: { document: "cluster", section: "4.3.9.36" } }), Attribute({ @@ -497,7 +624,7 @@ export const Thermostat = Cluster( "the Thermostat server shall set its OccupiedSetback value to OccupiedSetbackMin and shall send a " + "Write Attribute Response command with a Status Code field enumeration of SUCCESS response.", - xref: { document: "cluster", section: "4.3.9.38" } + xref: { document: "cluster", section: "4.3.9.37" } }), Attribute({ @@ -507,7 +634,7 @@ export const Thermostat = Cluster( "be configured by a user." + "\n" + "The null value indicates the attribute is unused.", - xref: { document: "cluster", section: "4.3.9.39" } + xref: { document: "cluster", section: "4.3.9.38" } }), Attribute({ @@ -517,7 +644,7 @@ export const Thermostat = Cluster( "be configured by a user." + "\n" + "The null value indicates the attribute is unused.", - xref: { document: "cluster", section: "4.3.9.40" } + xref: { document: "cluster", section: "4.3.9.39" } }), Attribute({ @@ -547,7 +674,7 @@ export const Thermostat = Cluster( "UnoccupiedSetbackMin and shall send a Write Attribute Response command with a Status Code field " + "enumeration of SUCCESS response.", - xref: { document: "cluster", section: "4.3.9.41" } + xref: { document: "cluster", section: "4.3.9.40" } }), Attribute({ @@ -557,7 +684,7 @@ export const Thermostat = Cluster( "to be configured by a user." + "\n" + "The null value indicates the attribute is unused.", - xref: { document: "cluster", section: "4.3.9.42" } + xref: { document: "cluster", section: "4.3.9.41" } }), Attribute({ @@ -568,7 +695,7 @@ export const Thermostat = Cluster( "to be configured by a user." + "\n" + "The null value indicates the attribute is unused.", - xref: { document: "cluster", section: "4.3.9.43" } + xref: { document: "cluster", section: "4.3.9.42" } }), Attribute( @@ -603,7 +730,7 @@ export const Thermostat = Cluster( "heating when a setpoint is of a specified amount greater than the measured temperature. This allows " + "the heated space to be quickly heated to the desired level set by the user.", - xref: { document: "cluster", section: "4.3.9.44" } + xref: { document: "cluster", section: "4.3.9.43" } } ), @@ -612,71 +739,363 @@ export const Thermostat = Cluster( default: 0, quality: "N", details: "Indicates the type of Mini Split ACTypeEnum of Mini Split AC is defined depending on how Cooling " + "and Heating condition is achieved by Mini Split AC.", - xref: { document: "cluster", section: "4.3.9.45" } + xref: { document: "cluster", section: "4.3.9.44" } }), Attribute({ name: "AcCapacity", id: 0x41, type: "uint16", access: "RW VM", conformance: "O", default: 0, quality: "N", details: "Indicates capacity of Mini Split AC in terms of the format defined by the ACCapacityFormat attribute", - xref: { document: "cluster", section: "4.3.9.46" } + xref: { document: "cluster", section: "4.3.9.45" } }), Attribute({ name: "AcRefrigerantType", id: 0x42, type: "ACRefrigerantTypeEnum", access: "RW VM", conformance: "O", constraint: "desc", default: 0, quality: "N", details: "Indicates type of refrigerant used within the Mini Split AC.", - xref: { document: "cluster", section: "4.3.9.47" } + xref: { document: "cluster", section: "4.3.9.46" } }), Attribute({ name: "AcCompressorType", id: 0x43, type: "ACCompressorTypeEnum", access: "RW VM", conformance: "O", constraint: "desc", default: 0, quality: "N", details: "Indicates the type of compressor used within the Mini Split AC.", - xref: { document: "cluster", section: "4.3.9.48" } + xref: { document: "cluster", section: "4.3.9.47" } }), Attribute({ name: "AcErrorCode", id: 0x44, type: "ACErrorCodeBitmap", access: "RW VM", conformance: "O", default: 0, details: "Indicates the type of errors encountered within the Mini Split AC.", - xref: { document: "cluster", section: "4.3.9.49" } + xref: { document: "cluster", section: "4.3.9.48" } }), Attribute({ name: "AcLouverPosition", id: 0x45, type: "ACLouverPositionEnum", access: "RW VM", conformance: "O", constraint: "desc", default: 0, quality: "N", details: "Indicates the position of Louver on the AC.", - xref: { document: "cluster", section: "4.3.9.50" } + xref: { document: "cluster", section: "4.3.9.49" } }), Attribute({ name: "AcCoilTemperature", id: 0x46, type: "temperature", access: "R V", conformance: "O", default: null, quality: "X", details: "Indicates the temperature of the AC coil, as measured locally or remotely (over the network).", - xref: { document: "cluster", section: "4.3.9.51" } + xref: { document: "cluster", section: "4.3.9.50" } }), Attribute({ name: "AcCapacityFormat", id: 0x47, type: "ACCapacityFormatEnum", access: "RW VM", conformance: "O", constraint: "desc", default: 0, quality: "N", details: "Indicates the format for the ACCapacity attribute.", - xref: { document: "cluster", section: "4.3.9.52" } + xref: { document: "cluster", section: "4.3.9.51" } + }), + + Attribute( + { + name: "PresetTypes", id: 0x48, type: "list", access: "R V", conformance: "PRES", constraint: "desc", + quality: "F", + details: "Indicates the supported PresetScenarioEnum values, limits on how many presets can be created for " + + "each PresetScenarioEnum, and whether or not a thermostat can transition automatically to a given " + + "scenario.", + xref: { document: "cluster", section: "4.3.9.52" } + }, + + Field({ name: "entry", type: "PresetTypeStruct" }) + ), + + Attribute( + { + name: "ScheduleTypes", id: 0x49, type: "list", access: "R V", conformance: "MSCH", + constraint: "desc", quality: "F", + details: "Indicates the supported SystemMode values for Schedules, limits on how many schedules can be " + + "created for each SystemMode value, and whether or not a given SystemMode value supports transitions " + + "to Presets, target setpoints, or both.", + xref: { document: "cluster", section: "4.3.9.53" } + }, + + Field({ name: "entry", type: "ScheduleTypeStruct" }) + ), + + Attribute({ + name: "NumberOfPresets", id: 0x4a, type: "uint8", access: "R V", conformance: "PRES", default: 0, + quality: "F", + details: "Indicates the maximum number of entries supported by the Presets attribute.", + xref: { document: "cluster", section: "4.3.9.54" } + }), + + Attribute({ + name: "NumberOfSchedules", id: 0x4b, type: "uint8", access: "R V", conformance: "MSCH", default: 0, + quality: "F", + details: "Indicates the maximum number of entries supported by the Schedules attribute.", + xref: { document: "cluster", section: "4.3.9.55" } + }), + + Attribute({ + name: "NumberOfScheduleTransitions", id: 0x4c, type: "uint8", access: "R V", conformance: "MSCH", + default: 0, quality: "F", + details: "Indicates the maximum number of transitions per Schedules attribute entry.", + xref: { document: "cluster", section: "4.3.9.56" } + }), + + Attribute({ + name: "NumberOfScheduleTransitionPerDay", id: 0x4d, type: "uint8", access: "R V", + conformance: "MSCH", default: null, quality: "X F", + xref: { document: "cluster", section: "4.3.9" } + }), + + Attribute({ + name: "ActivePresetHandle", id: 0x4e, type: "octstr", access: "R V", conformance: "PRES", + constraint: "max 16", default: null, quality: "X N", + details: "Indicates the PresetHandle of the active preset. If this attribute is null, then there is no active " + + "preset.", + xref: { document: "cluster", section: "4.3.9.58" } + }), + + Attribute({ + name: "ActiveScheduleHandle", id: 0x4f, type: "octstr", access: "R V", conformance: "MSCH", + constraint: "max 16", default: null, quality: "X N", + details: "Indicates the ScheduleHandle of the active schedule. A null value in this attribute indicates that " + + "there is no active schedule.", + xref: { document: "cluster", section: "4.3.9.59" } + }), + + Attribute( + { + name: "Presets", id: 0x50, type: "list", access: "RW VM", conformance: "PRES", + constraint: "max numberOfPresets", default: [], quality: "N T", + + details: "This attribute shall contain the current list of configured presets. On receipt of a write request:" + + "\n" + + " 1. If the PresetHandle field is null, the PresetStruct shall be treated as an added preset, and " + + " the device shall create a new unique value for the PresetHandle field." + + "\n" + + " a. If the BuiltIn field is true, a response with the status code CONSTRAINT_ERROR shall be " + + " returned." + + "\n" + + " 2. If the PresetHandle field is not null, the PresetStruct shall be treated as a modification of " + + " an existing preset." + + "\n" + + " a. If the value of the PresetHandle field does not match any of the existing presets, a " + + " response with the status code NOT_FOUND shall be returned." + + "\n" + + " b. If the value of the PresetHandle field is duplicated on multiple presets in the updated " + + " list, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " c. If the BuiltIn field is true, and the PresetStruct in the current value with a matching " + + " PresetHandle field has a BuiltIn field set to false, a response with the status code " + + " CONSTRAINT_ERROR shall be returned." + + "\n" + + " d. If the BuiltIn field is false, and the PresetStruct in the current value with a matching " + + " PresetHandle field has a BuiltIn field set to true, a response with the status code " + + " CONSTRAINT_ERROR shall be returned." + + "\n" + + " 3. If the specified PresetScenarioEnum value does not exist in PresetTypes, a response with the " + + " status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " 4. If the Name is set, but the associated PresetTypeStruct does not have the SupportsNames bit " + + " set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " 5. If appending the received PresetStruct to the pending list of Presets would cause the total " + + " number of pending presets to exceed the value of the NumberOfPresets attribute, a response " + + " with the status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " 6. If appending the received PresetStruct to the pending list of Presets would cause the total " + + " number of pending presets whose PresetScenario field matches the appended preset’s " + + " PresetScenario field to exceed the value of the NumberOfPresets field on the PresetTypeStruct " + + " whose PresetScenario matches the appended preset’s PresetScenario field, a response with the " + + " status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " 7. Otherwise, the write shall be pended until receipt of a commit request, and the status code " + + " SUCCESS shall be returned." + + "\n" + + " a. If the BuiltIn field is null:" + + "\n" + + " i. If there is a PresetStruct in the current value with a matching PresetHandle field, the " + + " BuiltIn field on the pending PresetStruct shall be set to the value of the BuiltIn on the " + + " matching PresetStruct." + + "\n" + + " ii. Otherwise, the BuiltIn field on the pending PresetStruct shall be set to false." + + "\n" + + "On an attempt to commit, the status of this attribute shall be determined as follows:" + + "\n" + + " 1. For all existing presets:" + + "\n" + + " a. If, after applying all pending changes, the updated value of the Presets attribute would not " + + " contain a PresetStruct with a matching PresetHandle field, indicating the removal of the " + + " PresetStruct, the server shall check for invalid removal of the PresetStruct:" + + "\n" + + " i. If the BuiltIn field is true on the removed PresetStruct, the attribute status shall be " + + " CONSTRAINT_ERROR." + + "\n" + + " ii. If the MSCH feature is supported and the removed PresetHandle would be referenced by any " + + " PresetHandle on any ScheduleTransitionStruct on any ScheduleStruct in the updated value " + + " of the Schedules attribute, the attribute status shall be INVALID_IN_STATE." + + "\n" + + " iii. If the removed PresetHandle is equal to the value of the ActivePresetHandle attribute, " + + " the attribute status shall be INVALID_IN_STATE." + + "\n" + + " 2. Otherwise, the attribute status shall be SUCCESS.", + + xref: { document: "cluster", section: "4.3.9.60" } + }, + + Field({ name: "entry", type: "PresetStruct" }) + ), + + Attribute( + { + name: "Schedules", id: 0x51, type: "list", access: "RW VM", conformance: "MSCH", constraint: "desc", + default: [], quality: "N T", + + details: "This attribute shall contain a list of ScheduleStructs. On receipt of a write request:" + + "\n" + + " 1. For all schedules in the write request:" + + "\n" + + " a. If the ScheduleHandle field is null, the ScheduleStruct shall be treated as an added " + + " schedule, and the device shall create a new unique value for the ScheduleHandle field." + + "\n" + + " i. If the BuiltIn field is true, a response with the status code CONSTRAINT_ERROR shall be " + + " returned." + + "\n" + + " b. Otherwise, if the ScheduleHandle field is not null, the ScheduleStruct shall be treated as a " + + " modification of an existing schedule." + + "\n" + + " i. If the value of the ScheduleHandle field does not match any of the existing schedules, a " + + " response with the status code NOT_FOUND shall be returned." + + "\n" + + " ii. If the BuiltIn field is true, and the ScheduleStruct in the current value with a matching " + + " ScheduleHandle field has a BuiltIn field set to false, a response with the status code " + + " CONSTRAINT_ERROR shall be returned." + + "\n" + + " iii. If the BuiltIn field is false, and the ScheduleStruct in the current value with a " + + " matching ScheduleHandle field has a BuiltIn field set to true, a response with the " + + " status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " c. If the specified SystemMode does not exist in ScheduleTypes, a response with the status code " + + " CONSTRAINT_ERROR shall be returned." + + "\n" + + " d. If the number of transitions exceeds the NumberOfScheduleTransitions value, a response with " + + " the status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " e. If the value of the NumberOfScheduleTransitionsPerDay attribute is not null, and the number " + + " of transitions on any single day of the week exceeds the NumberOfScheduleTransitionsPerDay " + + " value, a response with the status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " f. If the PresetHandle field is present, but the associated ScheduleTypeStruct does not have " + + " the SupportsPresets bit set, a response with the status code CONSTRAINT_ERROR shall be " + + " returned." + + "\n" + + " g. If the PresetHandle field is present, but after applying all pending changes, the Presets " + + " attribute would not contain a PresetStruct whose PresetHandle field matches the value of the " + + " PresetHandle field, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " h. If the Name is set, but the associated ScheduleTypeStruct does not have the SupportsNames " + + " bit set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " i. For all transitions in all schedules in the write request:" + + "\n" + + " i. If the PresetHandle field is present, but the ScheduleTypeStruct matching the value of the " + + " SystemMode field on the encompassing ScheduleStruct does not have the SupportsPresets bit " + + " set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " j. If the PresetHandle field is present, but after applying all pending changes, the Presets " + + " attribute would not contain a PresetStruct whose PresetHandle field matches the value of the " + + " PresetHandle field, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " i. If the SystemMode field is present, but the ScheduleTypeStruct matching the value of the " + + " SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints " + + " bit set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " ii. If the SystemMode field is has a value of SystemModeOff, but the ScheduleTypeStruct " + + " matching the value of the SystemMode field on the encompassing ScheduleStruct does not " + + " have the SupportsOff bit set, a response with the status code CONSTRAINT_ERROR shall be " + + " returned." + + "\n" + + " k. If the HeatingSetpoint field is present, but the ScheduleTypeStruct matching the value of " + + " the SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints " + + " bit set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " l. If the CoolingSetpoint field is present, but the ScheduleTypeStruct matching the value of " + + " the SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints " + + " bit set, a response with the status code CONSTRAINT_ERROR shall be returned." + + "\n" + + " 2. If appending the received ScheduleStruct to the pending list of Schedules would cause the " + + " total number of pending schedules to exceed the value of the NumberOfSchedules attribute, a " + + " response with the status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " 3. If appending the received ScheduleStruct to the pending list of Schedules would cause the " + + " total number of pending schedules whose SystemMode field matches the appended schedule’s " + + " SystemMode field to exceed the value of the NumberOfSchedules field on the ScheduleTypeStruct " + + " whose SystemMode field matches the appended schedule’s SystemMode field, a response with the " + + " status code RESOURCE_EXHAUSTED shall be returned." + + "\n" + + " 4. Otherwise, the write shall be pended until receipt of a commit request, and the attribute " + + " status shall be SUCCESS." + + "\n" + + " a. If the BuiltIn field is null:" + + "\n" + + " i. If there is a ScheduleStruct in the current value with a matching ScheduleHandle field, " + + " the BuiltIn field on the pending ScheduleStruct shall be set to the value of the BuiltIn " + + " on the matching ScheduleStruct." + + "\n" + + " ii. Otherwise, the BuiltIn field on the pending ScheduleStruct shall be set to false." + + "\n" + + "On an attempt to commit, the status of this attribute shall be determined as follows:" + + "\n" + + " 1. For all existing schedules:" + + "\n" + + " a. If, after applying all pending changes, the updated value of the Schedules attribute would " + + " not contain a ScheduleStruct with a matching ScheduleHandle field, indicating the removal of " + + " the ScheduleStruct, the server shall check for invalid removal of the ScheduleStruct:" + + "\n" + + " i. If the BuiltIn field is true on the removed ScheduleStruct, the attribute status shall be " + + " CONSTRAINT_ERROR." + + "\n" + + " ii. If the removed ScheduleHandle is equal to the value of the ActiveScheduleHandle " + + " attribute, the attribute status shall be INVALID_IN_STATE." + + "\n" + + " 2. Otherwise, the attribute status shall be SUCCESS.", + + xref: { document: "cluster", section: "4.3.9.61" } + }, + + Field({ name: "entry", type: "ScheduleStruct" }) + ), + + Attribute({ + name: "SetpointHoldExpiryTimestamp", id: 0x52, type: "epoch-s", access: "R V", conformance: "O", + default: null, quality: "X N", + + details: "If there is a known time when the TemperatureSetpointHold shall be cleared, this attribute shall " + + "contain the timestamp in UTC indicating when that will happen. If there is no such known time, this " + + "attribute shall be null." + + "\n" + + "If the TemperatureSetpointHold is set to SetpointHoldOff or the TemperatureSetpointHoldDuration is " + + "set to null, this attribute shall be set to null indicating there is no hold on the Thermostat " + + "either with or without a duration.", + + xref: { document: "cluster", section: "4.3.9.62" } }), Command( { name: "SetpointRaiseLower", id: 0x0, access: "O", conformance: "M", direction: "request", response: "status", - details: "Upon receipt, the attributes for the indicated setpoint(s) shall have the amount specified in the " + - "Amount field added to them. If the resulting value is outside the limits imposed by " + - "MinCoolSetpointLimit, MaxCoolSetpointLimit, MinHeatSetpointLimit and MaxHeatSetpointLimit, the " + - "value is clamped to those limits. This is not considered an error condition.", xref: { document: "cluster", section: "4.3.10.1" } }, + Field({ + name: "Mode", id: 0x0, type: "SetpointRaiseLowerModeEnum", conformance: "M", constraint: "desc", + details: "The field shall specify which setpoints are to be adjusted.", + xref: { document: "cluster", section: "4.3.10.1.1" } + }), - Field({ name: "Mode", id: 0x0, type: "SetpointRaiseLowerModeEnum", conformance: "M", constraint: "desc" }), - Field({ name: "Amount", id: 0x1, type: "int8", conformance: "M" }) + Field({ + name: "Amount", id: 0x1, type: "int8", conformance: "M", + details: "This field shall indicate the amount (possibly negative) that should be added to the setpoint(s), " + + "in steps of 0.1°C.", + xref: { document: "cluster", section: "4.3.10.1.2" } + }) ), Command( @@ -684,36 +1103,16 @@ export const Thermostat = Cluster( name: "SetWeeklySchedule", id: 0x1, access: "M", conformance: "SCH", direction: "request", response: "status", - details: "Upon receipt, the weekly schedule for updating setpoints shall be stored in the thermostat and " + - "SHOULD begin at the time of receipt. A status code shall be sent in response." + - "\n" + - "When a command is received that requires a total number of transitions greater than the device " + - "supports, the status of the response shall be INSUFFICIENT_SPACE." + - "\n" + - "When any of the setpoints sent in the sequence is out of range (AbsMin/MaxSetPointLimit), or when " + - "the Mode for Sequence field includes a mode not supported by the device, the status of the response " + - "shall be CONSTRAINT_ERROR and no setpoints from the entire sequence SHOULD be used." + - "\n" + - "When an overlapping transition is detected, the status of the response shall be FAILURE." + - "\n" + - "When a device which does not support multiple days in a command receives a command with more than " + - "one bit set in the DayOfWeekForSequence field, or when a device which does not support multiple " + - "modes in a command receives a command with more than one bit set in the ModeForSequence field, or " + - "when the contents of the Transitions field does not agree with NumberOfTransitionsForSequence, " + - "DayOfWeekForSequence or ModeForSequence, the status of the response shall be INVALID_COMMAND." + - "\n" + - "When the transitions could be added successfully, the status of the response shall be SUCCESS." + - "\n" + - "The set weekly schedule command is used to update the thermostat weekly setpoint schedule from a " + - "management system. If the thermostat already has a weekly setpoint schedule programmed, then it " + - "SHOULD replace each daily setpoint set as it receives the updates from the management system. For " + - "example, if the thermostat has 4 setpoints for every day of the week and is sent a Set Weekly " + - "Schedule command with one setpoint for Saturday then the thermostat SHOULD remove all 4 setpoints " + - "for Saturday and replace those with the updated setpoint but leave all other days unchanged. If the " + - "schedule is larger than what fits in one frame or contains more than 10 transitions, the schedule " + - "shall then be sent using multiple Set Weekly Schedule Commands.", + details: "This command is used to update the thermostat weekly setpoint schedule from a management system. If " + + "the thermostat already has a weekly setpoint schedule programmed, then it SHOULD replace each daily " + + "setpoint set as it receives the updates from the management system. For example, if the thermostat " + + "has 4 setpoints for every day of the week and is sent a SetWeeklySchedule command with one setpoint " + + "for Saturday then the thermostat SHOULD remove all 4 setpoints for Saturday and replace those with " + + "the updated setpoint but leave all other days unchanged. If the schedule is larger than what fits " + + "in one frame or contains more than 10 transitions, the schedule shall then be sent using multiple " + + "SetWeeklySchedule Commands.", - xref: { document: "cluster", section: "4.3.10.4" } + xref: { document: "cluster", section: "4.3.10.2" } }, Field({ @@ -722,7 +1121,7 @@ export const Thermostat = Cluster( "If a device supports more than 10 transitions in its schedule they can send this by sending more " + "than 1 “Set Weekly Schedule” command, each containing the separate information that the device " + "needs to set.", - xref: { document: "cluster", section: "4.3.10.4.1" } + xref: { document: "cluster", section: "4.3.10.2.1" } }), Field({ @@ -737,7 +1136,7 @@ export const Thermostat = Cluster( "Each setpoint transition will begin with the day of week for this transition. There can be up to 10 " + "transitions for each command.", - xref: { document: "cluster", section: "4.3.10.4.2" } + xref: { document: "cluster", section: "4.3.10.2.2" } }), Field({ @@ -763,7 +1162,7 @@ export const Thermostat = Cluster( "Both bits must be respected, even if the HEAT or COOL feature is not supported, to ensure the " + "command is decoded and handled correctly.", - xref: { document: "cluster", section: "4.3.10.4.3" } + xref: { document: "cluster", section: "4.3.10.2.3" } }), Field( @@ -771,7 +1170,7 @@ export const Thermostat = Cluster( name: "Transitions", id: 0x3, type: "list", conformance: "M", constraint: "max 10", details: "This field shall contain the list of setpoint transitions used to update the specified daily " + "schedules", - xref: { document: "cluster", section: "4.3.10.4.4" } + xref: { document: "cluster", section: "4.3.10.2.4" } }, Field({ name: "entry", type: "WeeklyScheduleTransitionStruct" }) @@ -782,12 +1181,7 @@ export const Thermostat = Cluster( { name: "GetWeeklySchedule", id: 0x2, access: "O", conformance: "SCH", direction: "request", response: "GetWeeklyScheduleResponse", - details: "Upon receipt, the unit SHOULD send in return the Get Weekly Schedule Response command. The Days to " + - "Return and Mode to Return fields are defined as bitmask for the flexibility to support multiple " + - "days and multiple modes within one command. If thermostat cannot handle incoming command with " + - "multiple days and/or multiple modes within one command, it shall send default response of " + - "INVALID_COMMAND in return.", - xref: { document: "cluster", section: "4.3.10.5" } + xref: { document: "cluster", section: "4.3.10.3" } }, Field({ @@ -795,14 +1189,14 @@ export const Thermostat = Cluster( constraint: "desc", details: "This field shall indicate the number of days the client would like to return the setpoint values " + "for and could be any combination of single days or the entire week.", - xref: { document: "cluster", section: "4.3.10.5.1" } + xref: { document: "cluster", section: "4.3.10.3.1" } }), Field({ name: "ModeToReturn", id: 0x1, type: "ScheduleModeBitmap", conformance: "M", constraint: "desc", details: "This field shall indicate the mode the client would like to return the set point values for and " + "could be any combination of heat only, cool only or heat & cool.", - xref: { document: "cluster", section: "4.3.10.5.2" } + xref: { document: "cluster", section: "4.3.10.3.2" } }) ), @@ -810,7 +1204,7 @@ export const Thermostat = Cluster( { name: "GetWeeklyScheduleResponse", id: 0x0, conformance: "SCH", direction: "response", details: "This command has the same payload format as the Set Weekly Schedule.", - xref: { document: "cluster", section: "4.3.10.6" } + xref: { document: "cluster", section: "4.3.10.4" } }, Field({ name: "NumberOfTransitionsForSequence", id: 0x0, type: "uint8", conformance: "M" }), Field({ @@ -831,7 +1225,7 @@ export const Thermostat = Cluster( "\n" + "Upon receipt, all transitions currently stored shall be cleared and a default response of SUCCESS " + "shall be sent in response. There are no error responses to this command.", - xref: { document: "cluster", section: "4.3.10.7" } + xref: { document: "cluster", section: "4.3.10.5" } }), Command( @@ -840,7 +1234,7 @@ export const Thermostat = Cluster( details: "This command is sent from the thermostat cluster server in response to the Get Relay Status Log. " + "After the Relay Status Entry is sent over the air to the requesting client, the specific entry will " + "be cleared from the thermostat internal log.", - xref: { document: "cluster", section: "4.3.10.9" } + xref: { document: "cluster", section: "4.3.10.7" } }, Field({ @@ -848,7 +1242,7 @@ export const Thermostat = Cluster( details: "This field shall indicate the sample time of the day, in minutes since midnight, when the relay " + "status was captured for this associated log entry. For example, 6am will be represented by 360 " + "minutes since midnight and 11:30pm will be represented by 1410 minutes since midnight.", - xref: { document: "cluster", section: "4.3.10.9.1" } + xref: { document: "cluster", section: "4.3.10.7.1" } }), Field({ @@ -857,29 +1251,59 @@ export const Thermostat = Cluster( "represents one relay used by the thermostat. If the bit is on, the associated relay is on and " + "active. Each thermostat manufacturer can create its own mapping between the bitmap and the " + "associated relay.", - xref: { document: "cluster", section: "4.3.10.9.2" } + xref: { document: "cluster", section: "4.3.10.7.2" } }), Field({ name: "LocalTemperature", id: 0x2, type: "temperature", conformance: "M", quality: "X", details: "This field shall indicate the LocalTemperature when the log is captured. The null value indicates " + "that LocalTemperature was invalid or unavailable.", - xref: { document: "cluster", section: "4.3.10.9.3" } + xref: { document: "cluster", section: "4.3.10.7.3" } }), Field({ - name: "HumidityInPercentage", id: 0x3, type: "uint8", conformance: "M", constraint: "0 to 100", + name: "HumidityInPercentage", id: 0x3, type: "uint8", conformance: "M", constraint: "0% to 100%", quality: "X" }), Field({ name: "SetPoint", id: 0x4, type: "temperature", conformance: "M", details: "This field shall indicate the target setpoint temperature when the log is captured.", - xref: { document: "cluster", section: "4.3.10.9.5" } + xref: { document: "cluster", section: "4.3.10.7.5" } }), Field({ name: "UnreadEntries", id: 0x5, type: "uint16", conformance: "M", details: "This field shall indicate the number of unread entries within the thermostat internal log system.", - xref: { document: "cluster", section: "4.3.10.9.6" } + xref: { document: "cluster", section: "4.3.10.7.6" } + }) + ), + + Command( + { + name: "SetActiveScheduleRequest", id: 0x5, access: "O", conformance: "MSCH", direction: "request", + response: "status", + xref: { document: "cluster", section: "4.3.10.8" } + }, + + Field({ + name: "ScheduleHandle", id: 0x0, type: "octstr", conformance: "M", constraint: "max 16", + details: "This field shall specify the value of the ScheduleHandle field on the ScheduleStruct to be made " + + "active.", + xref: { document: "cluster", section: "4.3.10.8.1" } + }) + ), + + Command( + { + name: "SetActivePresetRequest", id: 0x6, access: "O", conformance: "PRES", direction: "request", + response: "status", + xref: { document: "cluster", section: "4.3.10.9" } + }, + + Field({ + name: "PresetHandle", id: 0x0, type: "octstr", conformance: "M", constraint: "max 16", quality: "X", + details: "This field shall specify the value of the PresetHandle field on the PresetStruct to be made active. " + + "If the field is set to null, that indicates there should be no active preset.", + xref: { document: "cluster", section: "4.3.10.9.1" } }) ), @@ -966,7 +1390,7 @@ export const Thermostat = Cluster( Field( { - name: "CoolingStage", constraint: "0 to 2", + name: "CoolingStage", constraint: "1 to 1", description: "Stage of cooling the HVAC system is using.", details: "These bits shall indicate what stage of cooling the HVAC system is using." + @@ -985,7 +1409,7 @@ export const Thermostat = Cluster( Field( { - name: "HeatingStage", constraint: "2 to 4", + name: "HeatingStage", constraint: "3 to 3", description: "Stage of heating the HVAC system is using.", details: "These bits shall indicate what stage of heating the HVAC system is using." + @@ -1027,8 +1451,18 @@ export const Thermostat = Cluster( ) ), + Datatype({ + name: "OccupancyBitmap", type: "OccupancySensing.OccupancyBitmap", + xref: { document: "cluster", section: "4.3.8.7" } + }), Datatype( - { name: "ProgrammingOperationModeBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.7" } }, + { name: "PresetTypeFeaturesBitmap", type: "map16", xref: { document: "cluster", section: "4.3.8.8" } }, + Field({ name: "Automatic", constraint: "0", description: "Preset may be automatically activated by the thermostat" }), + Field({ name: "SupportsNames", constraint: "1", description: "Preset supports user- provided names" }) + ), + + Datatype( + { name: "ProgrammingOperationModeBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.9" } }, Field({ name: "ScheduleActive", constraint: "0", description: "Schedule programming mode. This enables any programmed weekly schedule configurations." @@ -1038,18 +1472,18 @@ export const Thermostat = Cluster( ), Datatype( - { name: "RelayStateBitmap", type: "map16", xref: { document: "cluster", section: "4.3.8.8" } }, - Field({ name: "Heat", constraint: "0", description: "Heat State On" }), - Field({ name: "Cool", constraint: "1", description: "Cool State On" }), - Field({ name: "Fan", constraint: "2", description: "Fan State On" }), - Field({ name: "HeatStage2", constraint: "3", description: "Heat 2nd State On" }), - Field({ name: "CoolStage2", constraint: "4", description: "Cool 2nd State On" }), - Field({ name: "FanStage2", constraint: "5", description: "Fan 2nd State On" }), + { name: "RelayStateBitmap", type: "map16", xref: { document: "cluster", section: "4.3.8.10" } }, + Field({ name: "Heat", constraint: "0", description: "Heat Stage On" }), + Field({ name: "Cool", constraint: "1", description: "Cool Stage On" }), + Field({ name: "Fan", constraint: "2", description: "Fan Stage On" }), + Field({ name: "HeatStage2", constraint: "3", description: "Heat 2nd Stage On" }), + Field({ name: "CoolStage2", constraint: "4", description: "Cool 2nd Stage On" }), + Field({ name: "FanStage2", constraint: "5", description: "Fan 2nd Stage On" }), Field({ name: "FanStage3", constraint: "6", description: "Fan 3rd Stage On" }) ), Datatype( - { name: "RemoteSensingBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.9" } }, + { name: "RemoteSensingBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.11" } }, Field({ name: "LocalTemperature", constraint: "0", description: "Calculated Local Temperature is derived from a remote node" @@ -1059,14 +1493,50 @@ export const Thermostat = Cluster( name: "OutdoorTemperature", constraint: "1", description: "OutdoorTemperature is derived from a remote node", details: "This bit shall be supported if the OutdoorTemperature attribute is supported.", - xref: { document: "cluster", section: "4.3.8.9.1" } + xref: { document: "cluster", section: "4.3.8.11.1" } }), Field({ name: "Occupancy", constraint: "2", description: "Occupancy is derived from a remote node" }) ), Datatype( - { name: "ScheduleDayOfWeekBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.10" } }, + { name: "ScheduleTypeFeaturesBitmap", type: "map16", xref: { document: "cluster", section: "4.3.8.12" } }, + + Field({ + name: "SupportsPresets", constraint: "0", description: "Supports presets", + details: "This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the " + + "SystemMode field on the encompassing ScheduleTypeStruct supports specifying presets on " + + "ScheduleTransitionStructs contained in its Transitions field.", + xref: { document: "cluster", section: "4.3.8.12.1" } + }), + + Field({ + name: "SupportsSetpoints", constraint: "1", description: "Supports setpoints", + details: "This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the " + + "SystemMode field on the encompassing ScheduleTypeStruct supports specifying setpoints on " + + "ScheduleTransitionStructs contained in its Transitions field.", + xref: { document: "cluster", section: "4.3.8.12.2" } + }), + + Field({ + name: "SupportsNames", constraint: "2", description: "Supports user-provided names", + details: "This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the " + + "SystemMode field on the encompassing ScheduleTypeStruct supports setting the value of the Name " + + "field.", + xref: { document: "cluster", section: "4.3.8.12.3" } + }), + + Field({ + name: "SupportsOff", constraint: "3", description: "Supports transitioning to SystemModeOff", + details: "This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the " + + "SystemMode field on the encompassing ScheduleTypeStruct supports setting its SystemMode field to " + + "Off.", + xref: { document: "cluster", section: "4.3.8.12.4" } + }) + ), + + Datatype( + { name: "ScheduleDayOfWeekBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.13" } }, Field({ name: "Sunday", constraint: "0", description: "Sunday" }), Field({ name: "Monday", constraint: "1", description: "Monday" }), Field({ name: "Tuesday", constraint: "2", description: "Tuesday" }), @@ -1078,17 +1548,17 @@ export const Thermostat = Cluster( ), Datatype( - { name: "ScheduleModeBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.11" } }, + { name: "ScheduleModeBitmap", type: "map8", xref: { document: "cluster", section: "4.3.8.14" } }, Field({ name: "HeatSetpointPresent", constraint: "0", description: "Adjust Heat Setpoint" }), Field({ name: "CoolSetpointPresent", constraint: "1", description: "Adjust Cool Setpoint" }) ), Datatype( - { name: "ACCapacityFormatEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.12" } }, + { name: "ACCapacityFormatEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.15" } }, Field({ name: "BtUh", id: 0x0, conformance: "O", description: "British Thermal Unit per Hour" }) ), Datatype( - { name: "ACCompressorTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.13" } }, + { name: "ACCompressorTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.16" } }, Field({ name: "Unknown", id: 0x0, conformance: "O", description: "Unknown compressor type" }), Field({ name: "T1", id: 0x1, conformance: "O", description: "Max working ambient 43 °C" }), Field({ name: "T2", id: 0x2, conformance: "O", description: "Max working ambient 35 °C" }), @@ -1096,7 +1566,7 @@ export const Thermostat = Cluster( ), Datatype( - { name: "ACLouverPositionEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.14" } }, + { name: "ACLouverPositionEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.17" } }, Field({ name: "Closed", id: 0x1, conformance: "O", description: "Fully Closed" }), Field({ name: "Open", id: 0x2, conformance: "O", description: "Fully Open" }), Field({ name: "Quarter", id: 0x3, conformance: "O", description: "Quarter Open" }), @@ -1105,7 +1575,7 @@ export const Thermostat = Cluster( ), Datatype( - { name: "ACRefrigerantTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.15" } }, + { name: "ACRefrigerantTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.18" } }, Field({ name: "Unknown", id: 0x0, conformance: "O", description: "Unknown Refrigerant Type" }), Field({ name: "R22", id: 0x1, conformance: "O", description: "R22 Refrigerant" }), Field({ name: "R410A", id: 0x2, conformance: "O", description: "R410a Refrigerant" }), @@ -1113,7 +1583,7 @@ export const Thermostat = Cluster( ), Datatype( - { name: "ACTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.16" } }, + { name: "ACTypeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.19" } }, Field({ name: "Unknown", id: 0x0, conformance: "O", description: "Unknown AC Type" }), Field({ name: "CoolingFixed", id: 0x1, conformance: "O", description: "Cooling and Fixed Speed" }), Field({ name: "HeatPumpFixed", id: 0x2, conformance: "O", description: "Heat Pump and Fixed Speed" }), @@ -1122,7 +1592,7 @@ export const Thermostat = Cluster( ), Datatype( - { name: "SetpointRaiseLowerModeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.17" } }, + { name: "SetpointRaiseLowerModeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.20" } }, Field({ name: "Heat", id: 0x0, conformance: "HEAT", description: "Adjust Heat Setpoint" }), Field({ name: "Cool", id: 0x1, conformance: "COOL", description: "Adjust Cool Setpoint" }), Field({ name: "Both", id: 0x2, conformance: "HEAT | COOL", description: "Adjust Heat Setpoint and Cool Setpoint" }) @@ -1143,7 +1613,7 @@ export const Thermostat = Cluster( "the whole building must be in the same mode, SHOULD report CoolingOnly or HeatingOnly based on the " + "current capability.", - xref: { document: "cluster", section: "4.3.8.18" } + xref: { document: "cluster", section: "4.3.8.21" } }, Field({ name: "CoolingOnly", id: 0x0, conformance: "[COOL]", description: "Heat and Emergency are not possible" }), @@ -1167,13 +1637,65 @@ export const Thermostat = Cluster( ), Datatype( - { name: "SetpointChangeSourceEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.19" } }, + { name: "PresetScenarioEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.22" } }, + + Field({ + name: "Occupied", id: 0x1, conformance: "M", + description: "The thermostat-controlled area is occupied", + details: "This value shall indicate the preset for periods when the thermostat’s temperature-controlled area " + + "is occupied. It is intended for thermostats that can automatically determine occupancy.", + xref: { document: "cluster", section: "4.3.8.22.2" } + }), + + Field({ + name: "Unoccupied", id: 0x2, conformance: "M", + description: "The thermostat-controlled area is unoccupied", + details: "This value shall indicate the preset for periods when the thermostat’s temperature-controlled area " + + "is unoccupied. It is intended for thermostats that can automatically determine occupancy.", + xref: { document: "cluster", section: "4.3.8.22.3" } + }), + + Field({ + name: "Sleep", id: 0x3, conformance: "M", description: "Users are likely to be sleeping", + details: "This value shall indicate the preset for periods when users are likely to be asleep.", + xref: { document: "cluster", section: "4.3.8.22.4" } + }), + Field({ + name: "Wake", id: 0x4, conformance: "M", description: "Users are likely to be waking up", + details: "This value shall indicate the preset for periods when users are likely to be waking up.", + xref: { document: "cluster", section: "4.3.8.22.5" } + }), + + Field({ + name: "Vacation", id: 0x5, conformance: "M", description: "Users are on vacation", + details: "This value shall indicate the preset for periods when users are on vacation, or otherwise out-of- " + + "home for extended periods of time.", + xref: { document: "cluster", section: "4.3.8.22.6" } + }), + + Field({ + name: "GoingToSleep", id: 0x6, conformance: "M", + description: "Users are likely to be going to sleep", + details: "This value shall indicate the preset for periods when users are likely to be going to sleep.", + xref: { document: "cluster", section: "4.3.8.22.7" } + }), + + Field({ + name: "UserDefined", id: 0xfe, conformance: "M", description: "Custom presets", + details: "This value shall indicate a free-form preset; when set, the Name field on PresetStruct shall NOT be " + + "null.", + xref: { document: "cluster", section: "4.3.8.22.8" } + }) + ), + + Datatype( + { name: "SetpointChangeSourceEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.23" } }, Field({ name: "Manual", id: 0x0, conformance: "O", description: "Manual, user-initiated setpoint change via the thermostat" }), Field({ - name: "Schedule", id: 0x1, conformance: "[SCH]", + name: "Schedule", id: 0x1, conformance: "[SCH | MSCH]", description: "Schedule/internal programming-initiated setpoint change" }), Field({ @@ -1183,7 +1705,7 @@ export const Thermostat = Cluster( ), Datatype( - { name: "StartOfWeekEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.20" } }, + { name: "StartOfWeekEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.24" } }, Field({ name: "Sunday", id: 0x0, conformance: "M" }), Field({ name: "Monday", id: 0x1, conformance: "M" }), Field({ name: "Tuesday", id: 0x2, conformance: "M" }), @@ -1196,8 +1718,8 @@ export const Thermostat = Cluster( Datatype( { name: "SystemModeEnum", type: "enum8", - details: "Table 35. Interpretation of Heat, Cool and Auto SystemModeEnum Values", - xref: { document: "cluster", section: "4.3.8.21" } + details: "Table 9. Interpretation of Heat, Cool and Auto SystemModeEnum Values", + xref: { document: "cluster", section: "4.3.8.25" } }, Field({ name: "Off", id: 0x0, conformance: "O", @@ -1220,7 +1742,7 @@ export const Thermostat = Cluster( ), Datatype( - { name: "ThermostatRunningModeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.22" } }, + { name: "ThermostatRunningModeEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.26" } }, Field({ name: "Off", id: 0x0, conformance: "O", description: "The Thermostat does not generate demand for Cooling or Heating" @@ -1230,7 +1752,7 @@ export const Thermostat = Cluster( ), Datatype( - { name: "TemperatureSetpointHoldEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.23" } }, + { name: "TemperatureSetpointHoldEnum", type: "enum8", xref: { document: "cluster", section: "4.3.8.27" } }, Field({ name: "SetpointHoldOff", id: 0x0, conformance: "M", description: "Follow scheduling program" }), Field({ name: "SetpointHoldOn", id: 0x1, conformance: "M", @@ -1238,11 +1760,86 @@ export const Thermostat = Cluster( }) ), + Datatype( + { name: "PresetStruct", type: "struct", xref: { document: "cluster", section: "4.3.8.28" } }, + + Field({ + name: "PresetHandle", id: 0x0, type: "octstr", conformance: "M", constraint: "max 16", quality: "X", + + details: "This field shall indicate a device generated identifier for this preset. It shall be unique on the " + + "device, and shall NOT be reused after the associated preset has been deleted." + + "\n" + + "This field shall only be null when the encompassing PresetStruct is appended to the Presets " + + "attribute for the purpose of creating a new Preset. Refer to Presets for the creation of Preset " + + "handles.", + + xref: { document: "cluster", section: "4.3.8.28.1" } + }), + + Field({ + name: "PresetScenario", id: 0x1, type: "PresetScenarioEnum", conformance: "M", + details: "This field shall indicate the associated PresetScenarioEnum value for this preset.", + xref: { document: "cluster", section: "4.3.8.28.2" } + }), + + Field({ + name: "Name", id: 0x2, type: "string", conformance: "O", constraint: "max 64", default: null, + quality: "X", + details: "This field shall indicate a name provided by a user. The null value shall indicate no name." + + "\n" + + "Within each subset of presets sharing the same PresetScenario field value, there shall NOT be any " + + "presets with the same value, including null as a value, in the Name field.", + xref: { document: "cluster", section: "4.3.8.28.3" } + }), + + Field({ + name: "CoolingSetpoint", id: 0x3, type: "temperature", conformance: "COOL", constraint: "desc", + default: { type: "celsius", value: 26 }, + details: "This field shall indicate the cooling setpoint for the preset. Refer to Setpoint Limits for value " + + "constraints.", + xref: { document: "cluster", section: "4.3.8.28.4" } + }), + + Field({ + name: "HeatingSetpoint", id: 0x4, type: "temperature", conformance: "HEAT", constraint: "desc", + default: { type: "celsius", value: 20 }, + details: "This field shall indicate the heating setpoint for the preset. Refer to Setpoint Limits for value " + + "constraints.", + xref: { document: "cluster", section: "4.3.8.28.5" } + }), + + Field({ + name: "BuiltIn", id: 0x5, type: "bool", conformance: "M", default: false, quality: "X", + details: "This field shall indicate whether the preset is marked as \"built-in\", meaning that it can be " + + "modified, but it cannot be deleted.", + xref: { document: "cluster", section: "4.3.8.28.6" } + }) + ), + + Datatype( + { name: "PresetTypeStruct", type: "struct", xref: { document: "cluster", section: "4.3.8.29" } }, + Field({ + name: "PresetScenario", id: 0x0, type: "PresetScenarioEnum", conformance: "M", + details: "This field shall specify a PresetScenarioEnum value supported by this thermostat.", + xref: { document: "cluster", section: "4.3.8.29.1" } + }), + Field({ + name: "NumberOfPresets", id: 0x1, type: "uint8", conformance: "M", default: 0, + details: "This field shall specify a limit for the number of presets for this PresetScenarioEnum.", + xref: { document: "cluster", section: "4.3.8.29.2" } + }), + Field({ + name: "PresetTypeFeatures", id: 0x2, type: "PresetTypeFeaturesBitmap", conformance: "M", default: 0, + details: "This field shall specify a bitmap of features for this PresetTypeStruct.", + xref: { document: "cluster", section: "4.3.8.29.3" } + }) + ), + Datatype( { name: "WeeklyScheduleTransitionStruct", type: "struct", details: "This represents a single transition in a Thermostat schedule", - xref: { document: "cluster", section: "4.3.8.24" } + xref: { document: "cluster", section: "4.3.8.30" } }, Field({ @@ -1251,22 +1848,240 @@ export const Thermostat = Cluster( "time will be represented by a 16 bits unsigned integer to designate the minutes since midnight. For " + "example, 6am will be represented by 360 minutes since midnight and 11:30pm will be represented by " + "1410 minutes since midnight.", - xref: { document: "cluster", section: "4.3.8.24.1" } + xref: { document: "cluster", section: "4.3.8.30.1" } }), Field({ name: "HeatSetpoint", id: 0x1, type: "temperature", conformance: "M", quality: "X", details: "This field shall represent the heat setpoint to be applied at this associated transition start time.", - xref: { document: "cluster", section: "4.3.8.24.2" } + xref: { document: "cluster", section: "4.3.8.30.2" } }), Field({ name: "CoolSetpoint", id: 0x2, type: "temperature", conformance: "M", quality: "X", details: "This field shall represent the cool setpoint to be applied at this associated transition start time.", - xref: { document: "cluster", section: "4.3.8.24.3" } + xref: { document: "cluster", section: "4.3.8.30.3" } }) ), - Datatype({ name: "OccupancyBitmap", type: "OccupancySensing.OccupancyBitmap" }) + Datatype( + { name: "ScheduleStruct", type: "struct", xref: { document: "cluster", section: "4.3.8.31" } }, + + Field({ + name: "ScheduleHandle", id: 0x0, type: "octstr", conformance: "M", constraint: "max 16", + quality: "X", + + details: "This field shall indicate a device generated identifier for this schedule. It shall be unique on " + + "the device, and shall NOT be reused after the associated schedule has been deleted." + + "\n" + + "This field shall only be null when the encompassing ScheduleStruct is appended to the Schedules " + + "attribute for the purpose of creating a new Schedule. Refer to Schedules for the creation of " + + "Schedule handles.", + + xref: { document: "cluster", section: "4.3.8.31.1" } + }), + + Field({ + name: "SystemMode", id: 0x1, type: "SystemModeEnum", conformance: "M", constraint: "desc", + details: "This field shall specify the default thermostat system mode for transitions in this schedule. The " + + "only valid values for this field shall be Auto, Heat, and Cool.", + xref: { document: "cluster", section: "4.3.8.31.2" } + }), + + Field({ + name: "Name", id: 0x2, type: "string", conformance: "O", constraint: "max 64", + details: "This field shall specify a name for the ScheduleStruct.", + xref: { document: "cluster", section: "4.3.8.31.3" } + }), + Field({ + name: "PresetHandle", id: 0x3, type: "octstr", conformance: "O", constraint: "max 16", + details: "This field shall indicate the default PresetHandle value for transitions in this schedule.", + xref: { document: "cluster", section: "4.3.8.31.4" } + }), + + Field( + { + name: "Transitions", id: 0x4, type: "list", conformance: "M", + constraint: "1 to numberOfScheduleTransitions", default: [], + + details: "This field shall specify a list of transitions for the schedule." + + "\n" + + "This field shall NOT contain more than one ScheduleStruct with the same TransitionTime field and " + + "overlapping DayOfWeek fields; i.e. there shall be no duplicate transitions." + + "\n" + + "If the NumberOfScheduleTransitionsPerDay attribute is not null, then for each bit in " + + "ScheduleDayOfWeekBitmap, the number of transitions with that bit set in DayOfWeek shall NOT be " + + "greater than the value of the NumberOfScheduleTransitionsPerDay attribute." + + "\n" + + "For the purposes of determining which ScheduleStruct in this list is currently active, the current " + + "time shall be the number of minutes past midnight in the display value of the current time, not the " + + "actual number of minutes that have elapsed since midnight. On days which transition into or out of " + + "daylight saving time, certain values may repeat or not occur during the transition period." + + "\n" + + "A ScheduleTransitionStruct in this list shall be active if the current day of the week matches its " + + "DayOfWeek field and the current time is greater than or equal to the TransitionTime, but less than " + + "the TransitionTime on any other ScheduleTransitionStruct in the Transitions field whose DayOfWeek " + + "field also matches the current day of the week." + + "\n" + + "If the current time is less than every ScheduleTransitionStruct whose DayOfWeek field also matches " + + "the current day of the week, the server shall attempt the same process to identify the active " + + "ScheduleTransitionStruct for the day preceding the previously attempted day of the week, repeating " + + "until an active ScheduleTransitionStruct is found or the attempted day is the current day of the " + + "week again. If no active ScheduleTransitionStruct is found, then the active " + + "ScheduleTransitionStruct shall be the ScheduleTransitionStruct with the largest TransitionTime " + + "field from the set of ScheduleTransitionStructs whose DayOfWeek field matches the current day of " + + "the week.", + + xref: { document: "cluster", section: "4.3.8.31.5" } + }, + + Field({ name: "entry", type: "ScheduleTransitionStruct" }) + ), + + Field({ + name: "BuiltIn", id: 0x5, type: "bool", conformance: "M", default: false, quality: "X", + details: "This field shall indicate whether the schedule is marked as \"built-in\", meaning that it can be " + + "modified, but it cannot be deleted.", + xref: { document: "cluster", section: "4.3.8.31.6" } + }) + ), + + Datatype( + { + name: "ScheduleTransitionStruct", type: "struct", + + details: "This struct provides a time of day and a set of days of the week for a state transition within a " + + "schedule. The thermostat shall use the following order of precedence for determining a new setpoint " + + "at the time of transition:" + + "\n" + + " 1. If the PresetHandle field is provided, then the setpoint for the PresetStruct in the Presets " + + " attribute with that identifier shall be used" + + "\n" + + " 2. If either the HeatingSetpoint or CoolingSetpoint is provided, then it shall be used" + + "\n" + + " a. If the SystemMode field is provided, the HeatingSetpoint and CoolingSetpoint fields shall be " + + " interpreted using the SystemMode field" + + "\n" + + " b. If the SystemMode field is not provided, the HeatingSetpoint and CoolingSetpoint fields " + + " shall be interpreted using the SystemMode field on the parent ScheduleStruct" + + "\n" + + " 3. If neither the PresetHandle field or any Setpoint field is provided, then the PresetHandle " + + " field on the parent ScheduleStruct shall be used to determine the active PresetStruct" + + "\n" + + " 4. If the PresetHandle is not indicated and no setpoint is provided for the current SystemMode, " + + " the server shall use a default value for the current SystemMode." + + "\n" + + "If the setpoint was derived from a preset, then the ActivePresetHandle shall be set to the " + + "PresetHandle of that preset." + + "\n" + + "If a CoolingSetpoint was used to determine the cooling setpoint:" + + "\n" + + " • If the server supports the OCC feature, and the Occupied bit is not set on the Occupancy " + + " attribute, then the UnoccupiedCoolingSetpoint attribute shall be set to the CoolingSetpoint" + + "\n" + + " • Otherwise, the OccupiedCoolingSetpoint attribute shall be set to the CoolingSetpoint If a " + + " HeatingSetpoint was used to determine the heating setpoint:" + + "\n" + + " • If the server supports the OCC feature, and the Occupied bit is not set on the Occupancy " + + " attribute, then the UnoccupiedHeatingSetpoint attribute shall be set to the HeatingSetpoint" + + "\n" + + " • Otherwise, the OccupiedHeatingSetpoint attribute shall be set to the HeatingSetpoint The " + + " ScheduleTransitionStruct shall be invalid if all the following are true:" + + "\n" + + " • The HeatingSetpoint field is not provided" + + "\n" + + " • The PresetHandle field is not provided" + + "\n" + + " • The PresetHandle field on the encompassing ScheduleStruct is not provided" + + "\n" + + " • The SystemMode field is provided and has the value Heat or Auto, or the SystemMode field on the " + + " parent ScheduleStruct has the value Heat or Auto" + + "\n" + + "The ScheduleTransitionStruct shall be invalid if all the following are true:" + + "\n" + + " • The CoolingSetpoint field is not provided" + + "\n" + + " • The PresetHandle field is not provided" + + "\n" + + " • The PresetHandle field on the encompassing ScheduleStruct is not provided" + + "\n" + + " • The SystemMode field is provided and has the value Cool or Auto, or the SystemMode field on the " + + " parent ScheduleStruct has the value Cool or Auto", + + xref: { document: "cluster", section: "4.3.8.32" } + }, + + Field({ + name: "DayOfWeek", id: 0x0, type: "ScheduleDayOfWeekBitmap", conformance: "M", constraint: "desc", + details: "This field shall specify a bitmask of days of the week that the transition applies to. The Vacation " + + "bit shall NOT be set; vacation schedules shall be set via the vacation preset.", + xref: { document: "cluster", section: "4.3.8.32.1" } + }), + + Field({ + name: "TransitionTime", id: 0x1, type: "uint16", conformance: "M", constraint: "max 1439", + details: "This shall specify the time of day at which the transition becomes active, in terms of minutes " + + "within the day representing the wall clock, where 0 is 00:00:00, 1 is 00:01:00 and 1439 is 23:59:00." + + "\n" + + "Handling of transitions during the changeover of Daylight Saving Time is implementation-dependent.", + xref: { document: "cluster", section: "4.3.8.32.2" } + }), + + Field({ + name: "PresetHandle", id: 0x2, type: "octstr", conformance: "[PRES]", constraint: "max 16", + details: "This field shall specify the preset used at the TransitionTime. If this field is provided, then the " + + "SystemMode, CoolingSetpoint and HeatingSetpoint fields shall NOT be provided.", + xref: { document: "cluster", section: "4.3.8.32.3" } + }), + + Field({ + name: "SystemMode", id: 0x3, type: "SystemModeEnum", conformance: "O", constraint: "desc", + details: "This shall specify the default mode to which the thermostat will switch for this transition, " + + "overriding the default for the schedule. The only valid values for this field shall be Auto, Heat, " + + "Cool and Off. This field shall only be included when the required system mode differs from the " + + "schedule’s default SystemMode.", + xref: { document: "cluster", section: "4.3.8.32.4" } + }), + + Field({ + name: "CoolingSetpoint", id: 0x4, type: "temperature", conformance: "[COOL]", constraint: "desc", + details: "This field shall specify the cooling setpoint for the transition. If PresetHandle is set, this " + + "field shall NOT be included. Refer to Setpoint Limits for value constraints.", + xref: { document: "cluster", section: "4.3.8.32.5" } + }), + + Field({ + name: "HeatingSetpoint", id: 0x5, type: "temperature", conformance: "[HEAT]", constraint: "desc", + details: "This field shall specify the cooling setpoint for the transition. If PresetHandle is set, this " + + "field shall NOT be included. Refer to Setpoint Limits for value constraints.", + xref: { document: "cluster", section: "4.3.8.32.6" } + }) + ), + + Datatype( + { name: "ScheduleTypeStruct", type: "struct", xref: { document: "cluster", section: "4.3.8.33" } }, + + Field({ + name: "SystemMode", id: 0x0, type: "SystemModeEnum", conformance: "M", constraint: "desc", + details: "This field shall specify a SystemModeEnum supported by this thermostat for Schedules. The only " + + "valid values for this field shall be Auto, Heat, and Cool.", + xref: { document: "cluster", section: "4.3.8.33.1" } + }), + + Field({ + name: "NumberOfSchedules", id: 0x1, type: "uint8", conformance: "M", + constraint: "max numberOfSchedules", default: 0, + details: "This field shall specify a limit for the number of Schedules for this SystemMode.", + xref: { document: "cluster", section: "4.3.8.33.2" } + }), + + Field({ + name: "ScheduleTypeFeatures", id: 0x2, type: "ScheduleTypeFeaturesBitmap", conformance: "M", + constraint: "desc", default: 0, + details: "This field shall specify a bitmap of features for this schedule entry. At least one of " + + "SupportsPresets and SupportsSetpoints shall be set.", + xref: { document: "cluster", section: "4.3.8.33.3" } + }) + ) ); MatterDefinition.children.push(Thermostat); diff --git a/packages/model/src/standard/elements/ThermostatDT.ts b/packages/model/src/standard/elements/ThermostatDT.ts index 1f51fb1e52..0fbde00b0f 100644 --- a/packages/model/src/standard/elements/ThermostatDT.ts +++ b/packages/model/src/standard/elements/ThermostatDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,7 @@ export const ThermostatDt = DeviceType( Requirement( { name: "Descriptor", id: 0x1d, element: "serverCluster" }, - Requirement({ name: "DeviceTypeList", default: [ { deviceType: 769, revision: 3 } ], element: "attribute" }) + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 769, revision: 4 } ], element: "attribute" }) ), Requirement({ name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", @@ -32,40 +32,36 @@ export const ThermostatDt = DeviceType( name: "Groups", id: 0x4, conformance: "Active", element: "serverCluster", xref: { document: "device", section: "9.1.4" } }), - Requirement({ - name: "Thermostat", id: 0x201, conformance: "M", element: "serverCluster", - xref: { document: "device", section: "9.1.4" } - }), - Requirement({ - name: "ScenesManagement", id: 0x62, conformance: "P, O", element: "serverCluster", - xref: { document: "device", section: "9.1.4" } - }), + + Requirement( + { + name: "Thermostat", id: 0x201, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "9.1.4" } + }, + Requirement({ name: "SCHEDULECONFIGURATION", conformance: "X", element: "feature" }), + Requirement({ name: "AlarmMask", conformance: "X", element: "attribute" }), + Requirement({ name: "GetRelayStatusLog", conformance: "X", element: "command" }), + Requirement({ name: "GetRelayStatusLogResponse", conformance: "X", element: "command" }) + ), + Requirement({ name: "ThermostatUserInterfaceConfiguration", id: 0x204, conformance: "O", element: "serverCluster", xref: { document: "device", section: "9.1.4" } }), Requirement({ - name: "EnergyPreference", id: 0x9b, conformance: "P, O", element: "serverCluster", - xref: { document: "device", section: "9.1.4" } - }), - Requirement({ - name: "RelativeHumidityMeasurement", id: 0x405, conformance: "O", element: "clientCluster", - xref: { document: "device", section: "9.1.4" } - }), - Requirement({ - name: "TimeSynchronization", id: 0x38, conformance: "O", element: "serverCluster", + name: "EnergyPreference", id: 0x9b, conformance: "O", element: "serverCluster", xref: { document: "device", section: "9.1.4" } }), Requirement({ - name: "TimeSynchronization", id: 0x38, conformance: "O", element: "clientCluster", + name: "FanControl", id: 0x202, conformance: "O", element: "clientCluster", xref: { document: "device", section: "9.1.4" } }), Requirement({ - name: "FanControl", id: 0x202, conformance: "O", element: "clientCluster", + name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "clientCluster", xref: { document: "device", section: "9.1.4" } }), Requirement({ - name: "TemperatureMeasurement", id: 0x402, conformance: "O", element: "clientCluster", + name: "RelativeHumidityMeasurement", id: 0x405, conformance: "O", element: "clientCluster", xref: { document: "device", section: "9.1.4" } }), Requirement({ diff --git a/packages/model/src/standard/elements/ThermostatUserInterfaceConfiguration.ts b/packages/model/src/standard/elements/ThermostatUserInterfaceConfiguration.ts index 71ed4303e2..7291950d8b 100644 --- a/packages/model/src/standard/elements/ThermostatUserInterfaceConfiguration.ts +++ b/packages/model/src/standard/elements/ThermostatUserInterfaceConfiguration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -27,21 +27,21 @@ export const ThermostatUserInterfaceConfiguration = Cluster( Attribute({ name: "TemperatureDisplayMode", id: 0x0, type: "TemperatureDisplayModeEnum", access: "RW VO", - conformance: "M", constraint: "desc", default: 0, + conformance: "M", default: 0, details: "Indicates the units of the temperature displayed on the thermostat screen.", xref: { document: "cluster", section: "4.5.6.1" } }), Attribute({ name: "KeypadLockout", id: 0x1, type: "KeypadLockoutEnum", access: "RW VM", conformance: "M", - constraint: "desc", default: 0, + default: 0, details: "Indicates the level of functionality that is available to the user via the keypad.", xref: { document: "cluster", section: "4.5.6.2" } }), Attribute({ name: "ScheduleProgrammingVisibility", id: 0x2, type: "ScheduleProgrammingVisibilityEnum", - access: "RW VM", conformance: "O", constraint: "desc", default: 0, + access: "RW VM", conformance: "O", default: 0, details: "This attribute is used to hide the weekly schedule programming functionality or menu on a " + "thermostat from a user to prevent local user programming of the weekly schedule. The schedule " + diff --git a/packages/model/src/standard/elements/ThreadBorderRouterManagement.ts b/packages/model/src/standard/elements/ThreadBorderRouterManagement.ts new file mode 100644 index 0000000000..f3bd74cc36 --- /dev/null +++ b/packages/model/src/standard/elements/ThreadBorderRouterManagement.ts @@ -0,0 +1,207 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + FieldElement as Field, + CommandElement as Command +} from "../../elements/index.js"; + +export const ThreadBorderRouterManagement = Cluster( + { + name: "ThreadBorderRouterManagement", id: 0x452, classification: "application", pics: "TBRM", + details: "This cluster provides an interface for managing a Thread Border Router and the Thread network that " + + "it belongs to. Privileged nodes within the same fabric as a Thread Border Router can use these " + + "interfaces to request and set credentials information to the Thread network.", + xref: { document: "cluster", section: "10.3" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "10.3.4" } }, + + Field({ + name: "PC", conformance: "O", constraint: "0", description: "PanChange", + + details: "This feature shall indicate the ability of the Border Router to change its already configured PAN " + + "to another, by setting a pending dataset." + + "\n" + + "NOTE" + + "\n" + + "This feature flag can be used to protect an already-configured network from accidental " + + "configuration change, e.g. when the Thread Border Router serves non-Matter devices that do not " + + "support PAN change for an implementation-specific reason.", + + xref: { document: "cluster", section: "10.3.4.1" } + }) + ), + + Attribute({ + name: "BorderRouterName", id: 0x0, type: "string", access: "R V", conformance: "M", + constraint: "1 to 63", + details: "Indicates a user-friendly name identifying the device model or product of the Border Router in " + + "MeshCOP (DNS-SD service name) as defined in the Thread specification, and has the following " + + "recommended format: ._meshcop._udp. An example name would be ACME Border " + + "Router (74be)._meshcop._udp.", + xref: { document: "cluster", section: "10.3.5.1" } + }), + + Attribute({ + name: "BorderAgentId", id: 0x1, type: "octstr", access: "R V", conformance: "M", constraint: "16", + details: "Indicates a 16-byte globally unique ID for a Thread Border Router device. This ID is " + + "manufacturer-specific, and it is created and managed by the border router’s implementation.", + xref: { document: "cluster", section: "10.3.5.2" } + }), + + Attribute({ + name: "ThreadVersion", id: 0x2, type: "uint16", access: "R V", conformance: "M", quality: "F", + details: "Indicates the Thread version supported by the Thread interface configured by the cluster instance." + + "\n" + + "The format shall match the value mapping defined in the \"Version TLV\" section of the Thread " + + "specification. For example, Thread 1.3.0 would have ThreadVersion set to 4.", + xref: { document: "cluster", section: "10.3.5.3" } + }), + + Attribute({ + name: "InterfaceEnabled", id: 0x3, type: "bool", access: "R V", conformance: "M", default: false, + quality: "N", + details: "Indicates whether the associated IEEE 802.15.4 Thread interface is enabled or disabled.", + xref: { document: "cluster", section: "10.3.5.4" } + }), + + Attribute({ + name: "ActiveDatasetTimestamp", id: 0x4, type: "uint64", access: "R V", conformance: "M", + default: 0, quality: "X N", + details: "Null if the Thread Border Router has no dataset configured, otherwise it shall be the timestamp " + + "value extracted from the Active Dataset value configured by the Thread Node to which the border " + + "router is connected. This attribute shall be updated when a new Active dataset is configured on the " + + "Thread network to which the border router is connected.", + xref: { document: "cluster", section: "10.3.5.5" } + }), + + Attribute({ + name: "PendingDatasetTimestamp", id: 0x5, type: "uint64", access: "R V", conformance: "M", + default: 0, quality: "X N", + details: "Null if the Thread Border Router has no Pending dataset configured, otherwise it shall be the " + + "timestamp value extracted from the Pending Dataset value configured by the Thread Node to which the " + + "border router is connected. This attribute shall be updated when a new Pending dataset is " + + "configured on the Thread network to which the border router is connected.", + xref: { document: "cluster", section: "10.3.5.6" } + }), + + Command({ + name: "GetActiveDatasetRequest", id: 0x0, access: "M", conformance: "M", direction: "request", + response: "DatasetResponse", + + details: "This command shall be used to request the active operational dataset of the Thread network to which " + + "the border router is connected." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "If an internal error occurs, then this command shall fail with a FAILURE status code sent back to " + + "the initiator." + + "\n" + + "Otherwise, this shall generate a DatasetResponse command.", + + xref: { document: "cluster", section: "10.3.6.1" } + }), + + Command({ + name: "GetPendingDatasetRequest", id: 0x1, access: "M", conformance: "M", direction: "request", + response: "DatasetResponse", + + details: "This command shall be used to request the pending dataset of the Thread network to which the border " + + "router is connected." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "If an internal error occurs, then this command shall fail with a FAILURE status code sent back to " + + "the initiator." + + "\n" + + "Otherwise, this shall generate a DatasetResponse command.", + + xref: { document: "cluster", section: "10.3.6.2" } + }), + + Command( + { + name: "DatasetResponse", id: 0x2, conformance: "M", direction: "response", + details: "This command is sent in response to GetActiveDatasetRequest or GetPendingDatasetRequest command.", + xref: { document: "cluster", section: "10.3.6.3" } + }, + + Field({ + name: "Dataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254", + details: "If no dataset (active or pending as requested) is configured, this field shall be set to empty." + + "\n" + + "Otherwise, this field shall contain the active or pending dataset of the Thread network to which " + + "the Border Router is connected as an octet string containing the raw Thread TLV value of the " + + "dataset, as defined in the Thread specification.", + xref: { document: "cluster", section: "10.3.6.3.1" } + }) + ), + + Command( + { + name: "SetActiveDatasetRequest", id: 0x3, access: "M T", conformance: "M", direction: "request", + response: "status", + details: "This command shall be used to set the active Dataset of the Thread network to which the Border " + + "Router is connected, when there is no active dataset already.", + xref: { document: "cluster", section: "10.3.6.4" } + }, + + Field({ + name: "ActiveDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254", + details: "This field shall contain the active dataset to set of the Thread network to configure in the Border " + + "Router as an octet string containing the raw Thread TLV value of the dataset, as defined in the " + + "Thread specification.", + xref: { document: "cluster", section: "10.3.6.4.1" } + }), + + Field({ + name: "Breadcrumb", id: 0x1, type: "uint64", conformance: "O", + details: "See Breadcrumb Attribute section of General Commissioning Cluster in [MatterCore] for usage.", + xref: { document: "cluster", section: "10.3.6.4.2" } + }) + ), + + Command( + { + name: "SetPendingDatasetRequest", id: 0x4, access: "M T", conformance: "PC", direction: "request", + response: "status", + + details: "This command shall be used to set or update the pending Dataset of the Thread network to which the " + + "Border Router is connected, if the Border Router supports PAN Change." + + "\n" + + "If the command is not executed via a CASE session, the command shall fail with a status code of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "This PendingDataset field shall contain the pending dataset to which the Thread network should be " + + "updated. The format of the data shall be an octet string containing the raw Thread TLV value of the " + + "pending dataset, as defined in the Thread specification." + + "\n" + + "If any of the parameters in the PendingDataset is invalid, the command shall fail with a status of " + + "INVALID_COMMAND." + + "\n" + + "Otherwise, this command shall configure the pending dataset of the Thread network to which the " + + "Border Router is connected, with the value given in the PendingDataset parameter. The Border Router " + + "will manage activation of the pending dataset as defined in the Thread specification.", + + xref: { document: "cluster", section: "10.3.6.5" } + }, + + Field({ name: "PendingDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254" }) + ) +); + +MatterDefinition.children.push(ThreadBorderRouterManagement); diff --git a/packages/model/src/standard/elements/ThreadNetworkDiagnostics.ts b/packages/model/src/standard/elements/ThreadNetworkDiagnostics.ts index 8f02499c73..79f2ddba7b 100644 --- a/packages/model/src/standard/elements/ThreadNetworkDiagnostics.ts +++ b/packages/model/src/standard/elements/ThreadNetworkDiagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -26,7 +26,7 @@ export const ThreadNetworkDiagnostics = Cluster( xref: { document: "core", section: "11.14" } }, - Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 3 }), Attribute( { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "core", section: "11.14.4" } }, @@ -62,8 +62,9 @@ export const ThreadNetworkDiagnostics = Cluster( name: "RoutingRole", id: 0x1, type: "RoutingRoleEnum", access: "R V", conformance: "M", quality: "X", details: "The RoutingRole attribute shall indicate the role that this Node has within the routing of messages " + - "through the Thread network, as defined by RoutingRoleEnum. The potential roles are defined in the " + - "following table. A value of null shall indicate that the Thread interface is not currently " + + "through the Thread network, as defined by RoutingRoleEnum. The potential roles are defined" + + "\n" + + "in the following table. A value of null shall indicate that the Thread interface is not currently " + "configured or operational.", xref: { document: "core", section: "11.14.6.2" } }), @@ -157,8 +158,7 @@ export const ThreadNetworkDiagnostics = Cluster( Attribute({ name: "StableDataVersion", id: 0xc, type: "uint16", access: "R V", conformance: "M", constraint: "max 255", quality: "X", - details: "The StableDataVersion attribute shall indicate the Network Data Version for the stable subset of" + - "\n" + + details: "The StableDataVersion attribute shall indicate the Network Data Version for the stable subset of " + "data the Node currently uses. Null if not attached to a Thread network.", xref: { document: "core", section: "11.14.6.13" } }), @@ -297,7 +297,8 @@ export const ThreadNetworkDiagnostics = Cluster( Attribute({ name: "TxNoAckRequestedCount", id: 0x1b, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, quality: "C", - details: "The TxNoAckRequestedCount attribute shall indicate the total number of unique MAC frame " + + details: "The TxNoAckRequestedCount attribute shall indicate the total number of unique MAC frame" + + "\n" + "transmission requests without requested acknowledgment. The TxNoAckRequestedCount attribute shall " + "only be incremented by 1 for each MAC transmission request that is does not request acknowledgement " + "regardless of the amount of CCA failures, CSMA-CA attempts, or retransmissions.", @@ -366,11 +367,14 @@ export const ThreadNetworkDiagnostics = Cluster( Attribute({ name: "TxDirectMaxRetryExpiryCount", id: 0x22, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, quality: "C", - details: "The TxDirectMaxRetryExpiryCount attribute shall indicate the total number of unique MAC " + + + details: "The TxDirectMaxRetryExpiryCount attribute shall indicate the total number of unique MAC" + + "\n" + "transmission packets that meet maximal retry limit for direct packets. The " + "TxDirectMaxRetryExpiryCount attribute shall only be incremented by 1 for each unique MAC " + "transmission packets that meets the maximal retry limit for direct packets. This value shall only " + "be reset upon a Node reboot.", + xref: { document: "core", section: "11.14.6.35" } }), @@ -440,8 +444,9 @@ export const ThreadNetworkDiagnostics = Cluster( Attribute({ name: "RxDataCount", id: 0x2a, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, quality: "C", - details: "The RxDataCount attribute shall indicate the total number of received unique MAC Data frames. This " + - "value shall only be reset upon a Node reboot.", + details: "The RxDataCount attribute shall indicate the total number of received unique MAC Data frames." + + "\n" + + "This value shall only be reset upon a Node reboot.", xref: { document: "core", section: "11.14.6.43" } }), @@ -517,8 +522,9 @@ export const ThreadNetworkDiagnostics = Cluster( name: "RxErrUnknownNeighborCount", id: 0x33, type: "uint32", access: "R V", conformance: "[MACCNT]", default: 0, quality: "C", details: "The RxErrUnknownNeighborCount attribute shall indicate the total number of received unique MAC " + - "frame requests that have been dropped as a result of originating from an unknown neighbor device. " + - "This value shall only be reset upon a Node reboot.", + "frame requests that have been dropped as a result of originating from an unknown neighbor" + + "\n" + + "device. This value shall only be reset upon a Node reboot.", xref: { document: "core", section: "11.14.6.52" } }), @@ -614,6 +620,15 @@ export const ThreadNetworkDiagnostics = Cluster( Field({ name: "entry", type: "NetworkFaultEnum" }) ), + Attribute({ + name: "ExtAddress", id: 0x3f, type: "uint64", access: "R V", conformance: "P, M", quality: "X", + xref: { document: "core", section: "11.14.6" } + }), + Attribute({ + name: "Rloc16", id: 0x40, type: "uint16", access: "R V", conformance: "P, M", quality: "X", + xref: { document: "core", section: "11.14.6" } + }), + Event( { name: "ConnectionStatus", id: 0x0, access: "V", conformance: "O", priority: "info", @@ -876,9 +891,8 @@ export const ThreadNetworkDiagnostics = Cluster( Field({ name: "LinkEstablished", id: 0x9, type: "bool", conformance: "M", - details: "This field shall specify if a link has been established to the Node for which this route table entry" + - "\n" + - "corresponds.", + details: "This field shall specify if a link has been established to the Node for which this route table " + + "entry corresponds.", xref: { document: "core", section: "11.14.5.5.10" } }) ), diff --git a/packages/model/src/standard/elements/ThreadNetworkDirectory.ts b/packages/model/src/standard/elements/ThreadNetworkDirectory.ts new file mode 100644 index 0000000000..1544273811 --- /dev/null +++ b/packages/model/src/standard/elements/ThreadNetworkDirectory.ts @@ -0,0 +1,175 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + FieldElement as Field, + CommandElement as Command, + DatatypeElement as Datatype +} from "../../elements/index.js"; + +export const ThreadNetworkDirectory = Cluster( + { + name: "ThreadNetworkDirectory", id: 0x453, classification: "application", pics: "THNETDIR", + details: "This cluster stores a list of Thread networks (including the credentials required to access each " + + "network), as well as a designation of the user’s preferred network, to facilitate the sharing of " + + "Thread networks across fabrics.", + xref: { document: "cluster", section: "10.4" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "PreferredExtendedPanId", id: 0x0, type: "octstr", access: "RW VM", conformance: "M", + constraint: "8", default: null, quality: "X N", + + details: "Indicates the Thread Extended PAN ID value for the Thread network designated by the user to be " + + "their preferred network for commissioning of Thread devices. If not null, the value of this " + + "attribute shall match the ExtendedPanID of a network in the ThreadNetworks attribute. A write " + + "operation with a non-null value that does not match any network in the ThreadNetworks list shall be " + + "rejected with a status of CONSTRAINT_ERROR." + + "\n" + + "The purpose of designating one Thread network as preferred is to help a commissioner to select a " + + "Thread network when a Thread device is within suitable range of more than one Thread network which " + + "appears in the ThreadNetworks list. A value of null indicates that there is no current preferred " + + "network: All networks may be treated as equally preferred by a commissioner with access to this " + + "cluster." + + "\n" + + "This attribute may be automatically set to the ExtendedPanID of the first Thread network added to " + + "the ThreadNetworks list." + + "\n" + + "A client shall obtain user consent before changing the value of this attribute from a non-null " + + "value." + + "\n" + + "On a factory reset this attribute shall be reset to null.", + + xref: { document: "cluster", section: "10.4.5.1" } + }), + + Attribute( + { + name: "ThreadNetworks", id: 0x1, type: "list", access: "R V", conformance: "M", + constraint: "max threadNetworkTableSize", quality: "N", + + details: "Indicates the list of Thread Networks known about by this cluster. If the node hosting this cluster " + + "includes a Thread Border Router, then an entry for its Thread Network shall be included in this " + + "list." + + "\n" + + "The list can be modified via the AddNetwork and RemoveNetwork commands." + + "\n" + + "For each entry in the list, the cluster server also stores a Thread Operational Dataset. Clients " + + "use the GetOperationalDataset command to obtain the Operational Dataset for an entry in this list." + + "\n" + + "On a factory reset this list shall be cleared, and any Thread Operational datasets previously " + + "stored shall be removed from the Node.", + + xref: { document: "cluster", section: "10.4.5.2" } + }, + + Field({ name: "entry", type: "ThreadNetworkStruct" }) + ), + + Attribute({ + name: "ThreadNetworkTableSize", id: 0x2, type: "uint8", access: "R V", conformance: "M", + constraint: "desc", default: 10, quality: "F", + details: "Indicates the maximum number of entries that can be held in the ThreadNetworks list; it shall be at " + + "least 2 times the number of SupportedFabrics advertised in the Operational Credentials Cluster on " + + "the root endpoint of this node.", + xref: { document: "cluster", section: "10.4.5.3" } + }), + + Command( + { + name: "AddNetwork", id: 0x0, access: "M T", conformance: "M", direction: "request", + response: "status", + details: "Adds an entry to the ThreadNetworks attribute with the specified Thread Operational Dataset." + + "\n" + + "If there is an existing entry with the Extended PAN ID then the Thread Operational Dataset for that " + + "entry is replaced. As a result, changes to the network parameters (e.g. Channel, Network Name, " + + "PSKc, …) of an existing entry with a given Extended PAN ID can be made using this command.", + xref: { document: "cluster", section: "10.4.6.1" } + }, + + Field({ + name: "OperationalDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254", + details: "This field shall represent the Operational Dataset for the network, using the encoding defined in " + + "the Thread specification. It shall contain at least the following sub-TLVs: Active Timestamp, " + + "Channel, Channel Mask, Extended PAN ID, Network Key, Network Mesh-Local Prefix, Network Name, PAN " + + "ID, PSKc, and Security Policy.", + xref: { document: "cluster", section: "10.4.6.1.1" } + }) + ), + + Command( + { + name: "RemoveNetwork", id: 0x1, access: "M T", conformance: "M", direction: "request", + response: "status", + details: "Removes the network with the given Extended PAN ID from the ThreadNetworks attribute.", + xref: { document: "cluster", section: "10.4.6.2" } + }, + + Field({ name: "ExtendedPanId", id: 0x0, type: "octstr", conformance: "M", constraint: "8" }) + ), + + Command( + { + name: "GetOperationalDataset", id: 0x2, access: "M", conformance: "M", direction: "request", + response: "OperationalDatasetResponse", + details: "Retrieves the Thread Operational Dataset with the given Extended PAN ID.", + xref: { document: "cluster", section: "10.4.6.3" } + }, + + Field({ name: "ExtendedPanId", id: 0x0, type: "octstr", conformance: "M", constraint: "8" }) + ), + + Command( + { + name: "OperationalDatasetResponse", id: 0x3, conformance: "M", direction: "response", + details: "Contains the Thread Operational Dataset for the Extended PAN specified in GetOperationalDataset.", + xref: { document: "cluster", section: "10.4.6.4" } + }, + Field({ name: "OperationalDataset", id: 0x0, type: "octstr", conformance: "M", constraint: "max 254" }) + ), + + Datatype( + { + name: "ThreadNetworkStruct", type: "struct", + details: "Represents the data associated with a Thread Network.", + xref: { document: "cluster", section: "10.4.4.1" } + }, + + Field({ + name: "ExtendedPanId", id: 0x0, type: "octstr", conformance: "M", constraint: "8", + details: "This field shall indicate the Extended PAN ID from the OperationalDataset for the given Thread " + + "network.", + xref: { document: "cluster", section: "10.4.4.1.1" } + }), + + Field({ + name: "NetworkName", id: 0x1, type: "string", conformance: "M", constraint: "1 to 16", + details: "This field shall indicate the Network Name from the OperationalDataset for the given Thread network.", + xref: { document: "cluster", section: "10.4.4.1.2" } + }), + Field({ + name: "Channel", id: 0x2, type: "uint16", conformance: "M", + details: "This field shall indicate the Channel from the OperationalDataset for the given Thread network.", + xref: { document: "cluster", section: "10.4.4.1.3" } + }), + + Field({ + name: "ActiveTimestamp", id: 0x3, type: "uint64", conformance: "M", + details: "This field shall indicate the Active Timestamp from the OperationalDataset for the given Thread " + + "network.", + xref: { document: "cluster", section: "10.4.4.1.4" } + }) + ) +); + +MatterDefinition.children.push(ThreadNetworkDirectory); diff --git a/packages/model/src/standard/elements/TimeFormatLocalization.ts b/packages/model/src/standard/elements/TimeFormatLocalization.ts index 9ca1b7975d..21c8105053 100644 --- a/packages/model/src/standard/elements/TimeFormatLocalization.ts +++ b/packages/model/src/standard/elements/TimeFormatLocalization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -58,7 +58,7 @@ export const TimeFormatLocalization = Cluster( Attribute({ name: "ActiveCalendarType", id: 0x1, type: "CalendarTypeEnum", access: "RW VM", - conformance: "CALFMT", constraint: "in supportedCalendarTypes", quality: "N", + conformance: "CALFMT", constraint: "in SupportedCalendarTypes", quality: "N", details: "Indicates the calendar format that the Node is currently configured to use when conveying dates." + "\n" + diff --git a/packages/model/src/standard/elements/TimeSynchronization.ts b/packages/model/src/standard/elements/TimeSynchronization.ts index 1f5d6474c4..faa96c6266 100644 --- a/packages/model/src/standard/elements/TimeSynchronization.ts +++ b/packages/model/src/standard/elements/TimeSynchronization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -112,9 +112,9 @@ export const TimeSynchronization = Cluster( name: "TrustedTimeSource", id: 0x3, type: "TrustedTimeSourceStruct", access: "R V", conformance: "TSC", default: null, quality: "X N", details: "A Node ID, endpoint, and associated fabric index of a Node that may be used as trusted time source. " + - "See Time source prioritization. This attribute reflects the last value set by an administrator " + - "using the SetTrustedTimeSource command. If the value is null, no trusted time source has yet been " + - "set.", + "See Section 11.17.13, “Time source prioritization”. This attribute reflects the last value set by " + + "an administrator using the SetTrustedTimeSource command. If the value is null, no trusted time " + + "source has yet been set.", xref: { document: "core", section: "11.17.8.4" } }), @@ -146,9 +146,7 @@ export const TimeSynchronization = Cluster( "daylight savings time)." + "\n" + "The first entry shall have a ValidAt entry of 0. If there is a second entry, it shall have a " + - "non-zero" + - "\n" + - "ValidAt time." + + "non-zero ValidAt time." + "\n" + "If a node supports a TimeZoneDatabase, and it has data for the given time zone Name and the given " + "Offset matches, the node may update its own DSTOffset attribute to add new DST change times as " + @@ -280,18 +278,16 @@ export const TimeSynchronization = Cluster( Event( { name: "DstStatus", id: 0x1, access: "V", conformance: "TZ", priority: "info", - - details: "This event shall be generated when the node starts or stops applying a DST offset." + - "\n" + - "DSTOffsetActive" + - "\n" + - "Indicates whether the current DST offset is being applied (i.e, daylight savings time is applied, " + - "as opposed to standard time).", - + details: "This event shall be generated when the node starts or stops applying a DST offset.", xref: { document: "core", section: "11.17.10.2" } }, - Field({ name: "DstOffsetActive", id: 0x0, type: "bool", conformance: "M" }) + Field({ + name: "DstOffsetActive", id: 0x0, type: "bool", conformance: "M", + details: "Indicates whether the current DST offset is being applied (i.e, daylight savings time is applied, " + + "as opposed to standard time).", + xref: { document: "core", section: "11.17.10.2.1" } + }) ), Event( @@ -347,8 +343,9 @@ export const TimeSynchronization = Cluster( "valid time source, it may send a Granularity of NoTimeGranularity." + "\n" + "Upon receipt of this command, the node may update its UTCTime attribute to match the time specified " + - "in the command, if the stated Granularity and TimeSource are acceptable. The node shall update its " + - "UTCTime attribute if its current Granularity is NoTimeGranularity." + + "in the command, if the stated Granularity and TimeSource are acceptable. The node shall" + + "\n" + + "update its UTCTime attribute if its current Granularity is NoTimeGranularity." + "\n" + "If the time is updated, the node shall also update its Granularity attribute based on the " + "granularity specified in the command and the expected clock drift of the node. This SHOULD normally " + @@ -368,17 +365,14 @@ export const TimeSynchronization = Cluster( details: "This shall give the Client’s UTC Time.", xref: { document: "core", section: "11.17.9.1.1" } }), - Field({ name: "Granularity", id: 0x1, type: "GranularityEnum", conformance: "M", default: 0, - details: "This shall give the Client’s Granularity, as described in Section 11.17.8.2, “Granularity " + - "Attribute”.", + details: "This shall give the Client’s Granularity, as described in Granularity.", xref: { document: "core", section: "11.17.9.1.2" } }), - Field({ name: "TimeSource", id: 0x2, type: "TimeSourceEnum", conformance: "O", default: 0, - details: "This shall give the Client’s TimeSource, as described in Section 11.17.8.3, “TimeSource Attribute”.", + details: "This shall give the Client’s TimeSource, as described in TimeSource.", xref: { document: "core", section: "11.17.9.1.3" } }) ), @@ -387,11 +381,16 @@ export const TimeSynchronization = Cluster( { name: "SetTrustedTimeSource", id: 0x1, access: "F A", conformance: "TSC", direction: "request", response: "status", - details: "This command shall set the TrustedTimeSource attribute. Upon receipt of this command, * If the " + - "TrustedTimeSource field in the command is null, the node shall set the TrustedTimeSource attribute " + - "to null and shall generate a MissingTrustedTimeSource event. * Otherwise, the node shall set the " + - "TrustedTimeSource attribute to a struct which has NodeID and Endpoint fields matching those in the " + - "TrustedTimeSource field and has its FabricIndex field set to the command’s accessing fabric index.", + + details: "This command shall set the TrustedTimeSource attribute. Upon receipt of this command:" + + "\n" + + " • If the TrustedTimeSource field in the command is null, the node shall set the TrustedTimeSource " + + " attribute to null and shall generate a MissingTrustedTimeSource event." + + "\n" + + " • Otherwise, the node shall set the TrustedTimeSource attribute to a struct which has NodeID and " + + " Endpoint fields matching those in the TrustedTimeSource field and has its FabricIndex field set " + + " to the command’s accessing fabric index.", + xref: { document: "core", section: "11.17.9.2" } }, @@ -445,10 +444,9 @@ export const TimeSynchronization = Cluster( Field({ name: "DstOffsetsRequired", id: 0x0, type: "bool", conformance: "M", default: true, details: "If the node supports a time zone database with information for the time zone that will be applied, " + - "it" + - "\n" + - "may use this information to set the DSTOffset attribute. If the node is setting its own DSTOffset " + - "attribute, the DSTOffsetsRequired field shall be set to false, otherwise it shall be set to true.", + "it may use this information to set the DSTOffset attribute. If the node is setting its own " + + "DSTOffset attribute, the DSTOffsetsRequired field shall be set to false, otherwise it shall be set " + + "to true.", xref: { document: "core", section: "11.17.9.4.1" } }) ), @@ -460,8 +458,9 @@ export const TimeSynchronization = Cluster( details: "This command is used to set the DST offsets for a node." + "\n" + - " • If the length of DSTOffset is larger than DSTOffsetListMaxSize, the node shall respond with " + - " RESOURCE_EXHAUSTED." + + " • If the length of DSTOffset is larger than DSTOffsetListMaxSize, the node shall respond with" + + "\n" + + "RESOURCE_EXHAUSTED." + "\n" + " • Else if the list entries do not conform to the list requirements for DSTOffset attribute, the " + " node shall respond with CONSTRAINT_ERROR." + @@ -701,7 +700,10 @@ export const TimeSynchronization = Cluster( Datatype( { name: "StatusCodeEnum", type: "enum8", xref: { document: "core", section: "11.17.7.1" } }, - Field({ name: "TimeNotAccepted", id: 0x2, description: "Node rejected the attempt to set the UTC time" }) + Field({ + name: "TimeNotAccepted", id: 0x2, conformance: "M", + description: "Node rejected the attempt to set the UTC time" + }) ) ); diff --git a/packages/model/src/standard/elements/TotalVolatileOrganicCompoundsConcentrationMeasurement.ts b/packages/model/src/standard/elements/TotalVolatileOrganicCompoundsConcentrationMeasurement.ts index 975e01391c..e402a7e6f3 100644 --- a/packages/model/src/standard/elements/TotalVolatileOrganicCompoundsConcentrationMeasurement.ts +++ b/packages/model/src/standard/elements/TotalVolatileOrganicCompoundsConcentrationMeasurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/UnitLocalization.ts b/packages/model/src/standard/elements/UnitLocalization.ts index f8a012f1ad..a1ede51d7c 100644 --- a/packages/model/src/standard/elements/UnitLocalization.ts +++ b/packages/model/src/standard/elements/UnitLocalization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,8 +19,7 @@ export const UnitLocalization = Cluster( name: "UnitLocalization", id: 0x2d, classification: "node", pics: "LUNIT", details: "Nodes should be expected to be deployed to any and all regions of the world. These global regions " + - "may have differing preferences for the units in which values are conveyed in communication to a" + - "\n" + + "may have differing preferences for the units in which values are conveyed in communication to a " + "user. As such, Nodes that visually or audibly convey measurable values to the user need a mechanism " + "by which they can be configured to use a user’s preferred unit." + "\n" + diff --git a/packages/model/src/standard/elements/UserLabel.ts b/packages/model/src/standard/elements/UserLabel.ts index 066350596e..500fa3ca67 100644 --- a/packages/model/src/standard/elements/UserLabel.ts +++ b/packages/model/src/standard/elements/UserLabel.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,8 @@ import { export const UserLabel = Cluster( { name: "UserLabel", id: 0x41, type: "Label", classification: "endpoint", pics: "ULABEL", - details: "This cluster provides a feature to tag an endpoint with zero or more labels.", + details: "This cluster is derived from the Label cluster and provides a feature to tag an endpoint with zero " + + "or more writable labels.", xref: { document: "core", section: "9.9" } }, diff --git a/packages/model/src/standard/elements/ValidProxies.ts b/packages/model/src/standard/elements/ValidProxies.ts index a07496ae13..9f55409908 100644 --- a/packages/model/src/standard/elements/ValidProxies.ts +++ b/packages/model/src/standard/elements/ValidProxies.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -27,8 +27,8 @@ export const ValidProxies = Cluster( Attribute( { - name: "ValidProxyList", id: 0x0, type: "list", access: "RW", conformance: "M", constraint: "nA", - default: [], quality: "N F", + name: "ValidProxyList", id: 0x0, type: "list", access: "RW", conformance: "M", default: [], + quality: "N F", details: "List of valid proxies that can proxy this Node. Each entry in this list is fabric-scoped.", xref: { document: "core", section: "9.15.14.5.1" } }, diff --git a/packages/model/src/standard/elements/ValveConfigurationAndControl.ts b/packages/model/src/standard/elements/ValveConfigurationAndControl.ts index a9ceac0100..e220121310 100644 --- a/packages/model/src/standard/elements/ValveConfigurationAndControl.ts +++ b/packages/model/src/standard/elements/ValveConfigurationAndControl.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -302,7 +302,7 @@ export const ValveConfigurationAndControl = Cluster( Datatype( { name: "StatusCodeEnum", type: "enum8", xref: { document: "cluster", section: "4.6.6.1" } }, Field({ - name: "FailureDueToFault", id: 0x2, + name: "FailureDueToFault", id: 0x2, conformance: "M", description: "The requested action could not be performed due to a fault on the valve." }) ) diff --git a/packages/model/src/standard/elements/VideoRemoteControlDT.ts b/packages/model/src/standard/elements/VideoRemoteControlDT.ts index 7d409e90b1..f840911792 100644 --- a/packages/model/src/standard/elements/VideoRemoteControlDT.ts +++ b/packages/model/src/standard/elements/VideoRemoteControlDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/WakeOnLan.ts b/packages/model/src/standard/elements/WakeOnLan.ts index 47c4fa45c1..5bab99b442 100644 --- a/packages/model/src/standard/elements/WakeOnLan.ts +++ b/packages/model/src/standard/elements/WakeOnLan.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/WaterFreezeDetectorDT.ts b/packages/model/src/standard/elements/WaterFreezeDetectorDT.ts index d8b7a1d02a..1a80509709 100644 --- a/packages/model/src/standard/elements/WaterFreezeDetectorDT.ts +++ b/packages/model/src/standard/elements/WaterFreezeDetectorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/WaterHeaterDT.ts b/packages/model/src/standard/elements/WaterHeaterDT.ts new file mode 100644 index 0000000000..76c7bfcc77 --- /dev/null +++ b/packages/model/src/standard/elements/WaterHeaterDT.ts @@ -0,0 +1,47 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DeviceTypeElement as DeviceType, RequirementElement as Requirement } from "../../elements/index.js"; + +export const WaterHeaterDt = DeviceType( + { + name: "WaterHeater", id: 0x50f, category: "Energy", classification: "simple", + details: "A water heater is a device that is generally installed in properties to heat water for showers, " + + "baths etc.", + xref: { document: "device", section: "14.2" } + }, + + Requirement( + { name: "Descriptor", id: 0x1d, element: "serverCluster" }, + Requirement({ name: "DeviceTypeList", default: [ { deviceType: 1295, revision: 1 } ], element: "attribute" }) + ), + Requirement({ + name: "Identify", id: 0x3, conformance: "O", element: "serverCluster", + xref: { document: "device", section: "14.2.6" } + }), + + Requirement( + { + name: "Thermostat", id: 0x201, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.2.6" } + }, + Requirement({ name: "HEATING", conformance: "M", element: "feature" }) + ), + + Requirement({ + name: "WaterHeaterManagement", id: 0x94, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.2.6" } + }), + Requirement({ + name: "WaterHeaterMode", id: 0x9e, conformance: "M", element: "serverCluster", + xref: { document: "device", section: "14.2.6" } + }) +); + +MatterDefinition.children.push(WaterHeaterDt); diff --git a/packages/model/src/standard/elements/WaterHeaterManagement.ts b/packages/model/src/standard/elements/WaterHeaterManagement.ts new file mode 100644 index 0000000000..235c5c81a7 --- /dev/null +++ b/packages/model/src/standard/elements/WaterHeaterManagement.ts @@ -0,0 +1,283 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + FieldElement as Field, + EventElement as Event, + CommandElement as Command, + DatatypeElement as Datatype +} from "../../elements/index.js"; + +export const WaterHeaterManagement = Cluster( + { + name: "WaterHeaterManagement", id: 0x94, classification: "application", pics: "EWATERHTR", + + details: "This cluster is used to allow clients to control the operation of a hot water heating appliance so " + + "that it can be used with energy management." + + "\n" + + "Heating of hot water is one of the main energy uses in homes, and when coupled with the Energy " + + "Management cluster, it can help consumers save cost (e.g. using power at cheaper times or from " + + "local solar PV generation).", + + xref: { document: "cluster", section: "9.5" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 2 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.5.4" } }, + Field({ + name: "EM", conformance: "O", constraint: "0", description: "EnergyManagement", + details: "Allows energy management control of the tank" + }), + Field({ + name: "TP", conformance: "O", constraint: "1", description: "TankPercent", + details: "Supports monitoring the percentage of hot water in the tank" + }) + ), + + Attribute({ + name: "HeaterTypes", id: 0x0, type: "WaterHeaterHeatSourceBitmap", access: "R V", conformance: "M", + default: 0, quality: "F", + details: "Indicates the heat sources that the water heater can call on for heating. If a bit is set then the " + + "water heater supports the corresponding heat source.", + xref: { document: "cluster", section: "9.5.7.1" } + }), + + Attribute({ + name: "HeatDemand", id: 0x1, type: "WaterHeaterHeatSourceBitmap", access: "R V", conformance: "M", + default: 0, + details: "Indicates if the water heater is heating water. If a bit is set then the corresponding heat source " + + "is active.", + xref: { document: "cluster", section: "9.5.7.2" } + }), + + Attribute({ + name: "TankVolume", id: 0x2, type: "uint16", access: "R V", conformance: "EM", default: 0, + details: "Indicates the volume of water that the hot water tank can hold (in units of Litres). This allows an " + + "energy management system to estimate the required heating energy needed to reach the target " + + "temperature.", + xref: { document: "cluster", section: "9.5.7.3" } + }), + + Attribute( + { + name: "EstimatedHeatRequired", id: 0x3, type: "energy-mWh", access: "R V", conformance: "EM", + constraint: "min 0", default: 0, + + details: "Indicates the estimated heat energy needed to raise the water temperature to the target setpoint. " + + "This can be computed by taking the specific heat capacity of water (4182 J/kg °C) and by knowing " + + "the current temperature of the water, the tank volume and target temperature." + + "\n" + + "For example, if the target temperature was 60°C, the current temperature was 20°C and the tank " + + "volume was 100L:" + + "\n" + + "Mass of water = 1kg per Litre" + + "\n" + + "Total Mass = 100 x 1kg = 100kg" + + "\n" + + "Δ Temperature = (target temperature - current temperature)" + + "\n" + + "= (60°C - 20°C) = 40°C" + + "\n" + + "Energy required to" + + "\n" + + "heat the water to 60°C = 4182 x 40 x 100 = 16,728,000 J" + + "\n" + + "Converting Joules in to Wh of heat (divide by 3600):" + + "\n" + + "If the TankPercent feature is supported, then this estimate shall also take into account the " + + "percentage of the water in the tank which is already hot." + + "\n" + + "NOTE" + + "\n" + + "The electrical energy required to heat the water depends on the heating system used to heat the " + + "water. For example, a direct electric immersion heating element can be close to 100% efficient, so " + + "the electrical energy needed to heat the hot water is nearly the same as the " + + "EstimatedHeatEnergyRequired. However some forms of heating, such as an air-source heat pump which " + + "extracts heat from ambient air, requires much less electrical energy to heat hot water. Heat pumps " + + "can be produce 3kWh of heat output for 1kWh of electrical energy input. The conversion between heat " + + "energy and electrical energy is outside the scope of this cluster.", + + xref: { document: "cluster", section: "9.5.7.4" } + } + ), + + Attribute( + { + name: "TankPercentage", id: 0x4, type: "percent", access: "R V", conformance: "TP", default: 0, + + details: "Indicates an approximate level of hot water stored in the tank, which might help consumers " + + "understand the amount of hot water remaining in the tank. The accuracy of this attribute is " + + "manufacturer specific." + + "\n" + + "In most hot water tanks, there is a stratification effect where the hot water layer rests above a " + + "cooler layer of water below. For this reason cold water is fed in at the bottom of the tank and the " + + "hot water is drawn from the top." + + "\n" + + "Some water tanks might use multiple temperature probes to estimate the level of the hot water " + + "layer. A water heater with multiple temperature probes is likely to implement an algorithm to " + + "estimate the hot water tank percentage by taking into account the temperature values of each probe " + + "to determine the height of the hot water." + + "\n" + + "However it might be possible with a single temperature probe to estimate how much hot water is left " + + "using a simpler algorithm:" + + "\n" + + "For example, if the target temperature was 60°C, the CurrentTemperature was 40°C from a single " + + "temperature probe measuring the average water temperature and the temperature of incoming cold " + + "water (COLD_WATER_TEMP) was assumed to be 20°C:" + + "\n" + + "TankPercentage = int(((current temperature - COLD_WATER_TEMP) / (target temperature - " + + "COLD_WATER_TEMP)) * 100)" + + "\n" + + "TankPercentage = min( max(TankPercentage,0), 100)" + + "\n" + + "TankPercentage = 50%", + + xref: { document: "cluster", section: "9.5.7.5" } + } + ), + + Attribute({ + name: "BoostState", id: 0x5, type: "BoostStateEnum", access: "R V", conformance: "M", default: 0, + details: "Indicates whether the Boost, as triggered by a Boost command, is currently" + + "\n" + + "Active or Inactive." + + "\n" + + "See Boost and CancelBoost commands for more details.", + xref: { document: "cluster", section: "9.5.7.6" } + }), + + Event( + { + name: "BoostStarted", id: 0x0, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated whenever a Boost command is accepted." + + "\n" + + "The corresponding structure fields within the WaterHeaterBoostInfoStruct are copied from the Boost " + + "command.", + xref: { document: "cluster", section: "9.5.9.1" } + }, + + Field({ name: "BoostInfo", id: 0x0, type: "WaterHeaterBoostInfoStruct", conformance: "M" }) + ), + + Event({ + name: "BoostEnded", id: 0x1, access: "V", conformance: "M", priority: "info", + details: "This event shall be generated whenever the BoostState transitions from Active to Inactive.", + xref: { document: "cluster", section: "9.5.9.2" } + }), + + Command( + { + name: "Boost", id: 0x0, access: "M", conformance: "M", direction: "request", response: "status", + details: "Allows a client to request that the water heater is put into a Boost state.", + xref: { document: "cluster", section: "9.5.8.1" } + }, + Field({ name: "BoostInfo", id: 0x0, type: "WaterHeaterBoostInfoStruct", conformance: "M" }) + ), + + Command({ + name: "CancelBoost", id: 0x1, access: "M", conformance: "M", direction: "request", + response: "status", + details: "Allows a client to cancel an ongoing Boost operation. This command has no payload.", + xref: { document: "cluster", section: "9.5.8.2" } + }), + + Datatype( + { name: "WaterHeaterHeatSourceBitmap", type: "map8", xref: { document: "cluster", section: "9.5.6.1" } }, + Field({ name: "ImmersionElement1", constraint: "0", description: "Immersion Heating Element 1" }), + Field({ name: "ImmersionElement2", constraint: "1", description: "Immersion Heating Element 2" }), + Field({ name: "HeatPump", constraint: "2", description: "Heat pump Heating" }), + Field({ name: "Boiler", constraint: "3", description: "Boiler Heating (e.g. Gas or Oil)" }), + Field({ name: "Other", constraint: "4", description: "Other Heating" }) + ), + + Datatype( + { name: "BoostStateEnum", type: "enum8", xref: { document: "cluster", section: "9.5.6.2" } }, + Field({ name: "Inactive", id: 0x0, conformance: "M", description: "Boost is not currently active" }), + Field({ name: "Active", id: 0x1, conformance: "M", description: "Boost is currently active" }) + ), + + Datatype( + { name: "WaterHeaterBoostInfoStruct", type: "struct", xref: { document: "cluster", section: "9.5.6.3" } }, + Field({ + name: "Duration", id: 0x0, type: "elapsed-s", conformance: "M", constraint: "min 1", + details: "This field shall indicate the time period, in seconds, for which the boost state is activated.", + xref: { document: "cluster", section: "9.5.6.3.1" } + }), + + Field({ + name: "OneShot", id: 0x1, type: "bool", conformance: "[!TP], [TP].a-", default: false, + + details: "This field shall indicate whether the boost state shall be automatically canceled once the hot " + + "water has reached either:" + + "\n" + + " • the set point temperature (from the thermostat cluster)" + + "\n" + + " • the TemporarySetpoint temperature (if specified)" + + "\n" + + " • the TargetPercentage (if specified).", + + xref: { document: "cluster", section: "9.5.6.3.2" } + }), + + Field({ + name: "EmergencyBoost", id: 0x2, type: "bool", conformance: "O", default: false, + details: "This field shall indicate that the consumer wants the water to be heated quickly. This may cause " + + "multiple heat sources to be activated (e.g. a heat pump and direct electric immersion heating " + + "element)." + + "\n" + + "The choice of which heat sources are activated is manufacturer specific.", + xref: { document: "cluster", section: "9.5.6.3.3" } + }), + + Field({ + name: "TemporarySetpoint", id: 0x3, type: "temperature", conformance: "O", constraint: "desc", + + details: "This field shall indicate the target temperature to which the water will be heated." + + "\n" + + "If included, it shall be used instead of the thermostat cluster set point temperature whilst the " + + "boost state is activated." + + "\n" + + "The value of this field shall be within the constraints of the MinHeatSetpointLimit and " + + "MaxHeatSetpointLimit attributes (inclusive), of the thermostat cluster.", + + xref: { document: "cluster", section: "9.5.6.3.4" } + }), + + Field({ + name: "TargetPercentage", id: 0x4, type: "percent", conformance: "TargetReheat, [TP]", + details: "This field shall indicate the target percentage of hot water in the tank that the TankPercentage " + + "attribute must reach before the heating is switched off.", + xref: { document: "cluster", section: "9.5.6.3.5" } + }), + + Field({ + name: "TargetReheat", id: 0x5, type: "percent", conformance: "[TP].a-", + constraint: "max targetPercentage", + + details: "This field shall indicate the percentage to which the hot water in the tank shall be allowed to " + + "fall before again beginning to reheat it." + + "\n" + + "For example if the TargetPercentage was 80%, and the TargetReheat was 40%, then after initial " + + "heating to 80% hot water, the tank may have hot water drawn off until only 40% hot water remains. " + + "At this point the heater will begin to heat back up to 80% of hot water. If this field and the " + + "OneShot field were both omitted, heating would begin again after any water draw which reduced the " + + "TankPercentage below 80%." + + "\n" + + "This field shall be less than or equal to the TargetPercentage field.", + + xref: { document: "cluster", section: "9.5.6.3.6" } + }) + ) +); + +MatterDefinition.children.push(WaterHeaterManagement); diff --git a/packages/model/src/standard/elements/WaterHeaterMode.ts b/packages/model/src/standard/elements/WaterHeaterMode.ts new file mode 100644 index 0000000000..29dc548b93 --- /dev/null +++ b/packages/model/src/standard/elements/WaterHeaterMode.ts @@ -0,0 +1,95 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + FieldElement as Field, + DatatypeElement as Datatype +} from "../../elements/index.js"; + +export const WaterHeaterMode = Cluster( + { + name: "WaterHeaterMode", id: 0x9e, type: "ModeBase", classification: "application", pics: "WHM", + details: "This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced " + + "enumerated values for water heater devices.", + xref: { document: "cluster", section: "9.6" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute( + { name: "FeatureMap", id: 0xfffc, type: "FeatureMap", xref: { document: "cluster", section: "9.6.4" } }, + Field({ + name: "DEPONOFF", conformance: "X", constraint: "0", description: "OnOff", + details: "Dependency with the OnOff cluster" + }) + ), + + Attribute({ + name: "SupportedModes", id: 0x0, + + details: "At least one entry in the SupportedModes attribute shall include the Manual mode tag in the " + + "ModeTags field list." + + "\n" + + "At least one entry in the SupportedModes attribute shall include the Off mode tag in the ModeTags " + + "field list." + + "\n" + + "An entry in the SupportedModes attribute that includes one of an Off, Manual, or Timed tag shall " + + "NOT also include an additional instance of any one of these tag types.", + + xref: { document: "cluster", section: "9.6.6.1" } + }), + + Attribute({ name: "CurrentMode", id: 0x1, xref: { document: "cluster", section: "9.6.6" } }), + Attribute({ name: "StartUpMode", id: 0x2, conformance: "X", xref: { document: "cluster", section: "9.6.6" } }), + Attribute({ name: "OnMode", id: 0x3, conformance: "X", xref: { document: "cluster", section: "9.6.6" } }), + + Datatype({ + name: "ModeOptionStruct", type: "ModeOptionStruct", + details: "The table below lists the changes relative to the Mode Base cluster for the fields of the " + + "ModeOptionStruct type. A blank field indicates no change.", + xref: { document: "cluster", section: "9.6.5.1" } + }), + + Datatype( + { name: "ModeTag", type: "enum16" }, + Field({ name: "Auto", id: 0x0, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Quick", id: 0x1, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Quiet", id: 0x2, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "LowNoise", id: 0x3, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "LowEnergy", id: 0x4, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Vacation", id: 0x5, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Min", id: 0x6, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Max", id: 0x7, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Night", id: 0x8, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ name: "Day", id: 0x9, xref: { document: "cluster", section: "9.6.7.1" } }), + Field({ + name: "Off", id: 0x4000, + details: "While in modes with this tag, the device will not attempt to keep the water warm.", + xref: { document: "cluster", section: "9.6.7.1.1" } + }), + + Field({ + name: "Manual", id: 0x4001, + details: "While in modes with this tag, the device will attempt to keep the water warm based on the " + + "OccupiedHeatingSetpoint attribute of the associated Thermostat cluster.", + xref: { document: "cluster", section: "9.6.7.1.2" } + }), + + Field({ + name: "Timed", id: 0x4002, + details: "While in modes with this tag, the device will attempt to keep the water warm based on the Schedules " + + "attribute of the associated Thermostat cluster.", + xref: { document: "cluster", section: "9.6.7.1.3" } + }) + ) +); + +MatterDefinition.children.push(WaterHeaterMode); diff --git a/packages/model/src/standard/elements/WaterLeakDetectorDT.ts b/packages/model/src/standard/elements/WaterLeakDetectorDT.ts index 1f9a6e9302..07fe1fcb78 100644 --- a/packages/model/src/standard/elements/WaterLeakDetectorDT.ts +++ b/packages/model/src/standard/elements/WaterLeakDetectorDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/WaterTankLevelMonitoring.ts b/packages/model/src/standard/elements/WaterTankLevelMonitoring.ts new file mode 100644 index 0000000000..431c0d7c14 --- /dev/null +++ b/packages/model/src/standard/elements/WaterTankLevelMonitoring.ts @@ -0,0 +1,15 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { ClusterElement as Cluster } from "../../elements/index.js"; + +export const WaterTankLevelMonitoring = Cluster( + { name: "WaterTankLevelMonitoring", id: 0x79, type: "ResourceMonitoring", pics: "WTLREPMON" } +); +MatterDefinition.children.push(WaterTankLevelMonitoring); diff --git a/packages/model/src/standard/elements/WaterValveDT.ts b/packages/model/src/standard/elements/WaterValveDT.ts index e5940ad5ef..17c5b0e2f1 100644 --- a/packages/model/src/standard/elements/WaterValveDT.ts +++ b/packages/model/src/standard/elements/WaterValveDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ export const WaterValveDt = DeviceType( name: "WaterValve", id: 0x42, category: "Smart Plugs/Outlets and other Actuators", classification: "simple", details: "This defines conformance to the Water Valve device type.", - xref: { document: "device", section: "5.4" } + xref: { document: "device", section: "5.6" } }, Requirement( @@ -23,19 +23,19 @@ export const WaterValveDt = DeviceType( ), Requirement({ name: "Identify", id: 0x3, conformance: "M", element: "serverCluster", - xref: { document: "device", section: "5.4.4" } + xref: { document: "device", section: "5.6.4" } }), Requirement({ name: "ValveConfigurationAndControl", id: 0x81, conformance: "M", element: "serverCluster", - xref: { document: "device", section: "5.4.4" } + xref: { document: "device", section: "5.6.4" } }), Requirement({ name: "FlowMeasurement", id: 0x404, conformance: "O", element: "serverCluster", - xref: { document: "device", section: "5.4.4" } + xref: { document: "device", section: "5.6.4" } }), Requirement({ name: "FlowMeasurement", id: 0x404, conformance: "O", element: "clientCluster", - xref: { document: "device", section: "5.4.4" } + xref: { document: "device", section: "5.6.4" } }) ) diff --git a/packages/model/src/standard/elements/WiFiNetworkDiagnostics.ts b/packages/model/src/standard/elements/WiFiNetworkDiagnostics.ts index ab299df7aa..34cd5e5624 100644 --- a/packages/model/src/standard/elements/WiFiNetworkDiagnostics.ts +++ b/packages/model/src/standard/elements/WiFiNetworkDiagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -92,11 +92,10 @@ export const WiFiNetworkDiagnostics = Cluster( Attribute({ name: "BeaconRxCount", id: 0x6, type: "uint32", access: "R V", conformance: "PKTCNT", default: 0, quality: "X C", - details: "The BeaconRxCount attribute shall indicate the count of the number of received beacons. The" + - "\n" + - "total number of expected beacons that could have been received during the interval since " + - "association SHOULD match the sum of BeaconRxCount and BeaconLostCount. If the Node does not have an " + - "ability to report count of beacons received, this value may remain set to zero.", + details: "The BeaconRxCount attribute shall indicate the count of the number of received beacons. The total " + + "number of expected beacons that could have been received during the interval since association " + + "SHOULD match the sum of BeaconRxCount and BeaconLostCount. If the Node does not have an ability to " + + "report count of beacons received, this value may remain set to zero.", xref: { document: "core", section: "11.15.6.7" } }), @@ -185,8 +184,7 @@ export const WiFiNetworkDiagnostics = Cluster( name: "Status", id: 0x1, type: "uint16", conformance: "M", details: "The Status field shall be set to the Status Code value that was present in the last frame related " + - "to association where Status Code was not equal to zero and which caused the failure of a last trial" + - "\n" + + "to association where Status Code was not equal to zero and which caused the failure of a last trial " + "attempt, if this last failure was due to one of the following Management frames:" + "\n" + " • Association Response (Type 0, Subtype 1)" + diff --git a/packages/model/src/standard/elements/WiFiNetworkManagement.ts b/packages/model/src/standard/elements/WiFiNetworkManagement.ts new file mode 100644 index 0000000000..a5d3485718 --- /dev/null +++ b/packages/model/src/standard/elements/WiFiNetworkManagement.ts @@ -0,0 +1,98 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { + ClusterElement as Cluster, + AttributeElement as Attribute, + CommandElement as Command +} from "../../elements/index.js"; + +export const WiFiNetworkManagement = Cluster( + { + name: "WiFiNetworkManagement", id: 0x451, classification: "application", pics: "WIFINM", + details: "This cluster provides an interface for getting information about the Wi-Fi network that a Network " + + "Infrastructure Manager device type provides. Privileged nodes within the same fabric as a Network " + + "Infrastructure Manager can use these interfaces to request information related to the Wi-Fi Network " + + "such as SSID and Passphrase.", + xref: { document: "cluster", section: "10.2" } + }, + + Attribute({ name: "ClusterRevision", id: 0xfffd, type: "ClusterRevision", default: 1 }), + + Attribute({ + name: "Ssid", id: 0x0, type: "octstr", access: "R V", conformance: "M", constraint: "1 to 32", + default: null, quality: "X N", + + details: "Indicates the SSID of the primary Wi-Fi network provided by this device." + + "\n" + + "A value of null shall indicate that no primary Wi-Fi network is available (e.g. because the Wi-Fi " + + "network has not yet been configured by the user)." + + "\n" + + "NOTE" + + "\n" + + "The SSID in Wi-Fi is a collection of 1-32 bytes, the text encoding of which is not specified. " + + "Implementations must be careful to support transferring these byte strings without requiring a " + + "particular encoding. The most common encoding is UTF-8, however this is just a convention. Some " + + "configurations may use Latin-1 or other character sets.", + + xref: { document: "cluster", section: "10.2.4.1" } + }), + + Attribute({ + name: "PassphraseSurrogate", id: 0x1, type: "uint64", access: "R M", conformance: "M", + default: null, quality: "X N", + + details: "This attribute shall contain an arbitrary numeric value; this value shall increase whenever the " + + "passphrase or PSK associated with the primary Wi-Fi network provided by this device changes." + + "\n" + + "A value of null shall indicate that no primary Wi-Fi network is available." + + "\n" + + "Clients can subscribe to this attribute or compare its value to a locally cached copy to detect if " + + "a cached passphrase value has become stale." + + "\n" + + "It is recommended that servers implement this attribute as either a timestamp or a counter. When " + + "implemented as a counter it SHOULD be initialized with a random value." + + "\n" + + "NOTE" + + "\n" + + "The passphrase itself is not exposed as an attribute to avoid its unintentional retrieval or " + + "caching by clients that use wildcard reads or otherwise routinely read all available attributes. It " + + "can be retrieved using the NetworkPassphraseRequest" + + "\n" + + "command.", + + xref: { document: "cluster", section: "10.2.4.2" } + }), + + Command({ + name: "NetworkPassphraseRequest", id: 0x0, access: "M", conformance: "M", direction: "request", + response: "NetworkPassphraseResponse", + + details: "This command is used to request the current WPA-Personal passphrase or PSK associated with the " + + "Wi-Fi network provided by this device." + + "\n" + + "If the command is not executed via a CASE session, the command shall be rejected with a status of " + + "UNSUPPORTED_ACCESS." + + "\n" + + "If no primary Wi-Fi network is available (the SSID attribute is null), the command shall be " + + "rejected with a status of INVALID_IN_STATE." + + "\n" + + "Otherwise a NetworkPassphraseResponse shall be generated.", + + xref: { document: "cluster", section: "10.2.5.1" } + }), + + Command({ + name: "NetworkPassphraseResponse", id: 0x1, conformance: "M", direction: "response", + details: "This command shall be generated in response to a NetworkPassphraseRequest command.", + xref: { document: "cluster", section: "10.2.5.2" } + }) +); + +MatterDefinition.children.push(WiFiNetworkManagement); diff --git a/packages/model/src/standard/elements/WildcardPathFlagsBitmap.ts b/packages/model/src/standard/elements/WildcardPathFlagsBitmap.ts index d7ea6129ca..92ade7536a 100644 --- a/packages/model/src/standard/elements/WildcardPathFlagsBitmap.ts +++ b/packages/model/src/standard/elements/WildcardPathFlagsBitmap.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/WindowCovering.ts b/packages/model/src/standard/elements/WindowCovering.ts index a0a75289be..e57185bab8 100644 --- a/packages/model/src/standard/elements/WindowCovering.ts +++ b/packages/model/src/standard/elements/WindowCovering.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -69,7 +69,7 @@ export const WindowCovering = Cluster( name: "Type", id: 0x0, type: "TypeEnum", access: "R V", conformance: "M", constraint: "desc", default: 0, quality: "F", details: "This attribute shall identify the type of window covering.", - xref: { document: "cluster", section: "5.3.6.2" } + xref: { document: "cluster", section: "5.3.6.1" } }), Attribute({ @@ -77,7 +77,7 @@ export const WindowCovering = Cluster( conformance: "[LF & PA_LF & ABS]", default: 0, quality: "F", details: "Indicates the maximum possible encoder position possible (Unit cm, centimeters) to position the " + "height of the window covering lift.", - xref: { document: "cluster", section: "5.3.6.3" } + xref: { document: "cluster", section: "5.3.6.2" } }), Attribute({ @@ -85,7 +85,7 @@ export const WindowCovering = Cluster( conformance: "[TL & PA_TL & ABS]", default: 0, quality: "F", details: "Indicates the maximum possible encoder position possible (Unit 0.1°, tenths of a degree) to " + "position the angle of the window covering tilt.", - xref: { document: "cluster", section: "5.3.6.4" } + xref: { document: "cluster", section: "5.3.6.3" } }), Attribute({ @@ -94,7 +94,7 @@ export const WindowCovering = Cluster( default: null, quality: "X N", details: "Indicates the actual lift position (Unit cm, centimeters) of the window covering from the " + "fully-open position.", - xref: { document: "cluster", section: "5.3.6.5" } + xref: { document: "cluster", section: "5.3.6.4" } }), Attribute({ @@ -103,7 +103,7 @@ export const WindowCovering = Cluster( default: null, quality: "X N", details: "Indicates the actual tilt position (Unit 0.1°, tenths of a degree) of the window covering from the " + "fully-open position.", - xref: { document: "cluster", section: "5.3.6.6" } + xref: { document: "cluster", section: "5.3.6.5" } }), Attribute({ @@ -111,7 +111,7 @@ export const WindowCovering = Cluster( default: 0, quality: "N", details: "Indicates the total number of lift/slide actuations applied to the window covering since the device " + "was installed.", - xref: { document: "cluster", section: "5.3.6.7" } + xref: { document: "cluster", section: "5.3.6.6" } }), Attribute({ @@ -119,7 +119,7 @@ export const WindowCovering = Cluster( default: 0, quality: "N", details: "Indicates the total number of tilt actuations applied to the window covering since the device was " + "installed.", - xref: { document: "cluster", section: "5.3.6.8" } + xref: { document: "cluster", section: "5.3.6.7" } }), Attribute({ @@ -129,46 +129,46 @@ export const WindowCovering = Cluster( "\n" + "To change settings, devices shall write to the Mode attribute. The behavior causing the setting or " + "clearing of each bit is vendor specific.", - xref: { document: "cluster", section: "5.3.6.9" } + xref: { document: "cluster", section: "5.3.6.8" } }), Attribute({ name: "CurrentPositionLiftPercentage", id: 0x8, type: "percent", access: "R V", - conformance: "[LF & PA_LF]", default: null, quality: "X N S P", + conformance: "[LF & PA_LF]", default: null, quality: "X N P", details: "Indicates the actual position as a percentage from 0% to 100% with 1% default step. This attribute " + "is equal to CurrentPositionLiftPercent100ths attribute divided by 100.", - xref: { document: "cluster", section: "5.3.6.12" } + xref: { document: "cluster", section: "5.3.6.11" } }), Attribute({ name: "CurrentPositionTiltPercentage", id: 0x9, type: "percent", access: "R V", - conformance: "[TL & PA_TL]", constraint: "0 to 100", default: null, quality: "X N S P", + conformance: "[TL & PA_TL]", default: null, quality: "X N P", details: "Indicates the actual position as a percentage from 0% to 100% with 1% default step. This attribute " + "is equal to CurrentPositionTiltPercent100ths attribute divided by 100.", - xref: { document: "cluster", section: "5.3.6.13" } + xref: { document: "cluster", section: "5.3.6.12" } }), Attribute({ name: "OperationalStatus", id: 0xa, type: "OperationalStatusBitmap", access: "R V", conformance: "M", default: 0, quality: "P", details: "Indicates the currently ongoing operations and applies to all type of devices.", - xref: { document: "cluster", section: "5.3.6.16" } + xref: { document: "cluster", section: "5.3.6.15" } }), Attribute({ name: "TargetPositionLiftPercent100ths", id: 0xb, type: "percent100ths", access: "R V", - conformance: "LF & PA_LF", default: null, quality: "X S P", + conformance: "LF & PA_LF", default: null, quality: "X P", details: "Indicates the position where the window covering lift will go or is moving to as a percentage (Unit " + "0.01%).", - xref: { document: "cluster", section: "5.3.6.14" } + xref: { document: "cluster", section: "5.3.6.13" } }), Attribute({ name: "TargetPositionTiltPercent100ths", id: 0xc, type: "percent100ths", access: "R V", - conformance: "TL & PA_TL", default: null, quality: "X S P", + conformance: "TL & PA_TL", default: null, quality: "X P", details: "Indicates the position where the window covering tilt will go or is moving to as a percentage (Unit " + "0.01%).", - xref: { document: "cluster", section: "5.3.6.15" } + xref: { document: "cluster", section: "5.3.6.14" } }), Attribute({ @@ -178,55 +178,55 @@ export const WindowCovering = Cluster( "main category indicated by the Type attribute." + "\n" + "The table below helps to match the EndProductType attribute with the Type attribute.", - xref: { document: "cluster", section: "5.3.6.17" } + xref: { document: "cluster", section: "5.3.6.16" } }), Attribute({ name: "CurrentPositionLiftPercent100ths", id: 0xe, type: "percent100ths", access: "R V", - conformance: "LF & PA_LF", constraint: "0 to 10000", default: null, quality: "X N P", + conformance: "LF & PA_LF", constraint: "max 10000", default: null, quality: "X N P", details: "Indicates the actual position as a percentage with a minimal step of 0.01%. E.g Max 10000 equals " + "100.00%.", - xref: { document: "cluster", section: "5.3.6.10" } + xref: { document: "cluster", section: "5.3.6.9" } }), Attribute({ name: "CurrentPositionTiltPercent100ths", id: 0xf, type: "percent100ths", access: "R V", - conformance: "TL & PA_TL", constraint: "0 to 10000", default: null, quality: "X N P", + conformance: "TL & PA_TL", constraint: "max 10000", default: null, quality: "X N P", details: "Indicates the actual position as a percentage with a minimal step of 0.01%. E.g Max 10000 equals " + "100.00%.", - xref: { document: "cluster", section: "5.3.6.11" } + xref: { document: "cluster", section: "5.3.6.10" } }), Attribute({ name: "InstalledOpenLimitLift", id: 0x10, type: "uint16", access: "R V", - conformance: "LF & PA_LF & ABS", constraint: "0 to 65534", default: 0, quality: "N", + conformance: "LF & PA_LF & ABS", constraint: "max 65534", default: 0, quality: "N", details: "Indicates the open limit for lifting the window covering whether position (in centimeters) is " + "encoded or timed.", - xref: { document: "cluster", section: "5.3.6.18" } + xref: { document: "cluster", section: "5.3.6.17" } }), Attribute({ name: "InstalledClosedLimitLift", id: 0x11, type: "uint16", access: "R V", - conformance: "LF & PA_LF & ABS", constraint: "0 to 65534", default: 65534, quality: "N", + conformance: "LF & PA_LF & ABS", constraint: "max 65534", default: 65534, quality: "N", details: "Indicates the closed limit for lifting the window covering whether position (in centimeters) is " + "encoded or timed.", - xref: { document: "cluster", section: "5.3.6.19" } + xref: { document: "cluster", section: "5.3.6.18" } }), Attribute({ name: "InstalledOpenLimitTilt", id: 0x12, type: "uint16", access: "R V", - conformance: "TL & PA_TL & ABS", constraint: "0 to 65534", default: 0, quality: "N", + conformance: "TL & PA_TL & ABS", constraint: "max 65534", default: 0, quality: "N", details: "Indicates the open limit for tilting the window covering whether position (in tenth of a degree) is " + "encoded or timed.", - xref: { document: "cluster", section: "5.3.6.20" } + xref: { document: "cluster", section: "5.3.6.19" } }), Attribute({ name: "InstalledClosedLimitTilt", id: 0x13, type: "uint16", access: "R V", - conformance: "TL & PA_TL & ABS", constraint: "0 to 65534", default: 65534, quality: "N", + conformance: "TL & PA_TL & ABS", constraint: "max 65534", default: 65534, quality: "N", details: "Indicates the closed limit for tilting the window covering whether position (in tenth of a degree) " + "is encoded or timed.", - xref: { document: "cluster", section: "5.3.6.21" } + xref: { document: "cluster", section: "5.3.6.20" } }), Attribute({ name: "VelocityLift", id: 0x14, conformance: "D", xref: { document: "cluster", section: "5.3.6" } }), @@ -250,7 +250,7 @@ export const WindowCovering = Cluster( "any write interaction to the Mode attribute, with an unsupported mode bit or any out of bounds bits " + "set, must be ignored and a response containing the status of CONSTRAINT_ERROR will be returned.", - xref: { document: "cluster", section: "5.3.6.22" } + xref: { document: "cluster", section: "5.3.6.21" } }), Attribute({ name: "IntermediateSetpointsLift", id: 0x18, conformance: "D", xref: { document: "cluster", section: "5.3.6" } }), @@ -262,7 +262,7 @@ export const WindowCovering = Cluster( details: "The SafetyStatus attribute reflects the state of the safety sensors and the common issues " + "preventing movements. By default for nominal operation all flags are cleared (0). A device might " + "support none, one or several bit flags from this attribute (all optional).", - xref: { document: "cluster", section: "5.3.6.23" } + xref: { document: "cluster", section: "5.3.6.22" } }), Command({ @@ -390,7 +390,7 @@ export const WindowCovering = Cluster( }, Field({ name: "LiftPercent100thsValue", id: 0x0, type: "percent100ths", conformance: "M", constraint: "desc" }), - Field({ name: "Ignored", id: 0x1, type: "percent100ths", conformance: "X", constraint: "desc" }) + Field({ name: "Ignored", id: 0x1, conformance: "X" }) ), Command( @@ -433,7 +433,7 @@ export const WindowCovering = Cluster( }, Field({ name: "TiltPercent100thsValue", id: 0x0, type: "percent100ths", conformance: "M", constraint: "desc" }), - Field({ name: "Ignored", id: 0x1, type: "percent100ths", conformance: "X", constraint: "desc" }) + Field({ name: "Ignored", id: 0x1, conformance: "X" }) ), Datatype( @@ -451,7 +451,7 @@ export const WindowCovering = Cluster( } ), - Field({ name: "OnlineReserved", constraint: "1", description: "Deprecated and reserved." }), + Field({ name: "OnlineReserved", constraint: "1" }), Field( { diff --git a/packages/model/src/standard/elements/WindowCoveringControllerDT.ts b/packages/model/src/standard/elements/WindowCoveringControllerDT.ts index 5ea7d6fdb6..b2bd0b35b0 100644 --- a/packages/model/src/standard/elements/WindowCoveringControllerDT.ts +++ b/packages/model/src/standard/elements/WindowCoveringControllerDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -31,10 +31,6 @@ export const WindowCoveringControllerDt = DeviceType( name: "Groups", id: 0x4, conformance: "Active, O", element: "clientCluster", xref: { document: "device", section: "8.4.4" } }), - Requirement({ - name: "ScenesManagement", id: 0x62, conformance: "P, Active, O", element: "clientCluster", - xref: { document: "device", section: "8.4.4" } - }), Requirement({ name: "WindowCovering", id: 0x102, conformance: "M", element: "clientCluster", xref: { document: "device", section: "8.4.4" } diff --git a/packages/model/src/standard/elements/WindowCoveringDT.ts b/packages/model/src/standard/elements/WindowCoveringDT.ts index ff8e8f2cd4..ded330bc7d 100644 --- a/packages/model/src/standard/elements/WindowCoveringDT.ts +++ b/packages/model/src/standard/elements/WindowCoveringDT.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -28,18 +28,9 @@ export const WindowCoveringDt = DeviceType( xref: { document: "device", section: "8.3.4" } }), Requirement({ - name: "ScenesManagement", id: 0x62, conformance: "P, Active, O", element: "serverCluster", + name: "WindowCovering", id: 0x102, conformance: "M", element: "serverCluster", xref: { document: "device", section: "8.3.4" } - }), - - Requirement( - { - name: "WindowCovering", id: 0x102, conformance: "M", element: "serverCluster", - xref: { document: "device", section: "8.3.4" } - }, - Requirement({ name: "GoToLiftPercentageLiftPercent100thsValue", conformance: "Matter", element: "commandField" }), - Requirement({ name: "GoToTiltPercentageTiltPercent100thsValue", conformance: "Matter", element: "commandField" }) - ) + }) ); MatterDefinition.children.push(WindowCoveringDt); diff --git a/packages/model/src/standard/elements/action-id.ts b/packages/model/src/standard/elements/action-id.ts index 8a378b72f7..bb82a07f80 100644 --- a/packages/model/src/standard/elements/action-id.ts +++ b/packages/model/src/standard/elements/action-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const actionId = Datatype({ name: "action-id", type: "uint8", description: "Action ID", isSeed: true, details: "An identifier that indicates an action as defined in the Interaction Model specification.", - xref: { document: "core", section: "7.18.2.31" } + xref: { document: "core", section: "7.19.2.31" } }); MatterDefinition.children.push(actionId); diff --git a/packages/model/src/standard/elements/amperage-mA.ts b/packages/model/src/standard/elements/amperage-mA.ts index 610cd15b42..ab1ee29f7e 100644 --- a/packages/model/src/standard/elements/amperage-mA.ts +++ b/packages/model/src/standard/elements/amperage-mA.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const amperageMA = Datatype({ name: "amperage-mA", type: "int64", description: "Amperage", isSeed: true, details: "This type represents amperage measured in milliamps.", - xref: { document: "core", section: "7.18.2.13" } + xref: { document: "core", section: "7.19.2.13" } }); MatterDefinition.children.push(amperageMA); diff --git a/packages/model/src/standard/elements/any.ts b/packages/model/src/standard/elements/any.ts index 0e060f29ba..4ca6410681 100644 --- a/packages/model/src/standard/elements/any.ts +++ b/packages/model/src/standard/elements/any.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/attrib-id.ts b/packages/model/src/standard/elements/attrib-id.ts index 509f02657c..55067a974a 100644 --- a/packages/model/src/standard/elements/attrib-id.ts +++ b/packages/model/src/standard/elements/attrib-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const attribId = Datatype({ "\n" + "Attribute IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation " + "are described in Data Model Types.", - xref: { document: "core", section: "7.18.2.27" } + xref: { document: "core", section: "7.19.2.27" } }); MatterDefinition.children.push(attribId); diff --git a/packages/model/src/standard/elements/bool.ts b/packages/model/src/standard/elements/bool.ts index fe6c18beaa..86598ddbfc 100644 --- a/packages/model/src/standard/elements/bool.ts +++ b/packages/model/src/standard/elements/bool.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,7 @@ export const bool = Datatype({ " • FALSE shall be equivalent to the value 0 (zero)." + "\n" + " • TRUE shall be equivalent to the value 1 (one).", - xref: { document: "core", section: "7.18.1.1" } + xref: { document: "core", section: "7.19.1.1" } }); MatterDefinition.children.push(bool); diff --git a/packages/model/src/standard/elements/cluster-id.ts b/packages/model/src/standard/elements/cluster-id.ts index 449d192efe..f78c83c2a6 100644 --- a/packages/model/src/standard/elements/cluster-id.ts +++ b/packages/model/src/standard/elements/cluster-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const clusterId = Datatype({ "\n" + "Cluster IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation are " + "described in Data Model Types.", - xref: { document: "core", section: "7.18.2.26" } + xref: { document: "core", section: "7.19.2.26" } }); MatterDefinition.children.push(clusterId); diff --git a/packages/model/src/standard/elements/command-id.ts b/packages/model/src/standard/elements/command-id.ts index 8643a34afe..faffaddc69 100644 --- a/packages/model/src/standard/elements/command-id.ts +++ b/packages/model/src/standard/elements/command-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const commandId = Datatype({ "\n" + "Command IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation are " + "described in Data Model Types.", - xref: { document: "core", section: "7.18.2.30" } + xref: { document: "core", section: "7.19.2.30" } }); MatterDefinition.children.push(commandId); diff --git a/packages/model/src/standard/elements/data-ver.ts b/packages/model/src/standard/elements/data-ver.ts index 88c0d5d66a..3957d77976 100644 --- a/packages/model/src/standard/elements/data-ver.ts +++ b/packages/model/src/standard/elements/data-ver.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,7 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const dataVer = Datatype({ name: "data-ver", type: "uint32", description: "Data Version", isSeed: true, - details: "An unsigned number that indicates a Data Version.", - xref: { document: "core", section: "7.18.2.34" } + details: "An unsigned number that indicates a Data Version Type.", + xref: { document: "core", section: "7.19.2.34" } }); MatterDefinition.children.push(dataVer); diff --git a/packages/model/src/standard/elements/date.ts b/packages/model/src/standard/elements/date.ts index bc81ed02b6..0cba86aaef 100644 --- a/packages/model/src/standard/elements/date.ts +++ b/packages/model/src/standard/elements/date.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,19 +13,19 @@ export const date = Datatype( { name: "date", type: "struct", description: "Date", isSeed: true, metatype: "date", details: "This data type shall be a struct as defined below.", - xref: { document: "core", section: "7.18.2.4" } + xref: { document: "core", section: "7.19.2.4" } }, Field({ name: "Year", id: 0x0, type: "uint8", conformance: "M", default: null, quality: "X", details: "The year subfield represents years from 1900 (0) to 2155 (255).", - xref: { document: "core", section: "7.18.2.4.1" } + xref: { document: "core", section: "7.19.2.4.1" } }), Field({ name: "Month", id: 0x1, type: "uint8", conformance: "M", constraint: "1 to 12", default: null, quality: "X", details: "This field represents months January (1) to December (12).", - xref: { document: "core", section: "7.18.2.4.2" } + xref: { document: "core", section: "7.19.2.4.2" } }), Field({ @@ -33,14 +33,14 @@ export const date = Datatype( quality: "X", details: "This field represents the day of the month. Note that values in the range 29 to 31 may be invalid, " + "depending on the month and year.", - xref: { document: "core", section: "7.18.2.4.3" } + xref: { document: "core", section: "7.19.2.4.3" } }), Field({ name: "DayOfWeek", id: 0x3, type: "uint8", conformance: "M", constraint: "1 to 7", default: null, quality: "X", details: "This represents the day of the week from Monday (1) to Sunday (7).", - xref: { document: "core", section: "7.18.2.4.4" } + xref: { document: "core", section: "7.19.2.4.4" } }) ); diff --git a/packages/model/src/standard/elements/definitions.ts b/packages/model/src/standard/elements/definitions.ts index 4b980bf82d..da30b57e3b 100644 --- a/packages/model/src/standard/elements/definitions.ts +++ b/packages/model/src/standard/elements/definitions.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,6 @@ export * from "./Groups.js"; export * from "./ScenesManagement.js"; export * from "./OnOff.js"; export * from "./LevelControl.js"; -export * from "./PulseWidthModulation.js"; export * from "./BooleanState.js"; export * from "./BooleanStateConfiguration.js"; export * from "./ModeSelect.js"; @@ -22,6 +21,7 @@ export * from "./Switch.js"; export * from "./OperationalState.js"; export * from "./AlarmBase.js"; export * from "./Messages.js"; +export * from "./ServiceArea.js"; export * from "./IlluminanceMeasurement.js"; export * from "./TemperatureMeasurement.js"; export * from "./PressureMeasurement.js"; @@ -31,6 +31,7 @@ export * from "./OccupancySensing.js"; export * from "./ResourceMonitoring.js"; export * from "./HepaFilterMonitoring.js"; export * from "./ActivatedCarbonFilterMonitoring.js"; +export * from "./WaterTankLevelMonitoring.js"; export * from "./AirQuality.js"; export * from "./ConcentrationMeasurement.js"; export * from "./CarbonMonoxideConcentrationMeasurement.js"; @@ -85,8 +86,13 @@ export * from "./MicrowaveOvenControl.js"; export * from "./DeviceEnergyManagement.js"; export * from "./EnergyEvse.js"; export * from "./EnergyEvseMode.js"; +export * from "./WaterHeaterManagement.js"; +export * from "./WaterHeaterMode.js"; export * from "./EnergyPreference.js"; export * from "./DeviceEnergyManagementMode.js"; +export * from "./WiFiNetworkManagement.js"; +export * from "./ThreadBorderRouterManagement.js"; +export * from "./ThreadNetworkDirectory.js"; export * from "./Descriptor.js"; export * from "./Binding.js"; export * from "./Label.js"; @@ -99,6 +105,7 @@ export * from "./ProxyDiscovery.js"; export * from "./ProxyConfiguration.js"; export * from "./ValidProxies.js"; export * from "./IcdManagement.js"; +export * from "./EcosystemInformation.js"; export * from "./BasicInformation.js"; export * from "./GroupKeyManagement.js"; export * from "./LocalizationConfiguration.js"; @@ -120,9 +127,14 @@ export * from "./OperationalCredentials.js"; export * from "./AdministratorCommissioning.js"; export * from "./OtaSoftwareUpdateProvider.js"; export * from "./OtaSoftwareUpdateRequestor.js"; +export * from "./JointFabricDatastoreCluster.js"; +export * from "./JointFabricPki.js"; +export * from "./CommissionerControl.js"; export * from "./MeasurementTypeEnum.js"; export * from "./MeasurementAccuracyRangeStruct.js"; export * from "./MeasurementAccuracyStruct.js"; +export * from "./AtomicRequestTypeEnum.js"; +export * from "./AtomicAttributeStatusStruct.js"; export * from "./bool.js"; export * from "./map8.js"; export * from "./map16.js"; @@ -194,6 +206,7 @@ export * from "./hwadr.js"; export * from "./semtag.js"; export * from "./namespace.js"; export * from "./tag.js"; +export * from "./locationdesc.js"; export * from "./WildcardPathFlagsBitmap.js"; export * from "./SoftwareVersionCertificationStatusEnum.js"; export * from "./any.js"; @@ -213,12 +226,16 @@ export * from "./OtaProviderDT.js"; export * from "./BridgedNodeDT.js"; export * from "./ElectricalSensorDT.js"; export * from "./DeviceEnergyManagementDT.js"; +export * from "./SecondaryNetworkInterfaceDT.js"; +export * from "./JointFabricAdministratorDT.js"; export * from "./OnOffLightDT.js"; export * from "./DimmableLightDT.js"; export * from "./ColorTemperatureLightDT.js"; export * from "./ExtendedColorLightDT.js"; export * from "./OnOffPlugInUnitDT.js"; export * from "./DimmablePlugInUnitDT.js"; +export * from "./MountedOnOffControlDT.js"; +export * from "./MountedDimmableLoadControlDT.js"; export * from "./PumpDT.js"; export * from "./WaterValveDT.js"; export * from "./OnOffLightSwitchDT.js"; @@ -267,6 +284,12 @@ export * from "./CooktopDT.js"; export * from "./OvenDT.js"; export * from "./ExtractorHoodDT.js"; export * from "./MicrowaveOvenDT.js"; +export * from "./EnergyEvseDT.js"; +export * from "./WaterHeaterDT.js"; +export * from "./SolarPowerDT.js"; +export * from "./BatteryStorageDT.js"; +export * from "./HeatPumpDT.js"; +export * from "./NetworkInfrastructureManagerDT.js"; export * from "./ClosureNS.js"; export * from "./CompassDirectionNS.js"; export * from "./CompassLocationNS.js"; @@ -275,7 +298,10 @@ export * from "./LevelNS.js"; export * from "./LocationNS.js"; export * from "./NumberNS.js"; export * from "./PositionNS.js"; +export * from "./LandmarkNamespaceNS.js"; +export * from "./RelativePositionNS.js"; export * from "./ElectricalMeasurementNS.js"; +export * from "./AreaNamespaceNS.js"; export * from "./LaundryNS.js"; export * from "./PowerSourceNS.js"; export * from "./RefrigeratorNS.js"; diff --git a/packages/model/src/standard/elements/devtype-id.ts b/packages/model/src/standard/elements/devtype-id.ts index 524d2d293f..1abed7d1ea 100644 --- a/packages/model/src/standard/elements/devtype-id.ts +++ b/packages/model/src/standard/elements/devtype-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const devtypeId = Datatype({ "\n" + "Device Type IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation " + "are described in Data Model Types.", - xref: { document: "core", section: "7.18.2.25" } + xref: { document: "core", section: "7.19.2.25" } }); MatterDefinition.children.push(devtypeId); diff --git a/packages/model/src/standard/elements/double.ts b/packages/model/src/standard/elements/double.ts index 599ace4a12..190278aff3 100644 --- a/packages/model/src/standard/elements/double.ts +++ b/packages/model/src/standard/elements/double.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,7 +20,7 @@ export const double = Datatype({ "\n" + "See IEEE 754-2019 for more details on the representable values.", - xref: { document: "core", section: "7.18.1.6" } + xref: { document: "core", section: "7.19.1.6" } }); MatterDefinition.children.push(double); diff --git a/packages/model/src/standard/elements/elapsed-s.ts b/packages/model/src/standard/elements/elapsed-s.ts index e38ce6727f..95c2b63648 100644 --- a/packages/model/src/standard/elements/elapsed-s.ts +++ b/packages/model/src/standard/elements/elapsed-s.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ export const elapsedS = Datatype({ name: "elapsed-s", type: "uint32", description: "Elapsed Time in seconds", isSeed: true, details: "Elapsed time in seconds is an unsigned 32-bit value representing the time that has elapsed for an " + "operation or other activity, as determined by the definition of the attribute using this type.", - xref: { document: "core", section: "7.18.2.10" } + xref: { document: "core", section: "7.19.2.10" } }); MatterDefinition.children.push(elapsedS); diff --git a/packages/model/src/standard/elements/endpoint-no.ts b/packages/model/src/standard/elements/endpoint-no.ts index 7a722a7d04..d37bc3697a 100644 --- a/packages/model/src/standard/elements/endpoint-no.ts +++ b/packages/model/src/standard/elements/endpoint-no.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,9 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const endpointNo = Datatype({ name: "endpoint-no", type: "uint16", description: "Endpoint Number", isSeed: true, - details: "An unsigned number that indicates an instance of a device type.", - xref: { document: "core", section: "7.18.2.23" } + details: "An unsigned number that indicates an instance of a device type. Endpoint numbers shall NOT be " + + "0xFFFF, to allow all endpoint number values to be expressible in nullable endpoint-no fields.", + xref: { document: "core", section: "7.19.2.23" } }); + MatterDefinition.children.push(endpointNo); diff --git a/packages/model/src/standard/elements/energy-mWh.ts b/packages/model/src/standard/elements/energy-mWh.ts index a31d99237c..f89ac5ba06 100644 --- a/packages/model/src/standard/elements/energy-mWh.ts +++ b/packages/model/src/standard/elements/energy-mWh.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const energyMWh = Datatype({ name: "energy-mWh", type: "int64", description: "Energy", isSeed: true, details: "This type represents energy measured in milliwatt-hours.", - xref: { document: "core", section: "7.18.2.15" } + xref: { document: "core", section: "7.19.2.15" } }); MatterDefinition.children.push(energyMWh); diff --git a/packages/model/src/standard/elements/entry-idx.ts b/packages/model/src/standard/elements/entry-idx.ts index 33937c5018..ef15bab136 100644 --- a/packages/model/src/standard/elements/entry-idx.ts +++ b/packages/model/src/standard/elements/entry-idx.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const entryIdx = Datatype({ name: "entry-idx", type: "uint16", description: "Entry Index", isSeed: true, details: "This is an index for a list data type.", - xref: { document: "core", section: "7.18.2.33" } + xref: { document: "core", section: "7.19.2.33" } }); MatterDefinition.children.push(entryIdx); diff --git a/packages/model/src/standard/elements/enum16.ts b/packages/model/src/standard/elements/enum16.ts index a2b0d33983..1e18bdf7b6 100644 --- a/packages/model/src/standard/elements/enum16.ts +++ b/packages/model/src/standard/elements/enum16.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const enum16 = Datatype({ name: "enum16", type: "uint16", description: "16-bit enumeration", isSeed: true, metatype: "enum", - xref: { document: "core", section: "7.18.2" } + xref: { document: "core", section: "7.19.2" } }) MatterDefinition.children.push(enum16); diff --git a/packages/model/src/standard/elements/enum8.ts b/packages/model/src/standard/elements/enum8.ts index 8e4f405938..ed782261c7 100644 --- a/packages/model/src/standard/elements/enum8.ts +++ b/packages/model/src/standard/elements/enum8.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const enum8 = Datatype({ name: "enum8", type: "uint8", description: "8-bit enumeration", isSeed: true, metatype: "enum", - xref: { document: "core", section: "7.18.2" } + xref: { document: "core", section: "7.19.2" } }) MatterDefinition.children.push(enum8); diff --git a/packages/model/src/standard/elements/epoch-s.ts b/packages/model/src/standard/elements/epoch-s.ts index e053c91b03..cd09bf6c9d 100644 --- a/packages/model/src/standard/elements/epoch-s.ts +++ b/packages/model/src/standard/elements/epoch-s.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -21,7 +21,7 @@ export const epochS = Datatype({ "This type is employed where compactness of representation is important and where the resolution of " + "seconds is still satisfactory.", - xref: { document: "core", section: "7.18.2.6" } + xref: { document: "core", section: "7.19.2.6" } }); MatterDefinition.children.push(epochS); diff --git a/packages/model/src/standard/elements/epoch-us.ts b/packages/model/src/standard/elements/epoch-us.ts index aa75d22a81..c2e5e39559 100644 --- a/packages/model/src/standard/elements/epoch-us.ts +++ b/packages/model/src/standard/elements/epoch-us.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -71,7 +71,7 @@ export const epochUs = Datatype( "UTC Epoch Time = (NTP(s) - 0xBC17C200)*10^6 + ((NTP(frac32)*10^6) / 2^32) where all numbers are " + "treated as unsigned 64-bit integers and the division is integer division.", - xref: { document: "core", section: "7.18.2.5" } + xref: { document: "core", section: "7.19.2.5" } } ); diff --git a/packages/model/src/standard/elements/event-id.ts b/packages/model/src/standard/elements/event-id.ts index 9362083f1b..1814c767a0 100644 --- a/packages/model/src/standard/elements/event-id.ts +++ b/packages/model/src/standard/elements/event-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const eventId = Datatype({ "\n" + "Event IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation are " + "described in Data Model Types.", - xref: { document: "core", section: "7.18.2.29" } + xref: { document: "core", section: "7.19.2.29" } }); MatterDefinition.children.push(eventId); diff --git a/packages/model/src/standard/elements/event-no.ts b/packages/model/src/standard/elements/event-no.ts index c22f7f9c9d..ca95ae9097 100644 --- a/packages/model/src/standard/elements/event-no.ts +++ b/packages/model/src/standard/elements/event-no.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const eventNo = Datatype({ name: "event-no", type: "uint64", description: "Event Number", isSeed: true, details: "An unsigned number that indicates an Event instance.", - xref: { document: "core", section: "7.18.2.35" } + xref: { document: "core", section: "7.19.2.35" } }); MatterDefinition.children.push(eventNo); diff --git a/packages/model/src/standard/elements/fabric-id.ts b/packages/model/src/standard/elements/fabric-id.ts index 5523a0a886..a688d72cd5 100644 --- a/packages/model/src/standard/elements/fabric-id.ts +++ b/packages/model/src/standard/elements/fabric-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const fabricId = Datatype({ name: "fabric-id", type: "uint64", description: "Fabric ID", isSeed: true, details: "A value to identify a fabric.", - xref: { document: "core", section: "7.18.2.19" } + xref: { document: "core", section: "7.19.2.19" } }); MatterDefinition.children.push(fabricId); diff --git a/packages/model/src/standard/elements/fabric-idx.ts b/packages/model/src/standard/elements/fabric-idx.ts index af9dfd5ab7..e97b55f90e 100644 --- a/packages/model/src/standard/elements/fabric-idx.ts +++ b/packages/model/src/standard/elements/fabric-idx.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -16,7 +16,7 @@ export const fabricIdx = Datatype({ " • the accessing fabric index of an interaction" + "\n" + " • the FabricIndex global field in fabric-scoped data", - xref: { document: "core", section: "7.18.2.20" } + xref: { document: "core", section: "7.19.2.20" } }); MatterDefinition.children.push(fabricIdx); diff --git a/packages/model/src/standard/elements/field-id.ts b/packages/model/src/standard/elements/field-id.ts index ca4899cb5e..2952e93e68 100644 --- a/packages/model/src/standard/elements/field-id.ts +++ b/packages/model/src/standard/elements/field-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const fieldId = Datatype({ "\n" + "Field IDs shall be a Manufacturer Extensible Identifier. The specifics of its representation are " + "described in Data Model Types.", - xref: { document: "core", section: "7.18.2.28" } + xref: { document: "core", section: "7.19.2.28" } }); MatterDefinition.children.push(fieldId); diff --git a/packages/model/src/standard/elements/group-id.ts b/packages/model/src/standard/elements/group-id.ts index 261e63dc24..4b598e8261 100644 --- a/packages/model/src/standard/elements/group-id.ts +++ b/packages/model/src/standard/elements/group-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ export const groupId = Datatype({ name: "group-id", type: "uint16", description: "Group ID", isSeed: true, details: "A 16-bit ID for a group scoped to a particular fabric as indicated by an accompanying fabric index " + "adjacent instantiation.", - xref: { document: "core", section: "7.18.2.22" } + xref: { document: "core", section: "7.19.2.22" } }); MatterDefinition.children.push(groupId); diff --git a/packages/model/src/standard/elements/hwadr.ts b/packages/model/src/standard/elements/hwadr.ts index ae5eae677d..e5285f7ef3 100644 --- a/packages/model/src/standard/elements/hwadr.ts +++ b/packages/model/src/standard/elements/hwadr.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ export const hwadr = Datatype({ details: "The Hardware Address data type shall be either a 48-bit IEEE MAC Address or a 64-bit IEEE MAC " + "Address (e.g. EUI-64). The order of bytes is Big-Endian or display mode, where the first byte in " + "the string is the left most or highest order byte.", - xref: { document: "core", section: "7.18.2.41" } + xref: { document: "core", section: "7.19.2.41" } }); MatterDefinition.children.push(hwadr); diff --git a/packages/model/src/standard/elements/int16.ts b/packages/model/src/standard/elements/int16.ts index 0cdf90a5a5..0ba7dd7e34 100644 --- a/packages/model/src/standard/elements/int16.ts +++ b/packages/model/src/standard/elements/int16.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const int16 = Datatype({ name: "int16", byteSize: 2, description: "Signed 16-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(int16); diff --git a/packages/model/src/standard/elements/int24.ts b/packages/model/src/standard/elements/int24.ts index 378dd0ffa3..2f978d4f39 100644 --- a/packages/model/src/standard/elements/int24.ts +++ b/packages/model/src/standard/elements/int24.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const int24 = Datatype({ name: "int24", byteSize: 3, description: "Signed 24-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(int24); diff --git a/packages/model/src/standard/elements/int32.ts b/packages/model/src/standard/elements/int32.ts index 6428d640be..721d76e41b 100644 --- a/packages/model/src/standard/elements/int32.ts +++ b/packages/model/src/standard/elements/int32.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const int32 = Datatype({ name: "int32", byteSize: 4, description: "Signed 32-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(int32); diff --git a/packages/model/src/standard/elements/int40.ts b/packages/model/src/standard/elements/int40.ts index 06833faa76..34adf8ed62 100644 --- a/packages/model/src/standard/elements/int40.ts +++ b/packages/model/src/standard/elements/int40.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const int40 = Datatype({ name: "int40", byteSize: 5, description: "Signed 40-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(int40); diff --git a/packages/model/src/standard/elements/int48.ts b/packages/model/src/standard/elements/int48.ts index 29c93fc807..a01de67b47 100644 --- a/packages/model/src/standard/elements/int48.ts +++ b/packages/model/src/standard/elements/int48.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const int48 = Datatype({ name: "int48", byteSize: 6, description: "Signed 48-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(int48); diff --git a/packages/model/src/standard/elements/int56.ts b/packages/model/src/standard/elements/int56.ts index f7349c85c7..b310c60fbe 100644 --- a/packages/model/src/standard/elements/int56.ts +++ b/packages/model/src/standard/elements/int56.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const int56 = Datatype({ name: "int56", byteSize: 7, description: "Signed 56-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(int56); diff --git a/packages/model/src/standard/elements/int64.ts b/packages/model/src/standard/elements/int64.ts index 5ae7389d5c..cd80a2f461 100644 --- a/packages/model/src/standard/elements/int64.ts +++ b/packages/model/src/standard/elements/int64.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const int64 = Datatype({ name: "int64", byteSize: 8, description: "Signed 64-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(int64); diff --git a/packages/model/src/standard/elements/int8.ts b/packages/model/src/standard/elements/int8.ts index c42b228e11..535b9442a5 100644 --- a/packages/model/src/standard/elements/int8.ts +++ b/packages/model/src/standard/elements/int8.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const int8 = Datatype({ name: "int8", byteSize: 1, description: "Signed 8-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(int8); diff --git a/packages/model/src/standard/elements/ipadr.ts b/packages/model/src/standard/elements/ipadr.ts index 073363b844..118bb4c38a 100644 --- a/packages/model/src/standard/elements/ipadr.ts +++ b/packages/model/src/standard/elements/ipadr.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const ipadr = Datatype({ name: "ipadr", type: "octstr", description: "IP Address", isSeed: true, - details: "Either an IPv4 or an IPv6 address as defined below.", - xref: { document: "core", section: "7.18.2.37" } + xref: { document: "core", section: "7.19.2" } }); MatterDefinition.children.push(ipadr); diff --git a/packages/model/src/standard/elements/ipv4adr.ts b/packages/model/src/standard/elements/ipv4adr.ts index bb7e1c15bf..566a9a1913 100644 --- a/packages/model/src/standard/elements/ipv4adr.ts +++ b/packages/model/src/standard/elements/ipv4adr.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,7 @@ export const ipv4Adr = Datatype({ "\n" + " • Address 10.4.200.75 → 0A04C84B", - xref: { document: "core", section: "7.18.2.38" } + xref: { document: "core", section: "7.19.2.38" } }); MatterDefinition.children.push(ipv4Adr); diff --git a/packages/model/src/standard/elements/ipv6adr.ts b/packages/model/src/standard/elements/ipv6adr.ts index a2dbaa43d9..0fc6dc4bda 100644 --- a/packages/model/src/standard/elements/ipv6adr.ts +++ b/packages/model/src/standard/elements/ipv6adr.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,7 @@ export const ipv6Adr = Datatype({ "\n" + " • Address 2001:0DB8:1122:3344:5566:7788:99AA:BBCC → 20010DB8112233445566778899AABBCC", - xref: { document: "core", section: "7.18.2.39" } + xref: { document: "core", section: "7.19.2.39" } }); MatterDefinition.children.push(ipv6Adr); diff --git a/packages/model/src/standard/elements/ipv6pre.ts b/packages/model/src/standard/elements/ipv6pre.ts index efb22436a4..2b7fba20c8 100644 --- a/packages/model/src/standard/elements/ipv6pre.ts +++ b/packages/model/src/standard/elements/ipv6pre.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -31,7 +31,7 @@ export const ipv6Pre = Datatype({ "\n" + " • Allowed non-minimal encoding: Prefix 2001:0DB8:BB00::/40 → 7 octets → 2820010DB8BB00", - xref: { document: "core", section: "7.18.2.40" } + xref: { document: "core", section: "7.19.2.40" } }); MatterDefinition.children.push(ipv6Pre); diff --git a/packages/model/src/standard/elements/list.ts b/packages/model/src/standard/elements/list.ts index 354396bb5b..7d3ce42f10 100644 --- a/packages/model/src/standard/elements/list.ts +++ b/packages/model/src/standard/elements/list.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -9,98 +9,84 @@ import { MatterDefinition } from "../MatterDefinition.js"; import { DatatypeElement as Datatype } from "../../elements/index.js"; -export const list = Datatype( - { - name: "list", description: "List", isSeed: true, metatype: "array", +export const list = Datatype({ + name: "list", description: "List", isSeed: true, metatype: "array", - details: "A list is defined as a collection of entries of the same data type, with a finite count from 0 to " + - "65534. A cluster specification may define further constraints on the maximum possible count. The " + - "list entry data type shall be any defined data type, except a list data type, or any data type " + - "derived from a list." + - "\n" + - "The quality columns for a list definition are for the list." + - "\n" + - "The list entries are indicated with an index that is an unsigned integer starting at 0 (zero). The " + - "maintained order of entries, by index, is defined in the cluster specification, or undefined. Data " + - "that is defined as a list is indicated with \"list[X]\" where X is the entry type. The data type of " + - "the list entry has its own qualities, constraints, and conformance." + - "\n" + - "### To define qualities for the list entry data type, make the list entry data type a defined local " + - "derived data type, with a table including the columns required to define and constrain the data " + - "type." + - "\n" + - "There is an inline shortcut to define the list entry data type constraints. See List Constraints." + - "\n" + - "It is recommended to put a maximum constraint on the list and list entry data types." + - "\n" + - "It is recommended that a list entry data type be a struct, to enable the addition of new fields to " + - "the list’s entries in the future." + - "\n" + - " • The cluster data version shall be incremented when the list order or entries change." + - "\n" + - " • An entry shall NOT be null." + - "\n" + - " • The list shall support reading and reporting all entries." + - "\n" + - " • The list shall support reporting, updates, and/or deletion of one or more entries." + - "\n" + - " • If the list is writable, it shall support writing or deleting the entire list." + - "\n" + - " • If the list is writable, it shall support updating one or more individual entries by indicating " + - " an index per updated entry." + - "\n" + - " • If the list is writable, it shall support deleting one or more individual entries by indicating " + - " an index per deleted entry." + - "\n" + - " • If the list is writable, it shall support adding one or more individual entries." + - "\n" + - " • A list may define an entry that is a struct that is fabric-scoped (see Fabric-Scoped Quality)." + - "\n" + - "### Fabric-Scoped List" + - "\n" + - " • A fabric-scoped list shall define an entry data type that is a struct, which shall also be " + - " fabric-scoped (see Fabric-Scoped Struct)." + - "\n" + - "Each entry in a fabric-scoped list shall be fabric-scoped to a particular fabric or no fabric." + - "\n" + - "### A fabric-scoped list supports a fabric-filter that filters the view of the list for read and " + - "write interactions. This filter simplifies client side logic that does not want to read or write " + - "fabric data that is not associated with the accessing fabric." + - "\n" + - " • An interaction upon a list with fabric-filtering shall only indicate and access entries where " + - " the associated fabric matches the accessing fabric, and all other entries shall be ignored." + - "\n" + - " • Fabric-filtered list entries shall be in the same order as the full list." + - "\n" + - " • Fabric-filtered list entries shall be indexed from 0 with no gaps, as if the other entries did " + - " not exist." + - "\n" + - " • For a write interaction, fabric-filtering shall be enabled." + - "\n" + - " • When writing to a fabric-scoped list, the write interaction shall be on an accessing fabric, " + - " otherwise, the write interaction shall fail (see Interaction Model)." + - "\n" + - " • For a read interaction on a list, fabric-filtering may be enabled." + - "\n" + - " • For a read interaction on a list, with fabric-filtering disabled, the list shall be reported as " + - " a full list with all entries." + - "\n" + - "list[1] = [ { FabricIndex = B, Value = 55 } ]" + - "\n" + - "changes the full list to:" + - "\n" + - "list = [ { FabricIndex = A, Value = 20 }," + - "\n" + - "{ FabricIndex = B, Value = 30 }," + - "\n" + - "{ FabricIndex = A, Value = 40 }," + - "\n" + - "{ FabricIndex = B, Value = 55 }," + - "\n" + - "{ FabricIndex = B, Value = 60 } ]", + details: "A list is defined as a collection of entries of the same data type, with a finite count from 0 to " + + "65534. A cluster specification may define further constraints on the maximum possible count. The " + + "list entry data type shall be any defined data type, except a list data type, or any data type " + + "derived from a list." + + "\n" + + "The quality columns for a list definition are for the list." + + "\n" + + "The list entries are indicated with an index that is an unsigned integer starting at 0 (zero). The " + + "maintained order of entries, by index, is defined in the cluster specification, or undefined. Data " + + "that is defined as a list is indicated with \"list[X]\" where X is the entry type. The data type of " + + "the list entry has its own qualities, constraints, and conformance." + + "\n" + + "### To define qualities for the list entry data type, make the list entry data type a defined local " + + "derived data type, with a table including the columns required to define and constrain the data " + + "type." + + "\n" + + "There is an inline shortcut to define the list entry data type constraints. See List Constraints." + + "\n" + + "It is recommended to put a maximum constraint on the list and list entry data types." + + "\n" + + "It is recommended that a list entry data type be a struct, to enable the addition of new fields to " + + "the list’s entries in the future." + + "\n" + + " • The cluster data version shall be incremented when the list order or entries change." + + "\n" + + " • An entry shall NOT be null." + + "\n" + + " • The list shall support reading and reporting all entries." + + "\n" + + " • The list shall support reporting, updates, and/or deletion of one or more entries." + + "\n" + + " • If the list is writable, it shall support writing or deleting the entire list." + + "\n" + + " • If the list is writable, it shall support updating one or more individual entries by indicating " + + " an index per updated entry." + + "\n" + + " • If the list is writable, it shall support deleting one or more individual entries by indicating " + + " an index per deleted entry." + + "\n" + + " • If the list is writable, it shall support adding one or more individual entries." + + "\n" + + " • A list may define an entry that is a struct that is fabric-scoped (see Fabric-Scoped Quality)." + + "\n" + + "### Fabric-Scoped List" + + "\n" + + " • A fabric-scoped list shall define an entry data type that is a struct, which shall also be " + + " fabric-scoped (see Fabric-Scoped Struct)." + + "\n" + + "Each entry in a fabric-scoped list shall be fabric-scoped to a particular fabric or no fabric." + + "\n" + + "### Fabric-Filtered List" + + "\n" + + "A fabric-scoped list supports a fabric-filter that filters the view of the list for read and write " + + "interactions. This filter simplifies client side logic that does not want to read or write fabric " + + "data that is not associated with the accessing fabric." + + "\n" + + " • An interaction upon a list with fabric-filtering shall only indicate and access entries where " + + " the associated fabric matches the accessing fabric, and all other entries shall be ignored." + + "\n" + + " • Fabric-filtered list entries shall be in the same order as the full list." + + "\n" + + " • Fabric-filtered list entries shall be indexed from 0 with no gaps, as if the other entries did " + + " not exist." + + "\n" + + " • For a write interaction, fabric-filtering shall be enabled." + + "\n" + + " • When writing to a fabric-scoped list, the write interaction shall be on an accessing fabric, " + + " otherwise, the write interaction shall fail (see Interaction Model)." + + "\n" + + " • For a read interaction on a list, fabric-filtering may be enabled." + + "\n" + + " • For a read interaction on a list, with fabric-filtering disabled, the list shall be reported as " + + " a full list with all entries.", - xref: { document: "core", section: "7.18.1.8" } - } -); + xref: { document: "core", section: "7.19.1.8" } +}); MatterDefinition.children.push(list); diff --git a/packages/model/src/standard/elements/locationdesc.ts b/packages/model/src/standard/elements/locationdesc.ts new file mode 100644 index 0000000000..6e04844613 --- /dev/null +++ b/packages/model/src/standard/elements/locationdesc.ts @@ -0,0 +1,80 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MatterDefinition } from "../MatterDefinition.js"; +import { DatatypeElement as Datatype, FieldElement as Field } from "../../elements/index.js"; + +export const locationdesc = Datatype( + { + name: "locationdesc", type: "struct", description: "Location Descriptor", isSeed: true, + details: "This data type shall be represented by the following structure:", + xref: { document: "core", section: "7.19.2.45" } + }, + + Field({ + name: "LocationName", id: 0x0, type: "string", conformance: "M", constraint: "max 128", + details: "This field shall indicate the name of the location. For example, \"blue room\"." + + "\n" + + "If the location name is not user provided, the logic that generates it (clients, devices etc.) " + + "SHOULD utilize synthesized user-friendly, understandable, names for the location, rather than " + + "opaque values such as \"private\" or \"2fe7c241-a50a-4863-896e-c5878da5ed68\".", + xref: { document: "core", section: "7.19.2.45.1" } + }), + + Field({ + name: "FloorNumber", id: 0x1, type: "int16", conformance: "M", quality: "X", + + details: "This field shall indicate the level number. Negative values correspond to basement levels." + + "\n" + + "Value zero indicates this is the main floor, which typically includes the main entrance to the " + + "user’s home. For a building with multiple levels, it is the client’s responsibility to map each " + + "level to/from a FloorNumber tag value, using the level numbering convention of the region where the " + + "client operates. For example, if the client operates in Europe, building level 1, which is one " + + "level up from the street level, SHOULD be mapped to FloorNumber tag value 0x1. If the client " + + "operates in North America, building level 1, which is at street level, SHOULD be mapped to " + + "FloorNumber tag value 0x0." + + "\n" + + "A null value indicates that this information is not available." + + "\n" + + "When the clients present the level information for user selection, they SHOULD use the operating " + + "region to determine how to render and map this data. For example, if the client operates in North " + + "America it SHOULD present the user a list that includes entries labeled \"basement\", \"first\", " + + "\"second\", and internally mapped to floor numbers -1, 0, and 1. If operating in Europe, the client " + + "SHOULD present a list that includes entries labeled \"basement\", \"ground\", \"first\", internally " + + "mapped to floor numbers -1, 0, and 1." + + "\n" + + "The floor number information is expected to be mostly useful to the clients, rather than the " + + "devices, such as for grouping devices that are located on the same level. For example, an " + + "automation may be defined for all devices located at the basement level (floor number -1)." + + "\n" + + "NOTE" + + "\n" + + "Handling complex level situations, such as half levels (side split houses), or the levels from an " + + "apartment building, is up to the client and/or user.", + + xref: { document: "core", section: "7.19.2.45.2" } + }), + + Field({ + name: "AreaType", id: 0x2, type: "tag", conformance: "M", quality: "X", + + details: "This field shall be the ID of an area semantic tag, located within the Common Area Namespace. For " + + "example, this tag may indicate that the location refers to a bedroom." + + "\n" + + "If this field is null, that indicates that the area type information is not available." + + "\n" + + "NOTE" + + "\n" + + "This field only indicates the type of the area. Multiple areas of the same type, such as bedrooms, " + + "may exist in a user’s home.", + + xref: { document: "core", section: "7.19.2.45.3" } + }) +); + +MatterDefinition.children.push(locationdesc); diff --git a/packages/model/src/standard/elements/map16.ts b/packages/model/src/standard/elements/map16.ts index 76ec955905..8fb61b0521 100644 --- a/packages/model/src/standard/elements/map16.ts +++ b/packages/model/src/standard/elements/map16.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const map16 = Datatype({ name: "map16", byteSize: 2, description: "16-bit bitmap", isSeed: true, metatype: "bitmap", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(map16); diff --git a/packages/model/src/standard/elements/map32.ts b/packages/model/src/standard/elements/map32.ts index 0444a0b809..a69fcdb13d 100644 --- a/packages/model/src/standard/elements/map32.ts +++ b/packages/model/src/standard/elements/map32.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const map32 = Datatype({ name: "map32", byteSize: 4, description: "32-bit bitmap", isSeed: true, metatype: "bitmap", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(map32); diff --git a/packages/model/src/standard/elements/map64.ts b/packages/model/src/standard/elements/map64.ts index 1ef79674f4..edbd09f7bb 100644 --- a/packages/model/src/standard/elements/map64.ts +++ b/packages/model/src/standard/elements/map64.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const map64 = Datatype({ name: "map64", byteSize: 8, description: "64-bit bitmap", isSeed: true, metatype: "bitmap", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(map64); diff --git a/packages/model/src/standard/elements/map8.ts b/packages/model/src/standard/elements/map8.ts index 2cd406f7b0..cae6458e31 100644 --- a/packages/model/src/standard/elements/map8.ts +++ b/packages/model/src/standard/elements/map8.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const map8 = Datatype({ name: "map8", byteSize: 1, description: "8-bit bitmap", isSeed: true, metatype: "bitmap", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(map8); diff --git a/packages/model/src/standard/elements/models.ts b/packages/model/src/standard/elements/models.ts index d62a71b724..e3470c8775 100644 --- a/packages/model/src/standard/elements/models.ts +++ b/packages/model/src/standard/elements/models.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,6 @@ export const Groups = new ClusterModel(definitions.Groups); export const ScenesManagement = new ClusterModel(definitions.ScenesManagement); export const OnOff = new ClusterModel(definitions.OnOff); export const LevelControl = new ClusterModel(definitions.LevelControl); -export const PulseWidthModulation = new ClusterModel(definitions.PulseWidthModulation); export const BooleanState = new ClusterModel(definitions.BooleanState); export const BooleanStateConfiguration = new ClusterModel(definitions.BooleanStateConfiguration); export const ModeSelect = new ClusterModel(definitions.ModeSelect); @@ -30,6 +29,7 @@ export const Switch = new ClusterModel(definitions.Switch); export const OperationalState = new ClusterModel(definitions.OperationalState); export const AlarmBase = new ClusterModel(definitions.AlarmBase); export const Messages = new ClusterModel(definitions.Messages); +export const ServiceArea = new ClusterModel(definitions.ServiceArea); export const IlluminanceMeasurement = new ClusterModel(definitions.IlluminanceMeasurement); export const TemperatureMeasurement = new ClusterModel(definitions.TemperatureMeasurement); export const PressureMeasurement = new ClusterModel(definitions.PressureMeasurement); @@ -39,6 +39,7 @@ export const OccupancySensing = new ClusterModel(definitions.OccupancySensing); export const ResourceMonitoring = new ClusterModel(definitions.ResourceMonitoring); export const HepaFilterMonitoring = new ClusterModel(definitions.HepaFilterMonitoring); export const ActivatedCarbonFilterMonitoring = new ClusterModel(definitions.ActivatedCarbonFilterMonitoring); +export const WaterTankLevelMonitoring = new ClusterModel(definitions.WaterTankLevelMonitoring); export const AirQuality = new ClusterModel(definitions.AirQuality); export const ConcentrationMeasurement = new ClusterModel(definitions.ConcentrationMeasurement); export const CarbonMonoxideConcentrationMeasurement = new ClusterModel(definitions.CarbonMonoxideConcentrationMeasurement); @@ -93,8 +94,13 @@ export const MicrowaveOvenControl = new ClusterModel(definitions.MicrowaveOvenCo export const DeviceEnergyManagement = new ClusterModel(definitions.DeviceEnergyManagement); export const EnergyEvse = new ClusterModel(definitions.EnergyEvse); export const EnergyEvseMode = new ClusterModel(definitions.EnergyEvseMode); +export const WaterHeaterManagement = new ClusterModel(definitions.WaterHeaterManagement); +export const WaterHeaterMode = new ClusterModel(definitions.WaterHeaterMode); export const EnergyPreference = new ClusterModel(definitions.EnergyPreference); export const DeviceEnergyManagementMode = new ClusterModel(definitions.DeviceEnergyManagementMode); +export const WiFiNetworkManagement = new ClusterModel(definitions.WiFiNetworkManagement); +export const ThreadBorderRouterManagement = new ClusterModel(definitions.ThreadBorderRouterManagement); +export const ThreadNetworkDirectory = new ClusterModel(definitions.ThreadNetworkDirectory); export const Descriptor = new ClusterModel(definitions.Descriptor); export const Binding = new ClusterModel(definitions.Binding); export const Label = new ClusterModel(definitions.Label); @@ -107,6 +113,7 @@ export const ProxyDiscovery = new ClusterModel(definitions.ProxyDiscovery); export const ProxyConfiguration = new ClusterModel(definitions.ProxyConfiguration); export const ValidProxies = new ClusterModel(definitions.ValidProxies); export const IcdManagement = new ClusterModel(definitions.IcdManagement); +export const EcosystemInformation = new ClusterModel(definitions.EcosystemInformation); export const BasicInformation = new ClusterModel(definitions.BasicInformation); export const GroupKeyManagement = new ClusterModel(definitions.GroupKeyManagement); export const LocalizationConfiguration = new ClusterModel(definitions.LocalizationConfiguration); @@ -128,9 +135,14 @@ export const OperationalCredentials = new ClusterModel(definitions.OperationalCr export const AdministratorCommissioning = new ClusterModel(definitions.AdministratorCommissioning); export const OtaSoftwareUpdateProvider = new ClusterModel(definitions.OtaSoftwareUpdateProvider); export const OtaSoftwareUpdateRequestor = new ClusterModel(definitions.OtaSoftwareUpdateRequestor); +export const JointFabricDatastoreCluster = new ClusterModel(definitions.JointFabricDatastoreCluster); +export const JointFabricPki = new ClusterModel(definitions.JointFabricPki); +export const CommissionerControl = new ClusterModel(definitions.CommissionerControl); export const MeasurementTypeEnum = new DatatypeModel(definitions.MeasurementTypeEnum); export const MeasurementAccuracyRangeStruct = new DatatypeModel(definitions.MeasurementAccuracyRangeStruct); export const MeasurementAccuracyStruct = new DatatypeModel(definitions.MeasurementAccuracyStruct); +export const AtomicRequestTypeEnum = new DatatypeModel(definitions.AtomicRequestTypeEnum); +export const AtomicAttributeStatusStruct = new DatatypeModel(definitions.AtomicAttributeStatusStruct); export const bool = new DatatypeModel(definitions.bool); export const map8 = new DatatypeModel(definitions.map8); export const map16 = new DatatypeModel(definitions.map16); @@ -202,6 +214,7 @@ export const hwadr = new DatatypeModel(definitions.hwadr); export const semtag = new DatatypeModel(definitions.semtag); export const namespace = new DatatypeModel(definitions.namespace) export const tag = new DatatypeModel(definitions.tag); +export const locationdesc = new DatatypeModel(definitions.locationdesc); export const WildcardPathFlagsBitmap = new DatatypeModel(definitions.WildcardPathFlagsBitmap); export const SoftwareVersionCertificationStatusEnum = new DatatypeModel(definitions.SoftwareVersionCertificationStatusEnum); export const any = new DatatypeModel(definitions.any); @@ -221,12 +234,16 @@ export const OtaProviderDt = new DeviceTypeModel(definitions.OtaProviderDt); export const BridgedNodeDt = new DeviceTypeModel(definitions.BridgedNodeDt); export const ElectricalSensorDt = new DeviceTypeModel(definitions.ElectricalSensorDt); export const DeviceEnergyManagementDt = new DeviceTypeModel(definitions.DeviceEnergyManagementDt); +export const SecondaryNetworkInterfaceDt = new DeviceTypeModel(definitions.SecondaryNetworkInterfaceDt); +export const JointFabricAdministratorDt = new DeviceTypeModel(definitions.JointFabricAdministratorDt); export const OnOffLightDt = new DeviceTypeModel(definitions.OnOffLightDt); export const DimmableLightDt = new DeviceTypeModel(definitions.DimmableLightDt); export const ColorTemperatureLightDt = new DeviceTypeModel(definitions.ColorTemperatureLightDt); export const ExtendedColorLightDt = new DeviceTypeModel(definitions.ExtendedColorLightDt); export const OnOffPlugInUnitDt = new DeviceTypeModel(definitions.OnOffPlugInUnitDt); export const DimmablePlugInUnitDt = new DeviceTypeModel(definitions.DimmablePlugInUnitDt); +export const MountedOnOffControlDt = new DeviceTypeModel(definitions.MountedOnOffControlDt); +export const MountedDimmableLoadControlDt = new DeviceTypeModel(definitions.MountedDimmableLoadControlDt); export const PumpDt = new DeviceTypeModel(definitions.PumpDt); export const WaterValveDt = new DeviceTypeModel(definitions.WaterValveDt); export const OnOffLightSwitchDt = new DeviceTypeModel(definitions.OnOffLightSwitchDt); @@ -275,6 +292,12 @@ export const CooktopDt = new DeviceTypeModel(definitions.CooktopDt); export const OvenDt = new DeviceTypeModel(definitions.OvenDt); export const ExtractorHoodDt = new DeviceTypeModel(definitions.ExtractorHoodDt); export const MicrowaveOvenDt = new DeviceTypeModel(definitions.MicrowaveOvenDt); +export const EnergyEvseDt = new DeviceTypeModel(definitions.EnergyEvseDt); +export const WaterHeaterDt = new DeviceTypeModel(definitions.WaterHeaterDt); +export const SolarPowerDt = new DeviceTypeModel(definitions.SolarPowerDt); +export const BatteryStorageDt = new DeviceTypeModel(definitions.BatteryStorageDt); +export const HeatPumpDt = new DeviceTypeModel(definitions.HeatPumpDt); +export const NetworkInfrastructureManagerDt = new DeviceTypeModel(definitions.NetworkInfrastructureManagerDt); export const ClosureNs = new SemanticNamespaceModel(definitions.ClosureNs); export const CompassDirectionNs = new SemanticNamespaceModel(definitions.CompassDirectionNs); export const CompassLocationNs = new SemanticNamespaceModel(definitions.CompassLocationNs); @@ -283,7 +306,10 @@ export const LevelNs = new SemanticNamespaceModel(definitions.LevelNs); export const LocationNs = new SemanticNamespaceModel(definitions.LocationNs); export const NumberNs = new SemanticNamespaceModel(definitions.NumberNs); export const PositionNs = new SemanticNamespaceModel(definitions.PositionNs); +export const LandmarkNamespaceNs = new SemanticNamespaceModel(definitions.LandmarkNamespaceNs); +export const RelativePositionNs = new SemanticNamespaceModel(definitions.RelativePositionNs); export const ElectricalMeasurementNs = new SemanticNamespaceModel(definitions.ElectricalMeasurementNs); +export const AreaNamespaceNs = new SemanticNamespaceModel(definitions.AreaNamespaceNs); export const LaundryNs = new SemanticNamespaceModel(definitions.LaundryNs); export const PowerSourceNs = new SemanticNamespaceModel(definitions.PowerSourceNs); export const RefrigeratorNs = new SemanticNamespaceModel(definitions.RefrigeratorNs); diff --git a/packages/model/src/standard/elements/namespace.ts b/packages/model/src/standard/elements/namespace.ts index bea9704a14..9c9dbd22c9 100644 --- a/packages/model/src/standard/elements/namespace.ts +++ b/packages/model/src/standard/elements/namespace.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const namespace = Datatype({ name: "namespace", type: "uint8", description: "Namespace", isSeed: true, details: "The Namespace type identifies the namespace used for a semantic tag.", - xref: { document: "core", section: "7.18.2.43" } + xref: { document: "core", section: "7.19.2.43" } }) MatterDefinition.children.push(namespace); diff --git a/packages/model/src/standard/elements/node-id.ts b/packages/model/src/standard/elements/node-id.ts index fc4c1b859a..18c04543d9 100644 --- a/packages/model/src/standard/elements/node-id.ts +++ b/packages/model/src/standard/elements/node-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ export const nodeId = Datatype({ name: "node-id", type: "uint64", description: "Node ID", isSeed: true, details: "A 64-bit ID for a node scoped and unique to a particular fabric as indicated by an accompanying " + "fabric-index adjacent instantiation.", - xref: { document: "core", section: "7.18.2.21" } + xref: { document: "core", section: "7.19.2.21" } }); MatterDefinition.children.push(nodeId); diff --git a/packages/model/src/standard/elements/octstr.ts b/packages/model/src/standard/elements/octstr.ts index 0e02a80c5f..f255c01eb3 100644 --- a/packages/model/src/standard/elements/octstr.ts +++ b/packages/model/src/standard/elements/octstr.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ export const octstr = Datatype({ name: "octstr", description: "Octet string", isSeed: true, metatype: "bytes", details: "The octet string data type defines a sequence of octets with a finite octet count from 0 to 65534. " + "It is recommended to define a constraint on the maximum possible count.", - xref: { document: "core", section: "7.18.1.7" } + xref: { document: "core", section: "7.19.1.7" } }); MatterDefinition.children.push(octstr); diff --git a/packages/model/src/standard/elements/percent.ts b/packages/model/src/standard/elements/percent.ts index dd8b2dd955..7c1f50b308 100644 --- a/packages/model/src/standard/elements/percent.ts +++ b/packages/model/src/standard/elements/percent.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const percent = Datatype({ name: "percent", type: "uint8", description: "Percentage units 1%", isSeed: true, - xref: { document: "core", section: "7.18.2" } + xref: { document: "core", section: "7.19.2" } }); MatterDefinition.children.push(percent); diff --git a/packages/model/src/standard/elements/percent100ths.ts b/packages/model/src/standard/elements/percent100ths.ts index 077f465a40..acf5b461df 100644 --- a/packages/model/src/standard/elements/percent100ths.ts +++ b/packages/model/src/standard/elements/percent100ths.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const percent100ths = Datatype({ name: "percent100ths", type: "uint16", description: "Percentage units 0.01%", isSeed: true, - xref: { document: "core", section: "7.18.2" } + xref: { document: "core", section: "7.19.2" } }); MatterDefinition.children.push(percent100ths); diff --git a/packages/model/src/standard/elements/posix-ms.ts b/packages/model/src/standard/elements/posix-ms.ts index 0177555312..dcf18f211e 100644 --- a/packages/model/src/standard/elements/posix-ms.ts +++ b/packages/model/src/standard/elements/posix-ms.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const posixMs = Datatype({ "encoded as an unsigned 64-bit scalar value." + "\n" + "This type is employed for compatibility reasons.", - xref: { document: "core", section: "7.18.2.7" } + xref: { document: "core", section: "7.19.2.7" } }); MatterDefinition.children.push(posixMs); diff --git a/packages/model/src/standard/elements/power-mW.ts b/packages/model/src/standard/elements/power-mW.ts index a787ab0a8f..0ed915aa41 100644 --- a/packages/model/src/standard/elements/power-mW.ts +++ b/packages/model/src/standard/elements/power-mW.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const powerMW = Datatype({ name: "power-mW", type: "int64", description: "Power", isSeed: true, details: "This type represents power measured in milliwatts.", - xref: { document: "core", section: "7.18.2.12" } + xref: { document: "core", section: "7.19.2.12" } }); MatterDefinition.children.push(powerMW); diff --git a/packages/model/src/standard/elements/priority.ts b/packages/model/src/standard/elements/priority.ts index 8f49a0d5ac..7d139fd486 100644 --- a/packages/model/src/standard/elements/priority.ts +++ b/packages/model/src/standard/elements/priority.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const priority = Datatype( details: "This is an enumeration of priority used to tag events and possibly other data. The data type does " + "not define any particular ordering among the values. Specific uses of the data type may assign " + "semantics to the values that imply an ordering relationship.", - xref: { document: "core", section: "7.18.2.17" } + xref: { document: "core", section: "7.19.2.17" } }, Field({ name: "Debug", id: 0x0, description: "Information for engineering debugging/troubleshooting" }), diff --git a/packages/model/src/standard/elements/semtag.ts b/packages/model/src/standard/elements/semtag.ts index e316c460ca..f75934408d 100644 --- a/packages/model/src/standard/elements/semtag.ts +++ b/packages/model/src/standard/elements/semtag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ export const semtag = Datatype( { name: "semtag", type: "struct", description: "Semantic Tag", isSeed: true, details: "This data type shall be represented by the following structure:", - xref: { document: "core", section: "7.18.2.42" } + xref: { document: "core", section: "7.19.2.42" } }, Field({ @@ -30,7 +30,7 @@ export const semtag = Datatype( "\n" + "If MfgCode is null, the NamespaceID field shall indicate a standard namespace.", - xref: { document: "core", section: "7.18.2.42.1" } + xref: { document: "core", section: "7.19.2.42.1" } }), Field({ @@ -38,7 +38,7 @@ export const semtag = Datatype( details: "The NamespaceID field shall identify a namespace." + "\n" + "The common and device-specific semantic tag namespaces are listed in StandardNamespaces.", - xref: { document: "core", section: "7.18.2.42.2" } + xref: { document: "core", section: "7.19.2.42.2" } }), Field({ @@ -48,7 +48,7 @@ export const semtag = Datatype( "\n" + "A device may expose tags from the common or device-specific namespaces and from " + "manufacturer-specific namespaces in a single TagList.", - xref: { document: "core", section: "7.18.2.42.3" } + xref: { document: "core", section: "7.19.2.42.3" } }), Field({ @@ -63,7 +63,7 @@ export const semtag = Datatype( "that has the meaning of \"room\" in a location namespace, would require the a label string to qualify " + "the type of room, such as \"1\", \"2b\", \"Bathroom\", etc.", - xref: { document: "core", section: "7.18.2.42.4" } + xref: { document: "core", section: "7.19.2.42.4" } }) ); diff --git a/packages/model/src/standard/elements/single.ts b/packages/model/src/standard/elements/single.ts index 0dc5ef904d..5015180756 100644 --- a/packages/model/src/standard/elements/single.ts +++ b/packages/model/src/standard/elements/single.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const single = Datatype({ name: "single", byteSize: 4, description: "Single precision", isSeed: true, metatype: "float", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(single); diff --git a/packages/model/src/standard/elements/status.ts b/packages/model/src/standard/elements/status.ts index 0241adaba2..0545b32f27 100644 --- a/packages/model/src/standard/elements/status.ts +++ b/packages/model/src/standard/elements/status.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -27,7 +27,7 @@ export const status = Datatype( "Status codes in an undefined range, or status codes undefined within a range are reserved and shall " + "NOT be indicated.", - xref: { document: "core", section: "7.18.2.18" } + xref: { document: "core", section: "7.19.2.18" } }, Field({ @@ -123,6 +123,11 @@ export const status = Datatype( description: "The receiver is busy processing another action that prevents the execution of the incoming action.", xref: { document: "core", section: "8.10.1" } }), + Field({ + name: "AccessRestricted", id: 0x9d, + description: "The access to the action or command by the sender is permitted by the ACL but restricted by the ARL.", + xref: { document: "core", section: "8.10.1" } + }), Field({ name: "UnsupportedCluster", id: 0xc3, description: "The cluster indicated is not supported on the endpoint.", @@ -167,6 +172,16 @@ export const status = Datatype( name: "NoCommandResponse", id: 0xcc, description: "A CommandDataIB is missing a response in the InvokeResponses of an Invoke Response action.", xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "TermsAndConditionsChanged", id: 0xcd, + description: "The node requires updated TC acceptance. The user MAY be directed to visit the EnhancedSetupFlowMaintenanceUrl to complete this.", + xref: { document: "core", section: "8.10.1" } + }), + Field({ + name: "MaintenanceRequired", id: 0xce, + description: "The node requires the user to visit the EnhancedSetupFlowMaintenanceUrl for instructions on further action.", + xref: { document: "core", section: "8.10.1" } }) ); diff --git a/packages/model/src/standard/elements/string.ts b/packages/model/src/standard/elements/string.ts index d211f82d38..0d388f7efd 100644 --- a/packages/model/src/standard/elements/string.ts +++ b/packages/model/src/standard/elements/string.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -31,7 +31,7 @@ export const string = Datatype({ "specification. Implementations of this version of the specification shall NOT produce character " + "strings containing INFORMATION SEPARATOR 1.", - xref: { document: "core", section: "7.18.2.36" } + xref: { document: "core", section: "7.19.2.36" } }); MatterDefinition.children.push(string); diff --git a/packages/model/src/standard/elements/struct.ts b/packages/model/src/standard/elements/struct.ts index 2d7817b607..8055fa4272 100644 --- a/packages/model/src/standard/elements/struct.ts +++ b/packages/model/src/standard/elements/struct.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -69,7 +69,7 @@ export const struct = Datatype({ " fields shall NOT be indicated when reporting data back to the client, when the struct has an " + " associated fabric, and it is not the accessing fabric.", - xref: { document: "core", section: "7.18.1.9" } + xref: { document: "core", section: "7.19.1.9" } }); MatterDefinition.children.push(struct); diff --git a/packages/model/src/standard/elements/subject-id.ts b/packages/model/src/standard/elements/subject-id.ts index e4b8d29db7..18e2929f85 100644 --- a/packages/model/src/standard/elements/subject-id.ts +++ b/packages/model/src/standard/elements/subject-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/model/src/standard/elements/systime-ms.ts b/packages/model/src/standard/elements/systime-ms.ts index 6d06e443fa..eada5cb87e 100644 --- a/packages/model/src/standard/elements/systime-ms.ts +++ b/packages/model/src/standard/elements/systime-ms.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ export const systimeMs = Datatype({ "since boot." + "\n" + "This type is employed for compatibility reasons.", - xref: { document: "core", section: "7.18.2.9" } + xref: { document: "core", section: "7.19.2.9" } }); MatterDefinition.children.push(systimeMs); diff --git a/packages/model/src/standard/elements/systime-us.ts b/packages/model/src/standard/elements/systime-us.ts index 0e20e88f8c..00b359722e 100644 --- a/packages/model/src/standard/elements/systime-us.ts +++ b/packages/model/src/standard/elements/systime-us.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ export const systimeUs = Datatype({ name: "systime-us", type: "uint64", description: "System Time in microseconds", isSeed: true, details: "System time in microseconds is an unsigned 64-bit value representing the number of microseconds " + "since boot.", - xref: { document: "core", section: "7.18.2.8" } + xref: { document: "core", section: "7.19.2.8" } }); MatterDefinition.children.push(systimeUs); diff --git a/packages/model/src/standard/elements/tag.ts b/packages/model/src/standard/elements/tag.ts index 016c70c884..ca87e6612a 100644 --- a/packages/model/src/standard/elements/tag.ts +++ b/packages/model/src/standard/elements/tag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const tag = Datatype({ name: "tag", type: "uint8", description: "Tag", isSeed: true, details: "The Tag type shall identify a semantic tag located within a namespace.", - xref: { document: "core", section: "7.18.2.44" } + xref: { document: "core", section: "7.19.2.44" } }); MatterDefinition.children.push(tag); diff --git a/packages/model/src/standard/elements/temperature.ts b/packages/model/src/standard/elements/temperature.ts index d3542f067f..15f54b75bb 100644 --- a/packages/model/src/standard/elements/temperature.ts +++ b/packages/model/src/standard/elements/temperature.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -37,7 +37,7 @@ export const temperature = Datatype( "\n" + "0.01 resolution as expected by the ZCL format.", - xref: { document: "core", section: "7.18.2.11" } + xref: { document: "core", section: "7.19.2.11" } } ); diff --git a/packages/model/src/standard/elements/tod.ts b/packages/model/src/standard/elements/tod.ts index 50426bf315..f3ab38214a 100644 --- a/packages/model/src/standard/elements/tod.ts +++ b/packages/model/src/standard/elements/tod.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ export const tod = Datatype( { name: "tod", type: "struct", description: "Time of day", isSeed: true, details: "Represents time without a date component.", - xref: { document: "core", section: "7.18.2.3" } + xref: { document: "core", section: "7.19.2.3" } }, Field({ name: "hours", type: "uint8", constraint: "0 to 23", description: "Hour of the current day." }), Field({ name: "minutes", type: "uint8", constraint: "0 to 59", description: "Minute of the current hour." }), diff --git a/packages/model/src/standard/elements/trans-id.ts b/packages/model/src/standard/elements/trans-id.ts index 9241557170..6462257ba4 100644 --- a/packages/model/src/standard/elements/trans-id.ts +++ b/packages/model/src/standard/elements/trans-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ export const transId = Datatype({ name: "trans-id", type: "uint32", description: "Transaction ID", isSeed: true, details: "An identifier for a transaction as defined in the Interaction Model specification, see Transaction " + "ID.", - xref: { document: "core", section: "7.18.2.32" } + xref: { document: "core", section: "7.19.2.32" } }); MatterDefinition.children.push(transId); diff --git a/packages/model/src/standard/elements/uint16.ts b/packages/model/src/standard/elements/uint16.ts index 4895506480..220bee78b7 100644 --- a/packages/model/src/standard/elements/uint16.ts +++ b/packages/model/src/standard/elements/uint16.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const uint16 = Datatype({ name: "uint16", byteSize: 2, description: "Unsigned 16-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(uint16); diff --git a/packages/model/src/standard/elements/uint24.ts b/packages/model/src/standard/elements/uint24.ts index 69f13d2a15..43e2bc45fc 100644 --- a/packages/model/src/standard/elements/uint24.ts +++ b/packages/model/src/standard/elements/uint24.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const uint24 = Datatype({ name: "uint24", byteSize: 3, description: "Unsigned 24-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(uint24); diff --git a/packages/model/src/standard/elements/uint32.ts b/packages/model/src/standard/elements/uint32.ts index cfec62d4f1..5995927ec7 100644 --- a/packages/model/src/standard/elements/uint32.ts +++ b/packages/model/src/standard/elements/uint32.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const uint32 = Datatype({ name: "uint32", byteSize: 4, description: "Unsigned 32-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(uint32); diff --git a/packages/model/src/standard/elements/uint40.ts b/packages/model/src/standard/elements/uint40.ts index a160f83c1a..1a3f6ae66e 100644 --- a/packages/model/src/standard/elements/uint40.ts +++ b/packages/model/src/standard/elements/uint40.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const uint40 = Datatype({ name: "uint40", byteSize: 5, description: "Unsigned 40-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(uint40); diff --git a/packages/model/src/standard/elements/uint48.ts b/packages/model/src/standard/elements/uint48.ts index ab92375034..822a680ea9 100644 --- a/packages/model/src/standard/elements/uint48.ts +++ b/packages/model/src/standard/elements/uint48.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const uint48 = Datatype({ name: "uint48", byteSize: 6, description: "Unsigned 48-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(uint48); diff --git a/packages/model/src/standard/elements/uint56.ts b/packages/model/src/standard/elements/uint56.ts index d4e5030225..9ced320ae0 100644 --- a/packages/model/src/standard/elements/uint56.ts +++ b/packages/model/src/standard/elements/uint56.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const uint56 = Datatype({ name: "uint56", byteSize: 7, description: "Unsigned 56-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(uint56); diff --git a/packages/model/src/standard/elements/uint64.ts b/packages/model/src/standard/elements/uint64.ts index ec9bf22317..f3e848bbe4 100644 --- a/packages/model/src/standard/elements/uint64.ts +++ b/packages/model/src/standard/elements/uint64.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const uint64 = Datatype({ name: "uint64", byteSize: 8, description: "Unsigned 64-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(uint64); diff --git a/packages/model/src/standard/elements/uint8.ts b/packages/model/src/standard/elements/uint8.ts index 6e6772fc69..ccd29d8aa6 100644 --- a/packages/model/src/standard/elements/uint8.ts +++ b/packages/model/src/standard/elements/uint8.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const uint8 = Datatype({ name: "uint8", byteSize: 1, description: "Unsigned 8-bit integer", isSeed: true, metatype: "integer", - xref: { document: "core", section: "7.18.1" } + xref: { document: "core", section: "7.19.1" } }); MatterDefinition.children.push(uint8); diff --git a/packages/model/src/standard/elements/vendor-id.ts b/packages/model/src/standard/elements/vendor-id.ts index 6f121a2616..e4799b05f8 100644 --- a/packages/model/src/standard/elements/vendor-id.ts +++ b/packages/model/src/standard/elements/vendor-id.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,7 +14,7 @@ export const vendorId = Datatype({ details: "A Vendor ID." + "\n" + "Vendor IDs may be used as a prefix in a Manufacturer Extensible Identifier format.", - xref: { document: "core", section: "7.18.2.24" } + xref: { document: "core", section: "7.19.2.24" } }); MatterDefinition.children.push(vendorId); diff --git a/packages/model/src/standard/elements/voltage-mV.ts b/packages/model/src/standard/elements/voltage-mV.ts index 794cd83d3a..1bf7238f13 100644 --- a/packages/model/src/standard/elements/voltage-mV.ts +++ b/packages/model/src/standard/elements/voltage-mV.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,6 @@ import { DatatypeElement as Datatype } from "../../elements/index.js"; export const voltageMV = Datatype({ name: "voltage-mV", type: "int64", description: "Voltage", isSeed: true, details: "This type represents voltage measured in millivolts.", - xref: { document: "core", section: "7.18.2.14" } + xref: { document: "core", section: "7.19.2.14" } }); MatterDefinition.children.push(voltageMV); diff --git a/packages/model/src/tsconfig.json b/packages/model/src/tsconfig.json index ffe101210a..bd11c32f53 100644 --- a/packages/model/src/tsconfig.json +++ b/packages/model/src/tsconfig.json @@ -12,6 +12,9 @@ }, { "path": "../../testing/src" + }, + { + "path": "../../tools/src" } ] } \ No newline at end of file diff --git a/packages/model/test/aspects/QualityTest.ts b/packages/model/test/aspects/QualityTest.ts index 076aa6b898..827ca7422d 100644 --- a/packages/model/test/aspects/QualityTest.ts +++ b/packages/model/test/aspects/QualityTest.ts @@ -53,7 +53,7 @@ describe("Quality", () => { }); it("serialize", () => { - expect(`${quality}`).equal("X N F S P C I Q L K"); + expect(`${quality}`).equal("X N F S P C I Q L K T"); }); }); diff --git a/packages/model/test/models/ModelTest.ts b/packages/model/test/models/ModelTest.ts index 63e1c04c8f..d0f735e5f5 100644 --- a/packages/model/test/models/ModelTest.ts +++ b/packages/model/test/models/ModelTest.ts @@ -145,7 +145,7 @@ describe("Model", () => { describe("all", () => { it("finds all models by type", () => { expect(Fixtures.matter.all(ClusterModel).length).equal(3); - expect(Fixtures.matter.all(DatatypeModel).length).equal(74); + expect(Fixtures.matter.all(DatatypeModel).length).equal(75); }); }); diff --git a/packages/node/src/behavior/state/validation/ValueValidator.ts b/packages/node/src/behavior/state/validation/ValueValidator.ts index 3c3923e4d6..e0bbf06f5b 100644 --- a/packages/node/src/behavior/state/validation/ValueValidator.ts +++ b/packages/node/src/behavior/state/validation/ValueValidator.ts @@ -260,7 +260,7 @@ function createStructValidator(schema: Schema, supervisor: RootSupervisor): Valu for (const name in sublocation.choices) { const choice = sublocation.choices[name]; - if (choice.count < choice.target) { + if (choice.count < choice.target && !choice.orLess) { throw new ConformanceError( schema, location, diff --git a/packages/node/src/behavior/state/validation/conformance-compiler.ts b/packages/node/src/behavior/state/validation/conformance-compiler.ts index d612831766..4fd7b4c358 100644 --- a/packages/node/src/behavior/state/validation/conformance-compiler.ts +++ b/packages/node/src/behavior/state/validation/conformance-compiler.ts @@ -58,6 +58,29 @@ export function astToFunction(schema: ValueModel, supervisor: RootSupervisor): V supervisor.supportedFeatures, ); + // Create a node for the given name. + // + // Name resolution scope may change as we visit the AST; the base version creates a name reference if the the name + // is visible in scope. Other nodes may temporarily override this though + let createNameReference = (name: string): DynamicNode => { + const resolver = NameResolver(supervisor, schema.parent, camelize(name)); + if (resolver) { + return { + code: Code.Evaluate, + + evaluate: (_value, options) => { + return { + code: Code.Value, + value: resolver(options?.siblings), + }; + }, + }; + } + + // Unresolved names are always undefined + return { code: Code.Value, value: undefined }; + }; + // Compile the AST const compiledNode = compile(ast); @@ -211,6 +234,7 @@ export function astToFunction(schema: ValueModel, supervisor: RootSupervisor): V count: 0, target: param.num, orMore: !!param.orMore, + orLess: !!param.orLess, }; return { @@ -309,29 +333,13 @@ export function astToFunction(schema: ValueModel, supervisor: RootSupervisor): V // results in a static node that is conformant iff the feature is supported if (featuresSupported.has(param)) { return ConformantNode; - } else { - return NonconformantNode; } - } else { - // Name references another value. This results in a value node but must be evaluated at runtime against a - // specific struct - const resolver = NameResolver(supervisor, schema.parent, camelize(param)); - if (resolver) { - return { - code: Code.Evaluate, - - evaluate: (_value, options) => { - return { - code: Code.Value, - value: resolver(options?.siblings), - }; - }, - }; - } - - // Unresolved names are always undefined - return { code: Code.Value, value: undefined }; + return NonconformantNode; } + + // Name references another value. This results in a value node but must be evaluated at runtime against a + // specific struct + return createNameReference(param); } /** @@ -502,7 +510,40 @@ export function astToFunction(schema: ValueModel, supervisor: RootSupervisor): V operator: Conformance.Operator, { lhs, rhs }: Conformance.Ast.BinaryOperands, ): DynamicNode { - return createComparison(operator, compile(lhs), compile(rhs), schema); + const originalCreateNameReference = createNameReference; + try { + // Special case for binary operators where LHS references an enum - the RHS may reference a member of the + // enum by name. This feature is used in exactly one place as of 1.4, in + // ModeBase.ChangeToModeResponse.StatusText. And it's not formally specified as legal. But we support for + // completeness + if (lhs.type === Conformance.Special.Name) { + const name = camelize(lhs.param, false); + const field = supervisor.membersOf(schema).find(model => camelize(model.name, false) === name); + if (field?.effectiveMetatype === Metatype.enum) { + let enumValues: undefined | Record; + createNameReference = (name: string) => { + if (enumValues === undefined) { + enumValues = {}; + for (const member of supervisor.membersOf(field)) { + enumValues[camelize(member.name, true)] = member.id; + } + } + const id = enumValues[camelize(name, true)]; + if (id !== undefined) { + return { + code: Code.Value, + value: id, + }; + } + return originalCreateNameReference(name); + }; + } + } + + return createComparison(operator, compile(lhs), compile(rhs), schema); + } finally { + createNameReference = originalCreateNameReference; + } } /** diff --git a/packages/node/src/behavior/state/validation/conformance-util.ts b/packages/node/src/behavior/state/validation/conformance-util.ts index 8758e194a7..5f40155b6f 100644 --- a/packages/node/src/behavior/state/validation/conformance-util.ts +++ b/packages/node/src/behavior/state/validation/conformance-util.ts @@ -254,7 +254,6 @@ export function createBooleanTest(node: DynamicNode): DynamicNode { evaluate: (value, location) => { const result = evaluate(value, location); - assertValue(location, result, "boolean test"); return asConformance(result); }, }; diff --git a/packages/node/src/behavior/state/validation/location.ts b/packages/node/src/behavior/state/validation/location.ts index 70ff74a7b7..4613fed0b4 100644 --- a/packages/node/src/behavior/state/validation/location.ts +++ b/packages/node/src/behavior/state/validation/location.ts @@ -42,5 +42,6 @@ export namespace ValidationLocation { count: number; target: number; orMore: boolean; + orLess: boolean; } } diff --git a/packages/node/src/behaviors/access-control/AccessControlBehavior.ts b/packages/node/src/behaviors/access-control/AccessControlBehavior.ts index 9c158e0ea1..b5e1060d29 100644 --- a/packages/node/src/behaviors/access-control/AccessControlBehavior.ts +++ b/packages/node/src/behaviors/access-control/AccessControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,11 +8,17 @@ import { AccessControl } from "#clusters/access-control"; import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { AccessControlInterface } from "./AccessControlInterface.js"; /** * AccessControlBehavior is the base class for objects that support interaction with {@link AccessControl.Cluster}. + * + * This class does not have optional features of AccessControl.Cluster enabled. You can enable additional features + * using AccessControlBehavior.with. */ -export const AccessControlBehavior = ClusterBehavior.for(AccessControl.Cluster); +export const AccessControlBehavior = ClusterBehavior + .withInterface() + .for(AccessControl.Cluster); type AccessControlBehaviorType = InstanceType; export interface AccessControlBehavior extends AccessControlBehaviorType {} diff --git a/packages/node/src/behaviors/access-control/AccessControlInterface.ts b/packages/node/src/behaviors/access-control/AccessControlInterface.ts new file mode 100644 index 0000000000..0b990e7b69 --- /dev/null +++ b/packages/node/src/behaviors/access-control/AccessControlInterface.ts @@ -0,0 +1,40 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; +import { AccessControl } from "#clusters/access-control"; + +export namespace AccessControlInterface { + export interface ManagedDevice { + /** + * This command signals to the service associated with the device vendor that the fabric administrator would + * like a review of the current restrictions on the accessing fabric. This command includes an optional list of + * ARL entries that the fabric administrator would like removed. + * + * In response, a ReviewFabricRestrictionsResponse is sent which contains a token that can be used to correlate + * a review request with a FabricRestrictionReviewUpdate event. + * + * Within 1 hour of the ReviewFabricRestrictionsResponse, the FabricRestrictionReviewUpdate event shall be + * generated, in order to indicate completion of the review and any additional steps required by the user for + * the review. + * + * A review may include obtaining consent from the user, which can take time. For example, the user may need to + * respond to an email or a push notification. + * + * The ARL attribute may change at any time due to actions taken by the user, or the service associated with + * the device vendor. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.8.1 + */ + reviewFabricRestrictions(request: AccessControl.ReviewFabricRestrictionsRequest): MaybePromise; + } +} + +export type AccessControlInterface = { + components: [{ flags: { managedDevice: true }, methods: AccessControlInterface.ManagedDevice }] +}; diff --git a/packages/node/src/behaviors/access-control/AccessControlServer.ts b/packages/node/src/behaviors/access-control/AccessControlServer.ts index bac3f87049..25ca2841ce 100644 --- a/packages/node/src/behaviors/access-control/AccessControlServer.ts +++ b/packages/node/src/behaviors/access-control/AccessControlServer.ts @@ -30,7 +30,7 @@ const logger = Logger.get("AccessControlServer"); /** * This is the default server implementation of AccessControlBehavior. */ -export class AccessControlServer extends AccessControlBehavior { +export class AccessControlServer extends AccessControlBehavior.with("Extension") { declare internal: AccessControlServer.Internal; override initialize() { diff --git a/packages/node/src/behaviors/access-control/index.ts b/packages/node/src/behaviors/access-control/index.ts index 52401c36c3..218ae73711 100644 --- a/packages/node/src/behaviors/access-control/index.ts +++ b/packages/node/src/behaviors/access-control/index.ts @@ -1,10 +1,11 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ +export * from "./AccessControlInterface.js"; export * from "./AccessControlBehavior.js"; export * from "./AccessControlServer.js"; diff --git a/packages/node/src/behaviors/account-login/AccountLoginBehavior.ts b/packages/node/src/behaviors/account-login/AccountLoginBehavior.ts index 075009ddf5..5019542847 100644 --- a/packages/node/src/behaviors/account-login/AccountLoginBehavior.ts +++ b/packages/node/src/behaviors/account-login/AccountLoginBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/account-login/AccountLoginInterface.ts b/packages/node/src/behaviors/account-login/AccountLoginInterface.ts index 62ffd953e5..7788db74fb 100644 --- a/packages/node/src/behaviors/account-login/AccountLoginInterface.ts +++ b/packages/node/src/behaviors/account-login/AccountLoginInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/account-login/AccountLoginServer.ts b/packages/node/src/behaviors/account-login/AccountLoginServer.ts index 8da6d618b9..6bf52b8a7f 100644 --- a/packages/node/src/behaviors/account-login/AccountLoginServer.ts +++ b/packages/node/src/behaviors/account-login/AccountLoginServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/account-login/index.ts b/packages/node/src/behaviors/account-login/index.ts index 1f9d3ca7e6..ea4f9bf3a7 100644 --- a/packages/node/src/behaviors/account-login/index.ts +++ b/packages/node/src/behaviors/account-login/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/actions/ActionsBehavior.ts b/packages/node/src/behaviors/actions/ActionsBehavior.ts index c326f1058f..adcd0033d9 100644 --- a/packages/node/src/behaviors/actions/ActionsBehavior.ts +++ b/packages/node/src/behaviors/actions/ActionsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/actions/ActionsInterface.ts b/packages/node/src/behaviors/actions/ActionsInterface.ts index c195ac20fb..4f3f11007b 100644 --- a/packages/node/src/behaviors/actions/ActionsInterface.ts +++ b/packages/node/src/behaviors/actions/ActionsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/actions/ActionsServer.ts b/packages/node/src/behaviors/actions/ActionsServer.ts index 72c43c84db..53e2c6e890 100644 --- a/packages/node/src/behaviors/actions/ActionsServer.ts +++ b/packages/node/src/behaviors/actions/ActionsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/actions/index.ts b/packages/node/src/behaviors/actions/index.ts index fa4f5ecf04..db6a72eafc 100644 --- a/packages/node/src/behaviors/actions/index.ts +++ b/packages/node/src/behaviors/actions/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/activated-carbon-filter-monitoring/ActivatedCarbonFilterMonitoringBehavior.ts b/packages/node/src/behaviors/activated-carbon-filter-monitoring/ActivatedCarbonFilterMonitoringBehavior.ts index 4ced97a106..45d07a4915 100644 --- a/packages/node/src/behaviors/activated-carbon-filter-monitoring/ActivatedCarbonFilterMonitoringBehavior.ts +++ b/packages/node/src/behaviors/activated-carbon-filter-monitoring/ActivatedCarbonFilterMonitoringBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/activated-carbon-filter-monitoring/ActivatedCarbonFilterMonitoringServer.ts b/packages/node/src/behaviors/activated-carbon-filter-monitoring/ActivatedCarbonFilterMonitoringServer.ts index d27476e0e5..9974252fec 100644 --- a/packages/node/src/behaviors/activated-carbon-filter-monitoring/ActivatedCarbonFilterMonitoringServer.ts +++ b/packages/node/src/behaviors/activated-carbon-filter-monitoring/ActivatedCarbonFilterMonitoringServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/activated-carbon-filter-monitoring/index.ts b/packages/node/src/behaviors/activated-carbon-filter-monitoring/index.ts index 4019be0993..6ab54b016a 100644 --- a/packages/node/src/behaviors/activated-carbon-filter-monitoring/index.ts +++ b/packages/node/src/behaviors/activated-carbon-filter-monitoring/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/administrator-commissioning/AdministratorCommissioningBehavior.ts b/packages/node/src/behaviors/administrator-commissioning/AdministratorCommissioningBehavior.ts index 52a1be852e..a358d57d57 100644 --- a/packages/node/src/behaviors/administrator-commissioning/AdministratorCommissioningBehavior.ts +++ b/packages/node/src/behaviors/administrator-commissioning/AdministratorCommissioningBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/administrator-commissioning/AdministratorCommissioningInterface.ts b/packages/node/src/behaviors/administrator-commissioning/AdministratorCommissioningInterface.ts index 3ddee2b85d..5dd889e638 100644 --- a/packages/node/src/behaviors/administrator-commissioning/AdministratorCommissioningInterface.ts +++ b/packages/node/src/behaviors/administrator-commissioning/AdministratorCommissioningInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,12 +14,15 @@ export namespace AdministratorCommissioningInterface { /** * This command is used by a current Administrator to instruct a Node to go into commissioning mode. The * Enhanced Commissioning Method specifies a window of time during which an already commissioned Node accepts - * PASE sessions. The current Administrator MUST specify a timeout value for the duration of OCW. + * PASE sessions. The current Administrator MUST specify a timeout value for the duration of the + * OpenCommissioningWindow command. * - * When OCW expires or commissioning completes, the Node shall remove the Passcode by deleting the PAKE - * passcode verifier as well as stop publishing the DNS-SD record corresponding to this command as described in - * Section 4.3.1, “Commissionable Node Discovery”. The commissioning into a new Fabric completes when the Node - * successfully receives a CommissioningComplete command, see Section 5.5, “Commissioning Flows”. + * When the OpenCommissioningWindow command expires or commissioning completes, the Node shall remove the + * Passcode by deleting the PAKE passcode verifier as well as stop publishing the DNS-SD record corresponding + * to this command as described in Section 4.3.1, “Commissionable + * + * Node Discovery”. The commissioning into a new Fabric completes when the Node successfully receives a + * CommissioningComplete command, see Section 5.5, “Commissioning Flows”. * * The parameters for OpenCommissioningWindow command are as follows: * @@ -46,18 +49,19 @@ export namespace AdministratorCommissioningInterface { openCommissioningWindow(request: AdministratorCommissioning.OpenCommissioningWindowRequest): MaybePromise; /** - * This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning - * Window or Open Basic Commissioning Window command. This is an idempotent command and the Node shall (for - * ECM) delete the temporary PAKEPasscodeVerifier and associated data, and stop publishing the DNS-SD record - * associated with the Open Commissioning Window or Open Basic Commissioning Window command, see Section 4.3.1, - * “Commissionable Node Discovery”. + * This command is used by a current Administrator to instruct a Node to revoke any active + * OpenCommissioningWindow or OpenBasicCommissioningWindow command. This is an idempotent command and the Node + * shall (for ECM) delete the temporary PAKEPasscodeVerifier and associated data, and stop publishing the + * DNS-SD record associated with the OpenCommissioningWindow or OpenBasicCommissioningWindow command, see + * Section 4.3.1, “Commissionable Node Discovery”. * * If no commissioning window was open at time of receipt, this command shall fail with a cluster specific * status code of WindowNotOpen. * * If the commissioning window was open and the fail-safe was armed when this command is received, the device - * shall immediately expire the fail-safe and perform the cleanup steps outlined in Section 11.10.6.2.2, - * “Behavior on expiry of Fail-Safe timer”. + * shall immediately expire the fail-safe and perform the cleanup steps outlined + * + * in Section 11.10.7.2.2, “Behavior on expiry of Fail-Safe timer”. * * @see {@link MatterSpecification.v13.Core} § 11.19.8.3 */ @@ -69,7 +73,7 @@ export namespace AdministratorCommissioningInterface { * This command may be used by a current Administrator to instruct a Node to go into commissioning mode, if the * node supports the Basic Commissioning Method. The Basic Commissioning Method specifies a window of time * during which an already commissioned Node accepts PASE sessions. The current Administrator shall specify a - * timeout value for the duration of OBCW. + * timeout value for the duration of the OpenBasicCommissioningWindow command. * * If a commissioning window is already currently open, this command shall fail with a cluster specific status * code of Busy. diff --git a/packages/node/src/behaviors/administrator-commissioning/index.ts b/packages/node/src/behaviors/administrator-commissioning/index.ts index 852f104c28..2098b2029f 100644 --- a/packages/node/src/behaviors/administrator-commissioning/index.ts +++ b/packages/node/src/behaviors/administrator-commissioning/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/air-quality/AirQualityBehavior.ts b/packages/node/src/behaviors/air-quality/AirQualityBehavior.ts index d82d0b4afa..544f5d6a06 100644 --- a/packages/node/src/behaviors/air-quality/AirQualityBehavior.ts +++ b/packages/node/src/behaviors/air-quality/AirQualityBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/air-quality/AirQualityServer.ts b/packages/node/src/behaviors/air-quality/AirQualityServer.ts index c06142284a..9452271801 100644 --- a/packages/node/src/behaviors/air-quality/AirQualityServer.ts +++ b/packages/node/src/behaviors/air-quality/AirQualityServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/air-quality/index.ts b/packages/node/src/behaviors/air-quality/index.ts index 1c93a6eec1..9e2c2ff59d 100644 --- a/packages/node/src/behaviors/air-quality/index.ts +++ b/packages/node/src/behaviors/air-quality/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/alarm-base/AlarmBaseInterface.ts b/packages/node/src/behaviors/alarm-base/AlarmBaseInterface.ts index 84f02f87c0..2717d9582e 100644 --- a/packages/node/src/behaviors/alarm-base/AlarmBaseInterface.ts +++ b/packages/node/src/behaviors/alarm-base/AlarmBaseInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/alarm-base/index.ts b/packages/node/src/behaviors/alarm-base/index.ts index 6487d82950..c6a6b57e6f 100644 --- a/packages/node/src/behaviors/alarm-base/index.ts +++ b/packages/node/src/behaviors/alarm-base/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/application-basic/ApplicationBasicBehavior.ts b/packages/node/src/behaviors/application-basic/ApplicationBasicBehavior.ts index 90730ade52..79dd674000 100644 --- a/packages/node/src/behaviors/application-basic/ApplicationBasicBehavior.ts +++ b/packages/node/src/behaviors/application-basic/ApplicationBasicBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/application-basic/ApplicationBasicServer.ts b/packages/node/src/behaviors/application-basic/ApplicationBasicServer.ts index ed6d91b007..2aa6202718 100644 --- a/packages/node/src/behaviors/application-basic/ApplicationBasicServer.ts +++ b/packages/node/src/behaviors/application-basic/ApplicationBasicServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/application-basic/index.ts b/packages/node/src/behaviors/application-basic/index.ts index 5f04fd15dd..2dc35c93d2 100644 --- a/packages/node/src/behaviors/application-basic/index.ts +++ b/packages/node/src/behaviors/application-basic/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/application-launcher/ApplicationLauncherBehavior.ts b/packages/node/src/behaviors/application-launcher/ApplicationLauncherBehavior.ts index 32f7231de0..07bf8a72fd 100644 --- a/packages/node/src/behaviors/application-launcher/ApplicationLauncherBehavior.ts +++ b/packages/node/src/behaviors/application-launcher/ApplicationLauncherBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/application-launcher/ApplicationLauncherInterface.ts b/packages/node/src/behaviors/application-launcher/ApplicationLauncherInterface.ts index 3675929d8e..6a1babb8cf 100644 --- a/packages/node/src/behaviors/application-launcher/ApplicationLauncherInterface.ts +++ b/packages/node/src/behaviors/application-launcher/ApplicationLauncherInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -59,10 +59,10 @@ export namespace ApplicationLauncherInterface { * The endpoint may decide to stop the application based on manufacturer specific behavior or resource * constraints if any. The Status attribute shall be updated to ActiveHidden or Stopped, depending on the * action taken, on the Application Basic cluster of the Endpoint corresponding to the application on which the - * action was taken. The Status attribute shall be updated on any other + * action was taken. The Status attribute shall be updated on any other application whose Status may have + * changed as a result of this command. * - * application whose Status may have changed as a result of this command. This command returns a Launcher - * Response. + * This command returns a Launcher Response. * * @see {@link MatterSpecification.v13.Cluster} § 6.4.7.3 */ diff --git a/packages/node/src/behaviors/application-launcher/ApplicationLauncherServer.ts b/packages/node/src/behaviors/application-launcher/ApplicationLauncherServer.ts index eb9d38bb62..beebc22108 100644 --- a/packages/node/src/behaviors/application-launcher/ApplicationLauncherServer.ts +++ b/packages/node/src/behaviors/application-launcher/ApplicationLauncherServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/application-launcher/index.ts b/packages/node/src/behaviors/application-launcher/index.ts index 803ef31fb0..6e5670cdd4 100644 --- a/packages/node/src/behaviors/application-launcher/index.ts +++ b/packages/node/src/behaviors/application-launcher/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/audio-output/AudioOutputBehavior.ts b/packages/node/src/behaviors/audio-output/AudioOutputBehavior.ts index 86c19a0bfb..0632083af8 100644 --- a/packages/node/src/behaviors/audio-output/AudioOutputBehavior.ts +++ b/packages/node/src/behaviors/audio-output/AudioOutputBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/audio-output/AudioOutputInterface.ts b/packages/node/src/behaviors/audio-output/AudioOutputInterface.ts index 1d67212707..762df247c9 100644 --- a/packages/node/src/behaviors/audio-output/AudioOutputInterface.ts +++ b/packages/node/src/behaviors/audio-output/AudioOutputInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/audio-output/AudioOutputServer.ts b/packages/node/src/behaviors/audio-output/AudioOutputServer.ts index bf7d50b836..66cf543597 100644 --- a/packages/node/src/behaviors/audio-output/AudioOutputServer.ts +++ b/packages/node/src/behaviors/audio-output/AudioOutputServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/audio-output/index.ts b/packages/node/src/behaviors/audio-output/index.ts index f5c3f28af9..ca05601abe 100644 --- a/packages/node/src/behaviors/audio-output/index.ts +++ b/packages/node/src/behaviors/audio-output/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ballast-configuration/BallastConfigurationBehavior.ts b/packages/node/src/behaviors/ballast-configuration/BallastConfigurationBehavior.ts index 0a780dd4e2..5792723b7e 100644 --- a/packages/node/src/behaviors/ballast-configuration/BallastConfigurationBehavior.ts +++ b/packages/node/src/behaviors/ballast-configuration/BallastConfigurationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ballast-configuration/BallastConfigurationServer.ts b/packages/node/src/behaviors/ballast-configuration/BallastConfigurationServer.ts index be5799fd0d..075a8c1198 100644 --- a/packages/node/src/behaviors/ballast-configuration/BallastConfigurationServer.ts +++ b/packages/node/src/behaviors/ballast-configuration/BallastConfigurationServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ballast-configuration/index.ts b/packages/node/src/behaviors/ballast-configuration/index.ts index e0fe91213a..a1a1dd04cf 100644 --- a/packages/node/src/behaviors/ballast-configuration/index.ts +++ b/packages/node/src/behaviors/ballast-configuration/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/basic-information/BasicInformationBehavior.ts b/packages/node/src/behaviors/basic-information/BasicInformationBehavior.ts index 4553824153..821a379869 100644 --- a/packages/node/src/behaviors/basic-information/BasicInformationBehavior.ts +++ b/packages/node/src/behaviors/basic-information/BasicInformationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/basic-information/BasicInformationServer.ts b/packages/node/src/behaviors/basic-information/BasicInformationServer.ts index 6967ba7bfe..da77b22db3 100644 --- a/packages/node/src/behaviors/basic-information/BasicInformationServer.ts +++ b/packages/node/src/behaviors/basic-information/BasicInformationServer.ts @@ -5,9 +5,10 @@ */ import { ActionContext } from "#behavior/context/ActionContext.js"; +import { Schema } from "#behavior/supervision/Schema.js"; import { BasicInformation } from "#clusters/basic-information"; -import { Diagnostic, Logger, Observable } from "#general"; -import { Specification } from "#model"; +import { Base64, Crypto, Diagnostic, InternalError, Logger, Observable } from "#general"; +import { AttributeModel, Specification } from "#model"; import { NodeLifecycle } from "#node/NodeLifecycle.js"; import { Fabric, FabricManager } from "#protocol"; import { DEFAULT_MAX_PATHS_PER_INVOKE, VendorId } from "#types"; @@ -57,6 +58,9 @@ export class BasicInformationServer extends Base { setDefault("softwareVersionString", state.softwareVersion.toString()); setDefault("specificationVersion", Specification.SPECIFICATION_VERSION); setDefault("maxPathsPerInvoke", DEFAULT_MAX_PATHS_PER_INVOKE); + if (this.state.uniqueId === undefined) { + this.state.uniqueId = BasicInformationServer.createUniqueId(); + } const lifecycle = this.endpoint.lifecycle as NodeLifecycle; @@ -83,6 +87,20 @@ export class BasicInformationServer extends Base { } } + static override schema = this.enableUniqueIdPersistence(Base.schema); + + static enableUniqueIdPersistence(schema?: Schema): Schema { + if (schema === undefined) { + throw new InternalError("Basic information schema is undefined"); + } + + return schema.extend({}, schema.require(AttributeModel, "uniqueId").extend({ quality: "FN" })); + } + + static createUniqueId() { + return Base64.encode(Crypto.getRandomData(24)); + } + #online() { this.events.startUp.emit({ softwareVersion: this.state.softwareVersion }, this.context); diff --git a/packages/node/src/behaviors/basic-information/index.ts b/packages/node/src/behaviors/basic-information/index.ts index cf3276fbca..2ab3831c54 100644 --- a/packages/node/src/behaviors/basic-information/index.ts +++ b/packages/node/src/behaviors/basic-information/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/binding/BindingBehavior.ts b/packages/node/src/behaviors/binding/BindingBehavior.ts index 90a8ef95aa..bfe46e6ec3 100644 --- a/packages/node/src/behaviors/binding/BindingBehavior.ts +++ b/packages/node/src/behaviors/binding/BindingBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/binding/BindingServer.ts b/packages/node/src/behaviors/binding/BindingServer.ts index d1984f4b82..821cd9bab5 100644 --- a/packages/node/src/behaviors/binding/BindingServer.ts +++ b/packages/node/src/behaviors/binding/BindingServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/binding/index.ts b/packages/node/src/behaviors/binding/index.ts index 73b436027d..dd705549aa 100644 --- a/packages/node/src/behaviors/binding/index.ts +++ b/packages/node/src/behaviors/binding/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationBehavior.ts b/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationBehavior.ts index b5273c717f..d901045c07 100644 --- a/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationBehavior.ts +++ b/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationInterface.ts b/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationInterface.ts index be41b3d450..4b656433ef 100644 --- a/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationInterface.ts +++ b/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationServer.ts b/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationServer.ts index 675c4e82ac..6be6da4de1 100644 --- a/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationServer.ts +++ b/packages/node/src/behaviors/boolean-state-configuration/BooleanStateConfigurationServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/boolean-state-configuration/index.ts b/packages/node/src/behaviors/boolean-state-configuration/index.ts index 1df696e43d..81767bbc60 100644 --- a/packages/node/src/behaviors/boolean-state-configuration/index.ts +++ b/packages/node/src/behaviors/boolean-state-configuration/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/boolean-state/BooleanStateBehavior.ts b/packages/node/src/behaviors/boolean-state/BooleanStateBehavior.ts index b358a2708b..0e602b52fd 100644 --- a/packages/node/src/behaviors/boolean-state/BooleanStateBehavior.ts +++ b/packages/node/src/behaviors/boolean-state/BooleanStateBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/boolean-state/index.ts b/packages/node/src/behaviors/boolean-state/index.ts index abe15fa1c5..414f4dd225 100644 --- a/packages/node/src/behaviors/boolean-state/index.ts +++ b/packages/node/src/behaviors/boolean-state/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationBehavior.ts b/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationBehavior.ts index 191372b679..c821bdd9c7 100644 --- a/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationBehavior.ts +++ b/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,12 +8,18 @@ import { BridgedDeviceBasicInformation } from "#clusters/bridged-device-basic-information"; import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { BridgedDeviceBasicInformationInterface } from "./BridgedDeviceBasicInformationInterface.js"; /** * BridgedDeviceBasicInformationBehavior is the base class for objects that support interaction with {@link * BridgedDeviceBasicInformation.Cluster}. + * + * This class does not have optional features of BridgedDeviceBasicInformation.Cluster enabled. You can enable + * additional features using BridgedDeviceBasicInformationBehavior.with. */ -export const BridgedDeviceBasicInformationBehavior = ClusterBehavior.for(BridgedDeviceBasicInformation.Cluster); +export const BridgedDeviceBasicInformationBehavior = ClusterBehavior + .withInterface() + .for(BridgedDeviceBasicInformation.Cluster); type BridgedDeviceBasicInformationBehaviorType = InstanceType; export interface BridgedDeviceBasicInformationBehavior extends BridgedDeviceBasicInformationBehaviorType {} diff --git a/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationInterface.ts b/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationInterface.ts new file mode 100644 index 0000000000..8d444c20c7 --- /dev/null +++ b/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationInterface.ts @@ -0,0 +1,51 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; +import { BridgedDeviceBasicInformation } from "#clusters/bridged-device-basic-information"; + +export namespace BridgedDeviceBasicInformationInterface { + export interface BridgedIcdSupport { + /** + * Upon receipt, the server shall attempt to keep the bridged device active for the duration specified by the + * command, when the device is next active. + * + * The implementation of this is best-effort since it may interact with non-native protocols. However, several + * specific protocol requirements are: + * + * • If the bridged device is a Matter Intermittently Connected Device, then the server shall send a + * StayActiveRequest command with the StayActiveDuration field set to value of the StayActiveDuration field + * in the received command to the bridged device when the bridged device next sends a checks-in message or + * subscription report. See Intermittently Connected Devices Behavior for details on ICD state management. + * + * When the bridge detects that the bridged device goes into an active state, an ActiveChanged event shall be + * generated. + * + * In order to avoid unnecessary power consumption in the bridged device: + * + * • The server shall enter a "pending active" state for the associated device when the KeepActive command is + * received. The server "pending active" state shall expire after the amount of time defined by the + * TimeoutMs field, in milliseconds, if no subsequent KeepActive command is received. When a KeepActive + * command is received, the "pending active" state is set, the StayActiveDuration is updated to the greater + * of the new value and the previously stored value, and the TimeoutMs is updated to the greater of the new + * value and the remaining time until the prior "pending active" state expires. + * + * • The server shall only keep the bridged device active once for a request. (The server shall only consider + * the operation performed if an associated ActiveChanged event was generated.) + * + * @see {@link MatterSpecification.v13.Core} § 9.13.6.1 + */ + keepActive(request: BridgedDeviceBasicInformation.KeepActiveRequest): MaybePromise; + } +} + +export type BridgedDeviceBasicInformationInterface = { + components: [ + { flags: { bridgedIcdSupport: true }, methods: BridgedDeviceBasicInformationInterface.BridgedIcdSupport } + ] +}; diff --git a/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationServer.ts b/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationServer.ts index 1779f4c148..56e44eca33 100644 --- a/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationServer.ts +++ b/packages/node/src/behaviors/bridged-device-basic-information/BridgedDeviceBasicInformationServer.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { BasicInformationServer } from "#behaviors/basic-information"; import { DescriptorServer } from "#behaviors/descriptor"; import { AggregatorEndpoint } from "#endpoints/aggregator"; import { ImplementationError, Logger } from "#general"; @@ -26,15 +27,21 @@ export class BridgedDeviceBasicInformationServer extends BridgedDeviceBasicInfor } this.reactTo(this.events.reachable$Changed, this.#emitReachableChange); - if ( - this.state.uniqueId !== undefined && - this.state.serialNumber !== undefined && - this.state.uniqueId === this.state.serialNumber - ) { + const { uniqueId, serialNumber } = this.state; + + if (uniqueId === undefined) { + this.state.uniqueId = BasicInformationServer.createUniqueId(); + } + + if (serialNumber !== undefined && uniqueId === this.state.serialNumber) { logger.warn("uniqueId and serialNumber shall not be the same."); } } + static override schema = BasicInformationServer.enableUniqueIdPersistence( + BridgedDeviceBasicInformationBehavior.schema, + ); + /** * Per the specification. Not sure what this adds vs. subscribing to attribute changes. */ diff --git a/packages/node/src/behaviors/bridged-device-basic-information/index.ts b/packages/node/src/behaviors/bridged-device-basic-information/index.ts index 2457bede39..8330f60544 100644 --- a/packages/node/src/behaviors/bridged-device-basic-information/index.ts +++ b/packages/node/src/behaviors/bridged-device-basic-information/index.ts @@ -1,10 +1,11 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ +export * from "./BridgedDeviceBasicInformationInterface.js"; export * from "./BridgedDeviceBasicInformationBehavior.js"; export * from "./BridgedDeviceBasicInformationServer.js"; diff --git a/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/CarbonDioxideConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/CarbonDioxideConcentrationMeasurementBehavior.ts index 5ba449be83..f315760632 100644 --- a/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/CarbonDioxideConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/CarbonDioxideConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/CarbonDioxideConcentrationMeasurementServer.ts b/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/CarbonDioxideConcentrationMeasurementServer.ts index 8613cd1210..d59323e6e1 100644 --- a/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/CarbonDioxideConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/CarbonDioxideConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/index.ts b/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/index.ts index aee6392506..8c7d0dd914 100644 --- a/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/carbon-dioxide-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/CarbonMonoxideConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/CarbonMonoxideConcentrationMeasurementBehavior.ts index c4d839d036..ea923f972f 100644 --- a/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/CarbonMonoxideConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/CarbonMonoxideConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/CarbonMonoxideConcentrationMeasurementServer.ts b/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/CarbonMonoxideConcentrationMeasurementServer.ts index 0bcd86f5bb..61c1905ce1 100644 --- a/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/CarbonMonoxideConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/CarbonMonoxideConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/index.ts b/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/index.ts index f19e4ef195..da1d73cd24 100644 --- a/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/carbon-monoxide-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/channel/ChannelBehavior.ts b/packages/node/src/behaviors/channel/ChannelBehavior.ts index 9fa21aaf4e..49670d3856 100644 --- a/packages/node/src/behaviors/channel/ChannelBehavior.ts +++ b/packages/node/src/behaviors/channel/ChannelBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/channel/ChannelInterface.ts b/packages/node/src/behaviors/channel/ChannelInterface.ts index c6f3015a86..9f29214018 100644 --- a/packages/node/src/behaviors/channel/ChannelInterface.ts +++ b/packages/node/src/behaviors/channel/ChannelInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -52,9 +52,8 @@ export namespace ChannelInterface { /** * This command retrieves the program guide. It accepts several filter parameters to return specific schedule * and program information from a content app. The command shall receive in response a ProgramGuideResponse. - * Standard error codes shall be used when arguments provided are not - * - * valid. For example, if StartTime is greater than EndTime, the status code INVALID_ACTION shall be returned. + * Standard error codes shall be used when arguments provided are not valid. For example, if StartTime is + * greater than EndTime, the status code INVALID_ACTION shall be returned. * * @see {@link MatterSpecification.v13.Cluster} § 6.6.7.5 */ diff --git a/packages/node/src/behaviors/channel/ChannelServer.ts b/packages/node/src/behaviors/channel/ChannelServer.ts index b6aad30182..b4a4024906 100644 --- a/packages/node/src/behaviors/channel/ChannelServer.ts +++ b/packages/node/src/behaviors/channel/ChannelServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/channel/index.ts b/packages/node/src/behaviors/channel/index.ts index e15a5ba795..421e701c01 100644 --- a/packages/node/src/behaviors/channel/index.ts +++ b/packages/node/src/behaviors/channel/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/color-control/ColorControlBehavior.ts b/packages/node/src/behaviors/color-control/ColorControlBehavior.ts index c4b2b2f189..fce6655d54 100644 --- a/packages/node/src/behaviors/color-control/ColorControlBehavior.ts +++ b/packages/node/src/behaviors/color-control/ColorControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/color-control/ColorControlInterface.ts b/packages/node/src/behaviors/color-control/ColorControlInterface.ts index c997f35826..d08f993179 100644 --- a/packages/node/src/behaviors/color-control/ColorControlInterface.ts +++ b/packages/node/src/behaviors/color-control/ColorControlInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,132 +12,130 @@ import { ColorControl } from "#clusters/color-control"; export namespace ColorControlInterface { export interface HueSaturation { /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.4 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.4 */ moveToHue(request: ColorControl.MoveToHueRequest): MaybePromise; /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.5 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.5 */ moveHue(request: ColorControl.MoveHueRequest): MaybePromise; /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.6 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.6 */ stepHue(request: ColorControl.StepHueRequest): MaybePromise; /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.7 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.7 */ moveToSaturation(request: ColorControl.MoveToSaturationRequest): MaybePromise; /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.8 */ moveSaturation(request: ColorControl.MoveSaturationRequest): MaybePromise; /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.9 */ stepSaturation(request: ColorControl.StepSaturationRequest): MaybePromise; /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.10 */ moveToHueAndSaturation(request: ColorControl.MoveToHueAndSaturationRequest): MaybePromise; } export interface Xy { /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.11 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.11 */ moveToColor(request: ColorControl.MoveToColorRequest): MaybePromise; /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.12 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.12 */ moveColor(request: ColorControl.MoveColorRequest): MaybePromise; /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.13 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.13 */ stepColor(request: ColorControl.StepColorRequest): MaybePromise; } export interface ColorTemperature { /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.14 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.14 */ moveToColorTemperature(request: ColorControl.MoveToColorTemperatureRequest): MaybePromise; /** - * The MoveColorTemperature command allows the color temperature of a lamp to be moved at a specified rate. + * This command allows the color temperature of the light to be moved at a specified rate. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.21 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.21 */ moveColorTemperature(request: ColorControl.MoveColorTemperatureRequest): MaybePromise; /** - * The StepColorTemperature command allows the color temperature of a lamp to be stepped with a specified step - * size. + * This command allows the color temperature of the light to be stepped with a specified step size. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22 */ stepColorTemperature(request: ColorControl.StepColorTemperatureRequest): MaybePromise; } export interface EnhancedHue { /** - * The EnhancedMoveToHue command allows lamps to be moved in a smooth continuous transition from their current - * hue to a target hue. + * This command allows the light to be moved in a smooth continuous transition from their current hue to a + * target hue. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.15 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.15 */ enhancedMoveToHue(request: ColorControl.EnhancedMoveToHueRequest): MaybePromise; /** - * The EnhancedMoveHue command allows lamps to be moved in a continuous stepped transition from their current - * hue to a target hue. + * This command allows the light to start a continuous transition starting from their current hue. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.16 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.16 */ enhancedMoveHue(request: ColorControl.EnhancedMoveHueRequest): MaybePromise; /** - * The EnhancedStepHue command allows lamps to be moved in a stepped transition from their current hue to a - * target hue, resulting in a linear transition through XY space. + * This command allows the light to be moved in a stepped transition from their current hue, resulting in a + * linear transition through XY space. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.17 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.17 */ enhancedStepHue(request: ColorControl.EnhancedStepHueRequest): MaybePromise; /** - * The EnhancedMoveToHueAndSaturation command allows lamps to be moved in a smooth continuous transition from - * their current hue to a target hue and from their current saturation to a target saturation. + * This command allows the light to be moved in a smooth continuous transition from their current hue to a + * target hue and from their current saturation to a target saturation. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.18 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.18 */ enhancedMoveToHueAndSaturation(request: ColorControl.EnhancedMoveToHueAndSaturationRequest): MaybePromise; } export interface ColorLoop { /** - * The Color Loop Set command allows a color loop to be activated such that the color lamp cycles through its - * range of hues. + * This command allows a color loop to be activated such that the color light cycles through its range of hues. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.19 */ colorLoopSet(request: ColorControl.ColorLoopSetRequest): MaybePromise; } export interface HueSaturationOrXyOrColorTemperature { /** - * The StopMoveStep command is provided to allow MoveTo and Step commands to be stopped. (Note this - * automatically provides symmetry to the Level Control cluster.) + * This command is provided to allow MoveTo and Step commands to be stopped. * - * NOTE the StopMoveStep command has no effect on an active color loop. + * NOTE This automatically provides symmetry to the Level Control cluster. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.20 + * NOTE The StopMoveStep command has no effect on an active color loop. + * + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.20 */ stopMoveStep(request: ColorControl.StopMoveStepRequest): MaybePromise; } diff --git a/packages/node/src/behaviors/color-control/ColorControlServer.ts b/packages/node/src/behaviors/color-control/ColorControlServer.ts index f4f65475b4..74b947fdd7 100644 --- a/packages/node/src/behaviors/color-control/ColorControlServer.ts +++ b/packages/node/src/behaviors/color-control/ColorControlServer.ts @@ -776,7 +776,7 @@ export class ColorControlServerLogic extends ColorControlServerBase { transitionTime: number, ): MaybePromise { return MaybePromise.then( - this.moveToHueLogic(targetHue, ColorControl.Direction.ShortestDistance, transitionTime, false), + this.moveToHueLogic(targetHue, ColorControl.Direction.Shortest, transitionTime, false), () => this.moveToSaturationLogic(targetSaturation, transitionTime), ); } @@ -1124,7 +1124,7 @@ export class ColorControlServerLogic extends ColorControlServerBase { transitionTime: number, ): MaybePromise { return MaybePromise.then( - this.moveToHueLogic(targetEnhancedHue, ColorControl.Direction.ShortestDistance, transitionTime, true), + this.moveToHueLogic(targetEnhancedHue, ColorControl.Direction.Shortest, transitionTime, true), () => this.moveToSaturationLogic(targetSaturation, transitionTime), ); } @@ -1161,7 +1161,7 @@ export class ColorControlServerLogic extends ColorControlServerBase { this.state.colorLoopStartEnhancedHue = startHue; } if (updateFlags.updateAction) { - if (action === ColorControl.Action.DeActivateTheColorLoop) { + if (action === ColorControl.ColorLoopAction.Deactivate) { return this.#stopColorLoop(); } else { return MaybePromise.then( @@ -1169,15 +1169,9 @@ export class ColorControlServerLogic extends ColorControlServerBase { () => { this.state.colorLoopStoredEnhancedHue = this.state.enhancedCurrentHue; this.state.colorLoopActive = ColorControl.ColorLoopActive.Active; - if ( - action === - ColorControl.Action.ActivateTheColorLoopFromTheValueInTheColorLoopStartEnhancedHueField - ) { + if (action === ColorControl.ColorLoopAction.ActivateFromColorLoopStartEnhancedHue) { return this.startColorLoopLogic(this.state.colorLoopStartEnhancedHue); - } else if ( - action === - ColorControl.Action.ActivateTheColorLoopFromTheValueOfTheEnhancedCurrentHueAttribute - ) { + } else if (action === ColorControl.ColorLoopAction.ActivateFromEnhancedCurrentHue) { return this.startColorLoopLogic(this.state.enhancedCurrentHue); } }, @@ -1686,13 +1680,13 @@ export class ColorControlServerLogic extends ColorControlServerBase { } else if (direction === ColorControl.Direction.Down) { return -(max - distance); } - if (direction === ColorControl.Direction.ShortestDistance) { + if (direction === ColorControl.Direction.Shortest) { if (Math.abs(distance) > max / 2) { return -(max - distance); } return distance; } - if (direction === ColorControl.Direction.LongestDistance) { + if (direction === ColorControl.Direction.Longest) { if (Math.abs(distance) > max / 2) { return distance; } diff --git a/packages/node/src/behaviors/commissioner-control/CommissionerControlBehavior.ts b/packages/node/src/behaviors/commissioner-control/CommissionerControlBehavior.ts new file mode 100644 index 0000000000..2d0e71ed19 --- /dev/null +++ b/packages/node/src/behaviors/commissioner-control/CommissionerControlBehavior.ts @@ -0,0 +1,24 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { CommissionerControl } from "#clusters/commissioner-control"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { CommissionerControlInterface } from "./CommissionerControlInterface.js"; + +/** + * CommissionerControlBehavior is the base class for objects that support interaction with {@link + * CommissionerControl.Cluster}. + */ +export const CommissionerControlBehavior = ClusterBehavior + .withInterface() + .for(CommissionerControl.Cluster); + +type CommissionerControlBehaviorType = InstanceType; +export interface CommissionerControlBehavior extends CommissionerControlBehaviorType {} +type StateType = InstanceType; +export namespace CommissionerControlBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/commissioner-control/CommissionerControlInterface.ts b/packages/node/src/behaviors/commissioner-control/CommissionerControlInterface.ts new file mode 100644 index 0000000000..1c5701a73c --- /dev/null +++ b/packages/node/src/behaviors/commissioner-control/CommissionerControlInterface.ts @@ -0,0 +1,68 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; +import { CommissionerControl } from "#clusters/commissioner-control"; + +export namespace CommissionerControlInterface { + export interface Base { + /** + * This command is sent by a client to request approval for a future CommissionNode call. This is required to + * be a separate step in order to provide the server time for interacting with a user before informing the + * client that the CommissionNode operation may be successful. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * UNSUPPORTED_ACCESS. + * + * The server may request approval from the user, but it is not required. + * + * The server shall always return SUCCESS to a correctly formatted RequestCommissioningApproval command, and + * then generate a CommissioningRequestResult event associated with the command’s + * + * accessing fabric once the result is ready. + * + * Clients SHOULD avoid using the same RequestID. If the RequestID and client NodeID of a + * RequestCommissioningApproval match a previously received RequestCommissioningApproval and the server has not + * returned an error or completed commissioning of a device for the prior request, then the server SHOULD + * return FAILURE. + * + * The parameters for RequestCommissioningApproval command are as follows: + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.1 + */ + requestCommissioningApproval(request: CommissionerControl.RequestCommissioningApprovalRequest): MaybePromise; + + /** + * This command is sent by a client to request that the server begins commissioning a previously approved + * request. + * + * The server shall return FAILURE if the CommissionNode command is not sent from the same NodeID and on the + * same fabric as the RequestCommissioningApproval or if the provided RequestID to CommissionNode does not + * match the value provided to RequestCommissioningApproval. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * + * UNSUPPORTED_ACCESS. + * + * Upon receipt, the server shall respond with ReverseOpenCommissioningWindow if CommissioningRequestResult was + * generated with StatusCode of SUCCESS for the matching RequestID field and NodeID of the client. + * + * The server shall return FAILURE if the CommissionNode command is received after the server has already + * responded to a client with ReverseOpenCommissioningWindow for a matching RequestID field and NodeID of the + * client unless the client has sent another RequestCommissioningApproval and received an additional + * CommissioningRequestResult. + * + * The parameters for CommissionNode command are as follows: + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.5 + */ + commissionNode(request: CommissionerControl.CommissionNodeRequest): MaybePromise; + } +} + +export type CommissionerControlInterface = { components: [{ flags: {}, methods: CommissionerControlInterface.Base }] }; diff --git a/packages/node/src/behaviors/commissioner-control/CommissionerControlServer.ts b/packages/node/src/behaviors/commissioner-control/CommissionerControlServer.ts new file mode 100644 index 0000000000..50aef0a2ea --- /dev/null +++ b/packages/node/src/behaviors/commissioner-control/CommissionerControlServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { CommissionerControlBehavior } from "./CommissionerControlBehavior.js"; + +/** + * This is the default server implementation of {@link CommissionerControlBehavior}. + */ +export class CommissionerControlServer extends CommissionerControlBehavior {} diff --git a/packages/node/src/behaviors/commissioner-control/index.ts b/packages/node/src/behaviors/commissioner-control/index.ts new file mode 100644 index 0000000000..55ede06a75 --- /dev/null +++ b/packages/node/src/behaviors/commissioner-control/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./CommissionerControlInterface.js"; +export * from "./CommissionerControlBehavior.js"; +export * from "./CommissionerControlServer.js"; diff --git a/packages/node/src/behaviors/concentration-measurement/index.ts b/packages/node/src/behaviors/concentration-measurement/index.ts index f9d791ac10..87e7d08960 100644 --- a/packages/node/src/behaviors/concentration-measurement/index.ts +++ b/packages/node/src/behaviors/concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-app-observer/ContentAppObserverBehavior.ts b/packages/node/src/behaviors/content-app-observer/ContentAppObserverBehavior.ts index 53de11f321..8345101571 100644 --- a/packages/node/src/behaviors/content-app-observer/ContentAppObserverBehavior.ts +++ b/packages/node/src/behaviors/content-app-observer/ContentAppObserverBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-app-observer/ContentAppObserverInterface.ts b/packages/node/src/behaviors/content-app-observer/ContentAppObserverInterface.ts index 5c97faf842..a0cfc6cf03 100644 --- a/packages/node/src/behaviors/content-app-observer/ContentAppObserverInterface.ts +++ b/packages/node/src/behaviors/content-app-observer/ContentAppObserverInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-app-observer/ContentAppObserverServer.ts b/packages/node/src/behaviors/content-app-observer/ContentAppObserverServer.ts index e4f191bdb8..7711da479a 100644 --- a/packages/node/src/behaviors/content-app-observer/ContentAppObserverServer.ts +++ b/packages/node/src/behaviors/content-app-observer/ContentAppObserverServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-app-observer/index.ts b/packages/node/src/behaviors/content-app-observer/index.ts index b44b3647de..c589a7d741 100644 --- a/packages/node/src/behaviors/content-app-observer/index.ts +++ b/packages/node/src/behaviors/content-app-observer/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-control/ContentControlBehavior.ts b/packages/node/src/behaviors/content-control/ContentControlBehavior.ts index 4d4e94db59..4e9d4f77e9 100644 --- a/packages/node/src/behaviors/content-control/ContentControlBehavior.ts +++ b/packages/node/src/behaviors/content-control/ContentControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-control/ContentControlInterface.ts b/packages/node/src/behaviors/content-control/ContentControlInterface.ts index 369afc658a..4e2008e2b8 100644 --- a/packages/node/src/behaviors/content-control/ContentControlInterface.ts +++ b/packages/node/src/behaviors/content-control/ContentControlInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -60,10 +60,9 @@ export namespace ContentControlInterface { /** * The purpose of this command is to add the extra screen time for the user. * - * If a client with Operate privilege invokes this command, the media device shall check whether - * - * the PINCode passed in the command matches the current PINCode value. If these match, then the - * RemainingScreenTime attribute shall be increased by the specified BonusTime value. + * If a client with Operate privilege invokes this command, the media device shall check whether the PINCode + * passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime + * attribute shall be increased by the specified BonusTime value. * * If the PINs do not match, then a response with InvalidPINCode error status shall be returned, and no changes * shall be made to RemainingScreenTime. @@ -121,9 +120,10 @@ export namespace ContentControlInterface { /** * The purpose of this command is to set BlockChannelList attribute. * - * Upon receipt of the AddBlockChannels command, the media device shall check if the channels passed in this - * command are valid. If the channel is invalid, then a response with InvalidChannel error Status shall be - * returned. + * Upon receipt of the AddBlockChannels command, the media device shall check if the channels + * + * passed in this command are valid. If the channel is invalid, then a response with InvalidChannel error + * Status shall be returned. * * If there is at least one channel in Channels field which is not in the BlockChannelList attribute, the media * device shall process the request by adding these new channels into the BlockChannelList attribute and return @@ -156,7 +156,9 @@ export namespace ContentControlInterface { * * Upon receipt of the AddBlockApplications command, the media device shall check if the Applications passed in * this command are installed. If there is an application in Applications field which is not identified by - * media device, then a response with UnidentifiableApplication error Status may be returned. + * media device, then a response with UnidentifiableApplication error Status may be + * + * returned. * * If there is one or more applications which are not present in BlockApplicationList attribute, the media * device shall process the request by adding the new application to the BlockApplicationList attribute and @@ -186,13 +188,12 @@ export namespace ContentControlInterface { /** * The purpose of this command is to set the BlockContentTimeWindow attribute. * - * Upon receipt of the SetBlockContentTimeWindow command, the media device shall check if the - * - * TimeWindowIndex field passed in this command is NULL. If the TimeWindowIndex field is NULL, the media device - * shall check if there is an entry in the BlockContentTimeWindow attribute which matches with the TimePeriod - * and DayOfWeek fields passed in this command. * If Yes, then a response with TimeWindowAlreadyExist error - * status shall be returned. * If No, then the media device shall assign one unique index for this time window - * and add it into the BlockContentTimeWindow list attribute. + * Upon receipt of the SetBlockContentTimeWindow command, the media device shall check if the TimeWindowIndex + * field passed in this command is NULL. If the TimeWindowIndex field is NULL, the media device shall check if + * there is an entry in the BlockContentTimeWindow attribute which matches with the TimePeriod and DayOfWeek + * fields passed in this command. * If Yes, then a response with TimeWindowAlreadyExist error status shall be + * returned. * If No, then the media device shall assign one unique index for this time window and add it into + * the BlockContentTimeWindow list attribute. * * If the TimeWindowIndex field is not NULL and presents in the BlockContentTimeWindow attribute, the media * device shall replace the original time window with the new time window passed in this command. diff --git a/packages/node/src/behaviors/content-control/ContentControlServer.ts b/packages/node/src/behaviors/content-control/ContentControlServer.ts index 3cb3ea5332..bad2d17803 100644 --- a/packages/node/src/behaviors/content-control/ContentControlServer.ts +++ b/packages/node/src/behaviors/content-control/ContentControlServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-control/index.ts b/packages/node/src/behaviors/content-control/index.ts index 3e91fadada..f6e02cd725 100644 --- a/packages/node/src/behaviors/content-control/index.ts +++ b/packages/node/src/behaviors/content-control/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-launcher/ContentLauncherBehavior.ts b/packages/node/src/behaviors/content-launcher/ContentLauncherBehavior.ts index d14f2a80d9..36969b4d69 100644 --- a/packages/node/src/behaviors/content-launcher/ContentLauncherBehavior.ts +++ b/packages/node/src/behaviors/content-launcher/ContentLauncherBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-launcher/ContentLauncherInterface.ts b/packages/node/src/behaviors/content-launcher/ContentLauncherInterface.ts index 1b58c469e2..7e343944c2 100644 --- a/packages/node/src/behaviors/content-launcher/ContentLauncherInterface.ts +++ b/packages/node/src/behaviors/content-launcher/ContentLauncherInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,9 +14,8 @@ export namespace ContentLauncherInterface { /** * Upon receipt, this shall launch content from the specified URL. * - * The content types supported include those identified in the AcceptHeader and SupportedStreaming - * - * Protocols attributes. + * The content types supported include those identified in the AcceptHeader and SupportedStreamingProtocols + * attributes. * * A check shall be made to ensure the URL is secure (uses HTTPS). * diff --git a/packages/node/src/behaviors/content-launcher/ContentLauncherServer.ts b/packages/node/src/behaviors/content-launcher/ContentLauncherServer.ts index 683b84b2ac..f438fbf7f9 100644 --- a/packages/node/src/behaviors/content-launcher/ContentLauncherServer.ts +++ b/packages/node/src/behaviors/content-launcher/ContentLauncherServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/content-launcher/index.ts b/packages/node/src/behaviors/content-launcher/index.ts index 31957c6217..06aced08fd 100644 --- a/packages/node/src/behaviors/content-launcher/index.ts +++ b/packages/node/src/behaviors/content-launcher/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/descriptor/DescriptorBehavior.ts b/packages/node/src/behaviors/descriptor/DescriptorBehavior.ts index e0ded93a8f..463e511c8e 100644 --- a/packages/node/src/behaviors/descriptor/DescriptorBehavior.ts +++ b/packages/node/src/behaviors/descriptor/DescriptorBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/descriptor/index.ts b/packages/node/src/behaviors/descriptor/index.ts index 36da823db4..7fd38a7b88 100644 --- a/packages/node/src/behaviors/descriptor/index.ts +++ b/packages/node/src/behaviors/descriptor/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/device-energy-management-mode/DeviceEnergyManagementModeBehavior.ts b/packages/node/src/behaviors/device-energy-management-mode/DeviceEnergyManagementModeBehavior.ts index df4ce84cc3..05c920ff51 100644 --- a/packages/node/src/behaviors/device-energy-management-mode/DeviceEnergyManagementModeBehavior.ts +++ b/packages/node/src/behaviors/device-energy-management-mode/DeviceEnergyManagementModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,9 +12,6 @@ import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; /** * DeviceEnergyManagementModeBehavior is the base class for objects that support interaction with {@link * DeviceEnergyManagementMode.Cluster}. - * - * This class does not have optional features of DeviceEnergyManagementMode.Cluster enabled. You can enable additional - * features using DeviceEnergyManagementModeBehavior.with. */ export const DeviceEnergyManagementModeBehavior = ClusterBehavior.for(DeviceEnergyManagementMode.Cluster); diff --git a/packages/node/src/behaviors/device-energy-management-mode/DeviceEnergyManagementModeServer.ts b/packages/node/src/behaviors/device-energy-management-mode/DeviceEnergyManagementModeServer.ts index 323d21fa20..7d940ffae7 100644 --- a/packages/node/src/behaviors/device-energy-management-mode/DeviceEnergyManagementModeServer.ts +++ b/packages/node/src/behaviors/device-energy-management-mode/DeviceEnergyManagementModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/device-energy-management-mode/index.ts b/packages/node/src/behaviors/device-energy-management-mode/index.ts index 02f50244f7..f6bf733dbe 100644 --- a/packages/node/src/behaviors/device-energy-management-mode/index.ts +++ b/packages/node/src/behaviors/device-energy-management-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementBehavior.ts b/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementBehavior.ts index 1bdca772a2..bd38b2180b 100644 --- a/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementBehavior.ts +++ b/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementInterface.ts b/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementInterface.ts index db01b7efc1..e489442445 100644 --- a/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementInterface.ts +++ b/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementServer.ts b/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementServer.ts index c4f6b59443..b41180785e 100644 --- a/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementServer.ts +++ b/packages/node/src/behaviors/device-energy-management/DeviceEnergyManagementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/device-energy-management/index.ts b/packages/node/src/behaviors/device-energy-management/index.ts index 78b6ab7a23..1356e434e0 100644 --- a/packages/node/src/behaviors/device-energy-management/index.ts +++ b/packages/node/src/behaviors/device-energy-management/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsBehavior.ts b/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsBehavior.ts index 6792dbd133..8f1b293a82 100644 --- a/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsBehavior.ts +++ b/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsInterface.ts b/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsInterface.ts index c75b80041d..b8b65397eb 100644 --- a/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsInterface.ts +++ b/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsServer.ts b/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsServer.ts index 7af94088ef..4ab4032204 100644 --- a/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsServer.ts +++ b/packages/node/src/behaviors/diagnostic-logs/DiagnosticLogsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/diagnostic-logs/index.ts b/packages/node/src/behaviors/diagnostic-logs/index.ts index 0c07c14fa6..237f2dae6d 100644 --- a/packages/node/src/behaviors/diagnostic-logs/index.ts +++ b/packages/node/src/behaviors/diagnostic-logs/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/dishwasher-alarm/DishwasherAlarmBehavior.ts b/packages/node/src/behaviors/dishwasher-alarm/DishwasherAlarmBehavior.ts index 821bc3ebae..e6d8d72b12 100644 --- a/packages/node/src/behaviors/dishwasher-alarm/DishwasherAlarmBehavior.ts +++ b/packages/node/src/behaviors/dishwasher-alarm/DishwasherAlarmBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/dishwasher-alarm/DishwasherAlarmServer.ts b/packages/node/src/behaviors/dishwasher-alarm/DishwasherAlarmServer.ts index f2fe593812..dec6c5126f 100644 --- a/packages/node/src/behaviors/dishwasher-alarm/DishwasherAlarmServer.ts +++ b/packages/node/src/behaviors/dishwasher-alarm/DishwasherAlarmServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/dishwasher-alarm/index.ts b/packages/node/src/behaviors/dishwasher-alarm/index.ts index 98f8aa1469..6fc2ed1bf4 100644 --- a/packages/node/src/behaviors/dishwasher-alarm/index.ts +++ b/packages/node/src/behaviors/dishwasher-alarm/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/dishwasher-mode/DishwasherModeBehavior.ts b/packages/node/src/behaviors/dishwasher-mode/DishwasherModeBehavior.ts index 6dba92847a..a8ce1e12eb 100644 --- a/packages/node/src/behaviors/dishwasher-mode/DishwasherModeBehavior.ts +++ b/packages/node/src/behaviors/dishwasher-mode/DishwasherModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/dishwasher-mode/DishwasherModeServer.ts b/packages/node/src/behaviors/dishwasher-mode/DishwasherModeServer.ts index 8dfac2038f..c0fb880e69 100644 --- a/packages/node/src/behaviors/dishwasher-mode/DishwasherModeServer.ts +++ b/packages/node/src/behaviors/dishwasher-mode/DishwasherModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/dishwasher-mode/index.ts b/packages/node/src/behaviors/dishwasher-mode/index.ts index 4b7f5f653c..2a5972142f 100644 --- a/packages/node/src/behaviors/dishwasher-mode/index.ts +++ b/packages/node/src/behaviors/dishwasher-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/door-lock/DoorLockBehavior.ts b/packages/node/src/behaviors/door-lock/DoorLockBehavior.ts index 7c94fb65b3..de1fc1319b 100644 --- a/packages/node/src/behaviors/door-lock/DoorLockBehavior.ts +++ b/packages/node/src/behaviors/door-lock/DoorLockBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/door-lock/DoorLockInterface.ts b/packages/node/src/behaviors/door-lock/DoorLockInterface.ts index 9ea4876817..afbd0855ba 100644 --- a/packages/node/src/behaviors/door-lock/DoorLockInterface.ts +++ b/packages/node/src/behaviors/door-lock/DoorLockInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,8 +15,6 @@ export namespace DoorLockInterface { * This command causes the lock device to lock the door. This command includes an optional code for the lock. * The door lock may require a PIN depending on the value of the RequirePINForRemoteOperation attribute. * - * † The PIN/RFID Code is an obsolete field name, use PINCode instead. - * * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.1 */ lockDoor(request: DoorLock.LockDoorRequest): MaybePromise; @@ -30,8 +28,6 @@ export namespace DoorLockInterface { * If the attribute AutoRelockTime is supported the lock will transition to the locked state when the auto * relock time has expired. * - * † The PIN/RFID Code is an obsolete field name, use PINCode instead. - * * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.2 */ unlockDoor(request: DoorLock.UnlockDoorRequest): MaybePromise; @@ -39,30 +35,15 @@ export namespace DoorLockInterface { /** * This command causes the lock device to unlock the door with a timeout parameter. After the time in seconds * specified in the timeout field, the lock device will relock itself automatically. This timeout parameter is - * only temporary for this message transition and overrides the default relock time - * - * as specified in the AutoRelockTime attribute. If the door lock device is not capable of or does not want to - * support temporary Relock Timeout, it SHOULD NOT support this optional command. - * - * † The PIN/RFID Code is an obsolete field name, use PINCode instead. + * only temporary for this message transition and overrides the default relock time as specified in the + * AutoRelockTime attribute. If the door lock device is not capable of or does not want to support temporary + * Relock Timeout, it SHOULD NOT support this optional command. * * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.3 */ unlockWithTimeout(request: DoorLock.UnlockWithTimeoutRequest): MaybePromise; } - export interface Logging { - /** - * Request a log record. Log number is between 1 – [Number of Log Records Supported attribute]. If log number 0 - * is requested then the most recent log entry is returned. - * - * Log record format: The log record format is defined in the description of the GetLogRecordResponse command. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4 - */ - getLogRecord(request: DoorLock.GetLogRecordRequest): MaybePromise; - } - export interface User { /** * Set user into the lock. @@ -82,7 +63,7 @@ export namespace DoorLockInterface { * • INVALID_COMMAND, if one or more fields violate constraints or are invalid or if OperationType is Modify * and UserIndex points to an available slot. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32 */ setUser(request: DoorLock.SetUserRequest): MaybePromise; @@ -93,7 +74,7 @@ export namespace DoorLockInterface { * * COMMAND, etc.) as needed otherwise the GetUserResponse Command shall be sent implying a status of SUCCESS. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.33 */ getUser(request: DoorLock.GetUserRequest): MaybePromise; @@ -106,7 +87,7 @@ export namespace DoorLockInterface { * * A LockUserChange event with the provided UserIndex shall be generated after successfully clearing users. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35 */ clearUser(request: DoorLock.ClearUserRequest): MaybePromise; @@ -116,7 +97,7 @@ export namespace DoorLockInterface { * * Fields used for different use cases: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36 */ setCredential(request: DoorLock.SetCredentialRequest): MaybePromise; @@ -126,7 +107,7 @@ export namespace DoorLockInterface { * An InvokeResponse command shall be sent with an appropriate error (e.g. FAILURE, INVALID_COMMAND, etc.) as * needed otherwise the GetCredentialStatusResponse command shall be sent implying a status of SUCCESS. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.38 */ getCredentialStatus(request: DoorLock.GetCredentialStatusRequest): MaybePromise; @@ -137,12 +118,12 @@ export namespace DoorLockInterface { * * For each credential cleared whose user doesn’t have another valid credential, the corresponding user record * shall be reset back to default values and its UserStatus value shall be set to Available and UserType value - * shall be set to UnrestrictedUser and all schedules shall be cleared. In + * shall be set to UnrestrictedUser and all schedules shall be cleared. In this case a LockUserChange event + * shall be generated for the user being cleared. * - * this case a LockUserChange event shall be generated for the user being cleared. Return status shall be one - * of the following values: + * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.44 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40 */ clearCredential(request: DoorLock.ClearCredentialRequest): MaybePromise; } @@ -151,33 +132,27 @@ export namespace DoorLockInterface { /** * Set a weekly repeating schedule for a specified user. * - * † The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, respectively. - * * The associated UserType may be changed to ScheduleRestrictedUser by the lock when a Week Day schedule is set. * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12 */ setWeekDaySchedule(request: DoorLock.SetWeekDayScheduleRequest): MaybePromise; /** * Retrieve the specific weekly schedule for the specific user. * - * † The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, respectively. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.13 */ getWeekDaySchedule(request: DoorLock.GetWeekDayScheduleRequest): MaybePromise; /** * Clear the specific weekly schedule or all weekly schedules for the specific user. * - * † The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, respectively. - * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15 */ clearWeekDaySchedule(request: DoorLock.ClearWeekDayScheduleRequest): MaybePromise; } @@ -186,33 +161,27 @@ export namespace DoorLockInterface { /** * Set a time-specific schedule ID for a specified user. * - * † The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, respectively. - * * The associated UserType may be changed to ScheduleRestrictedUser by the lock when a Year Day schedule is set. * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16 */ setYearDaySchedule(request: DoorLock.SetYearDayScheduleRequest): MaybePromise; /** * Retrieve the specific year day schedule for the specific schedule and user indexes. * - * † The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, respectively. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17 */ getYearDaySchedule(request: DoorLock.GetYearDayScheduleRequest): MaybePromise; /** * Clears the specific year day schedule or all year day schedules for the specific user. * - * † The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, respectively. - * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19 */ clearYearDaySchedule(request: DoorLock.ClearYearDayScheduleRequest): MaybePromise; } @@ -222,28 +191,23 @@ export namespace DoorLockInterface { * Set the holiday Schedule by specifying local start time and local end time with respect to any Lock * Operating Mode. * - * † The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. Return status shall be one of - * the following values: + * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20 */ setHolidaySchedule(request: DoorLock.SetHolidayScheduleRequest): MaybePromise; /** * Get the holiday schedule for the specified index. * - * † The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21 */ getHolidaySchedule(request: DoorLock.GetHolidayScheduleRequest): MaybePromise; /** * Clears the holiday schedule or all holiday schedules. * - * † The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23 */ clearHolidaySchedule(request: DoorLock.ClearHolidayScheduleRequest): MaybePromise; } @@ -255,27 +219,25 @@ export namespace DoorLockInterface { * Return status is a global status code or a cluster-specific status code from the Status Codes table and * shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4 */ setPinCode(request: DoorLock.SetPinCodeRequest): MaybePromise; /** * Retrieve a PIN Code. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5 */ getPinCode(request: DoorLock.GetPinCodeRequest): MaybePromise; /** * Clear a PIN code or all PIN codes. * - * † The User ID is an obsolete field name, use PINSlotIndex instead. - * * For each PIN Code cleared whose user doesn’t have a RFID Code or other credential type, then corresponding * user record’s UserStatus value shall be set to Available, and UserType value shall be set to * UnrestrictedUser and all schedules shall be cleared. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7 */ clearPinCode(request: DoorLock.ClearPinCodeRequest): MaybePromise; @@ -287,23 +249,46 @@ export namespace DoorLockInterface { * On the server, the clear all PIN codes command SHOULD have the same effect as the ClearPINCode command with * respect to the setting of user status, user type and schedules. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.10 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.8 */ clearAllPinCodes(): MaybePromise; } + export interface AliroProvisioning { + /** + * This command allows communicating an Aliro Reader configuration, as defined in [Aliro], to the lock. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42 + */ + setAliroReaderConfig(request: DoorLock.SetAliroReaderConfigRequest): MaybePromise; + + /** + * This command allows clearing an existing Aliro Reader configuration for the lock. Administrators shall NOT + * clear an Aliro Reader configuration without explicit user permission. + * + * NOTE + * + * Using this command will revoke the ability of all existing Aliro user devices that have the old verification + * key to interact with the lock. This effect is not restricted to a single fabric or otherwise scoped in any + * way. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43 + */ + clearAliroReaderConfig(): MaybePromise; + } + export interface PinCredentialAndRfidCredentialAndFingerCredentialsNotUser { /** * Set the status of a user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9 */ setUserStatus(request: DoorLock.SetUserStatusRequest): MaybePromise; /** * Get the status of a user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.10 */ getUserStatus(request: DoorLock.GetUserStatusRequest): MaybePromise; @@ -314,14 +299,14 @@ export namespace DoorLockInterface { * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.26 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24 */ setUserType(request: DoorLock.SetUserTypeRequest): MaybePromise; /** * Retrieve the user type for a specific user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25 */ getUserType(request: DoorLock.GetUserTypeRequest): MaybePromise; } @@ -333,27 +318,25 @@ export namespace DoorLockInterface { * Return status is a global status code or a cluster-specific status code from the Status Codes table and * shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27 */ setRfidCode(request: DoorLock.SetRfidCodeRequest): MaybePromise; /** * Retrieve an RFID code. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.28 */ getRfidCode(request: DoorLock.GetRfidCodeRequest): MaybePromise; /** * Clear an RFID code or all RFID codes. * - * † The User ID is an obsolete field name, use RFIDSlotIndex instead. - * * For each RFID Code cleared whose user doesn’t have a PIN Code or other credential type, then the * corresponding user record’s UserStatus value shall be set to Available, and UserType value shall be set to * UnrestrictedUser and all schedules shall be cleared. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30 */ clearRfidCode(request: DoorLock.ClearRfidCodeRequest): MaybePromise; @@ -362,7 +345,7 @@ export namespace DoorLockInterface { * status has to be set to "0 Available", the user type has to be set to the default value, and all schedules * which are supported have to be set to the default values. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.33 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.31 */ clearAllRfidCodes(): MaybePromise; } @@ -378,7 +361,7 @@ export namespace DoorLockInterface { * If the attribute AutoRelockTime is supported, the lock will transition to the locked state when the auto * relock time has expired. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.45 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41 */ unboltDoor(request: DoorLock.UnboltDoorRequest): MaybePromise; } @@ -387,12 +370,12 @@ export namespace DoorLockInterface { export type DoorLockInterface = { components: [ { flags: {}, methods: DoorLockInterface.Base }, - { flags: { logging: true }, methods: DoorLockInterface.Logging }, { flags: { user: true }, methods: DoorLockInterface.User }, { flags: { weekDayAccessSchedules: true }, methods: DoorLockInterface.WeekDayAccessSchedules }, { flags: { yearDayAccessSchedules: true }, methods: DoorLockInterface.YearDayAccessSchedules }, { flags: { holidaySchedules: true }, methods: DoorLockInterface.HolidaySchedules }, { flags: { pinCredential: true, user: false }, methods: DoorLockInterface.PinCredentialNotUser }, + { flags: { aliroProvisioning: true }, methods: DoorLockInterface.AliroProvisioning }, { flags: { pinCredential: true, rfidCredential: true, fingerCredentials: true, user: false }, methods: DoorLockInterface.PinCredentialAndRfidCredentialAndFingerCredentialsNotUser diff --git a/packages/node/src/behaviors/door-lock/index.ts b/packages/node/src/behaviors/door-lock/index.ts index 1394835d37..53899bf6b9 100644 --- a/packages/node/src/behaviors/door-lock/index.ts +++ b/packages/node/src/behaviors/door-lock/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ecosystem-information/EcosystemInformationBehavior.ts b/packages/node/src/behaviors/ecosystem-information/EcosystemInformationBehavior.ts new file mode 100644 index 0000000000..4295567053 --- /dev/null +++ b/packages/node/src/behaviors/ecosystem-information/EcosystemInformationBehavior.ts @@ -0,0 +1,21 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { EcosystemInformation } from "#clusters/ecosystem-information"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; + +/** + * EcosystemInformationBehavior is the base class for objects that support interaction with {@link + * EcosystemInformation.Cluster}. + */ +export const EcosystemInformationBehavior = ClusterBehavior.for(EcosystemInformation.Cluster); + +type EcosystemInformationBehaviorType = InstanceType; +export interface EcosystemInformationBehavior extends EcosystemInformationBehaviorType {} +type StateType = InstanceType; +export namespace EcosystemInformationBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/ecosystem-information/EcosystemInformationServer.ts b/packages/node/src/behaviors/ecosystem-information/EcosystemInformationServer.ts new file mode 100644 index 0000000000..3183c06c7d --- /dev/null +++ b/packages/node/src/behaviors/ecosystem-information/EcosystemInformationServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { EcosystemInformationBehavior } from "./EcosystemInformationBehavior.js"; + +/** + * This is the default server implementation of {@link EcosystemInformationBehavior}. + */ +export class EcosystemInformationServer extends EcosystemInformationBehavior {} diff --git a/packages/node/src/behaviors/ecosystem-information/index.ts b/packages/node/src/behaviors/ecosystem-information/index.ts new file mode 100644 index 0000000000..3ef4ff7e15 --- /dev/null +++ b/packages/node/src/behaviors/ecosystem-information/index.ts @@ -0,0 +1,10 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./EcosystemInformationBehavior.js"; +export * from "./EcosystemInformationServer.js"; diff --git a/packages/node/src/behaviors/electrical-energy-measurement/ElectricalEnergyMeasurementBehavior.ts b/packages/node/src/behaviors/electrical-energy-measurement/ElectricalEnergyMeasurementBehavior.ts index 8bd501e932..d7dc511c38 100644 --- a/packages/node/src/behaviors/electrical-energy-measurement/ElectricalEnergyMeasurementBehavior.ts +++ b/packages/node/src/behaviors/electrical-energy-measurement/ElectricalEnergyMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/electrical-energy-measurement/index.ts b/packages/node/src/behaviors/electrical-energy-measurement/index.ts index 0c18463762..28adae6d91 100644 --- a/packages/node/src/behaviors/electrical-energy-measurement/index.ts +++ b/packages/node/src/behaviors/electrical-energy-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/electrical-power-measurement/ElectricalPowerMeasurementBehavior.ts b/packages/node/src/behaviors/electrical-power-measurement/ElectricalPowerMeasurementBehavior.ts index a27f9095f4..f093aac392 100644 --- a/packages/node/src/behaviors/electrical-power-measurement/ElectricalPowerMeasurementBehavior.ts +++ b/packages/node/src/behaviors/electrical-power-measurement/ElectricalPowerMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/electrical-power-measurement/ElectricalPowerMeasurementServer.ts b/packages/node/src/behaviors/electrical-power-measurement/ElectricalPowerMeasurementServer.ts index 47dacd7eab..999903d12b 100644 --- a/packages/node/src/behaviors/electrical-power-measurement/ElectricalPowerMeasurementServer.ts +++ b/packages/node/src/behaviors/electrical-power-measurement/ElectricalPowerMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/electrical-power-measurement/index.ts b/packages/node/src/behaviors/electrical-power-measurement/index.ts index 8aafce6446..88e89a8349 100644 --- a/packages/node/src/behaviors/electrical-power-measurement/index.ts +++ b/packages/node/src/behaviors/electrical-power-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/energy-evse-mode/EnergyEvseModeBehavior.ts b/packages/node/src/behaviors/energy-evse-mode/EnergyEvseModeBehavior.ts index e58cfccc6a..775f286517 100644 --- a/packages/node/src/behaviors/energy-evse-mode/EnergyEvseModeBehavior.ts +++ b/packages/node/src/behaviors/energy-evse-mode/EnergyEvseModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,9 +11,6 @@ import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; /** * EnergyEvseModeBehavior is the base class for objects that support interaction with {@link EnergyEvseMode.Cluster}. - * - * This class does not have optional features of EnergyEvseMode.Cluster enabled. You can enable additional features - * using EnergyEvseModeBehavior.with. */ export const EnergyEvseModeBehavior = ClusterBehavior.for(EnergyEvseMode.Cluster); diff --git a/packages/node/src/behaviors/energy-evse-mode/EnergyEvseModeServer.ts b/packages/node/src/behaviors/energy-evse-mode/EnergyEvseModeServer.ts index e1c88c1bef..788369e93b 100644 --- a/packages/node/src/behaviors/energy-evse-mode/EnergyEvseModeServer.ts +++ b/packages/node/src/behaviors/energy-evse-mode/EnergyEvseModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/energy-evse-mode/index.ts b/packages/node/src/behaviors/energy-evse-mode/index.ts index 226d6e2f9e..8ef2eac409 100644 --- a/packages/node/src/behaviors/energy-evse-mode/index.ts +++ b/packages/node/src/behaviors/energy-evse-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/energy-evse/EnergyEvseBehavior.ts b/packages/node/src/behaviors/energy-evse/EnergyEvseBehavior.ts index 07b7911221..8280e1c9a6 100644 --- a/packages/node/src/behaviors/energy-evse/EnergyEvseBehavior.ts +++ b/packages/node/src/behaviors/energy-evse/EnergyEvseBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/energy-evse/EnergyEvseInterface.ts b/packages/node/src/behaviors/energy-evse/EnergyEvseInterface.ts index c9e587bdf7..5e0562834c 100644 --- a/packages/node/src/behaviors/energy-evse/EnergyEvseInterface.ts +++ b/packages/node/src/behaviors/energy-evse/EnergyEvseInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,8 @@ export namespace EnergyEvseInterface { disable(): MaybePromise; /** - * Allows a client to enable the EVSE to charge an EV. + * This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum and + * minimum charge current. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.9.2 */ @@ -35,7 +36,8 @@ export namespace EnergyEvseInterface { export interface V2X { /** - * Allows a client to enable the EVSE to discharge an EV. + * Upon receipt, this shall allow a client to enable the discharge of an EV, and to provide or update the + * maximum discharge current. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.9.3 */ diff --git a/packages/node/src/behaviors/energy-evse/EnergyEvseServer.ts b/packages/node/src/behaviors/energy-evse/EnergyEvseServer.ts index e57407158c..e992bfd1cf 100644 --- a/packages/node/src/behaviors/energy-evse/EnergyEvseServer.ts +++ b/packages/node/src/behaviors/energy-evse/EnergyEvseServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/energy-evse/index.ts b/packages/node/src/behaviors/energy-evse/index.ts index f323bfcca1..73e6ff9788 100644 --- a/packages/node/src/behaviors/energy-evse/index.ts +++ b/packages/node/src/behaviors/energy-evse/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/energy-preference/EnergyPreferenceBehavior.ts b/packages/node/src/behaviors/energy-preference/EnergyPreferenceBehavior.ts index 7eeb3405fc..5104ffe9ef 100644 --- a/packages/node/src/behaviors/energy-preference/EnergyPreferenceBehavior.ts +++ b/packages/node/src/behaviors/energy-preference/EnergyPreferenceBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/energy-preference/EnergyPreferenceServer.ts b/packages/node/src/behaviors/energy-preference/EnergyPreferenceServer.ts index 5096add1fc..8bbdfa904c 100644 --- a/packages/node/src/behaviors/energy-preference/EnergyPreferenceServer.ts +++ b/packages/node/src/behaviors/energy-preference/EnergyPreferenceServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/energy-preference/index.ts b/packages/node/src/behaviors/energy-preference/index.ts index 51522ddafa..8be9768aef 100644 --- a/packages/node/src/behaviors/energy-preference/index.ts +++ b/packages/node/src/behaviors/energy-preference/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsBehavior.ts b/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsBehavior.ts index 18e7481f46..d921be84e8 100644 --- a/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsBehavior.ts +++ b/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsInterface.ts b/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsInterface.ts index 8f289a6cfd..e0f0964434 100644 --- a/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsInterface.ts +++ b/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsServer.ts b/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsServer.ts index 7b30469312..05b897530f 100644 --- a/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsServer.ts +++ b/packages/node/src/behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ethernet-network-diagnostics/index.ts b/packages/node/src/behaviors/ethernet-network-diagnostics/index.ts index 6de97f0db4..333bebd054 100644 --- a/packages/node/src/behaviors/ethernet-network-diagnostics/index.ts +++ b/packages/node/src/behaviors/ethernet-network-diagnostics/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/fan-control/FanControlBehavior.ts b/packages/node/src/behaviors/fan-control/FanControlBehavior.ts index f0b70d1782..1e578e76e2 100644 --- a/packages/node/src/behaviors/fan-control/FanControlBehavior.ts +++ b/packages/node/src/behaviors/fan-control/FanControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/fan-control/FanControlInterface.ts b/packages/node/src/behaviors/fan-control/FanControlInterface.ts index 54d1ab1fde..6a39038f68 100644 --- a/packages/node/src/behaviors/fan-control/FanControlInterface.ts +++ b/packages/node/src/behaviors/fan-control/FanControlInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/fan-control/FanControlServer.ts b/packages/node/src/behaviors/fan-control/FanControlServer.ts index bee3b6bd95..3e1619d833 100644 --- a/packages/node/src/behaviors/fan-control/FanControlServer.ts +++ b/packages/node/src/behaviors/fan-control/FanControlServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/fan-control/index.ts b/packages/node/src/behaviors/fan-control/index.ts index 091156d7df..45f310d3fc 100644 --- a/packages/node/src/behaviors/fan-control/index.ts +++ b/packages/node/src/behaviors/fan-control/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/fixed-label/FixedLabelBehavior.ts b/packages/node/src/behaviors/fixed-label/FixedLabelBehavior.ts index c22d6c5420..5e16edd829 100644 --- a/packages/node/src/behaviors/fixed-label/FixedLabelBehavior.ts +++ b/packages/node/src/behaviors/fixed-label/FixedLabelBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/fixed-label/FixedLabelServer.ts b/packages/node/src/behaviors/fixed-label/FixedLabelServer.ts index 593e77b698..caa0986c77 100644 --- a/packages/node/src/behaviors/fixed-label/FixedLabelServer.ts +++ b/packages/node/src/behaviors/fixed-label/FixedLabelServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/fixed-label/index.ts b/packages/node/src/behaviors/fixed-label/index.ts index ff817884a2..66032a308a 100644 --- a/packages/node/src/behaviors/fixed-label/index.ts +++ b/packages/node/src/behaviors/fixed-label/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/flow-measurement/FlowMeasurementBehavior.ts b/packages/node/src/behaviors/flow-measurement/FlowMeasurementBehavior.ts index 8aff036000..cfb77f85e4 100644 --- a/packages/node/src/behaviors/flow-measurement/FlowMeasurementBehavior.ts +++ b/packages/node/src/behaviors/flow-measurement/FlowMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/flow-measurement/FlowMeasurementServer.ts b/packages/node/src/behaviors/flow-measurement/FlowMeasurementServer.ts index 458b622e75..c17ee25c2d 100644 --- a/packages/node/src/behaviors/flow-measurement/FlowMeasurementServer.ts +++ b/packages/node/src/behaviors/flow-measurement/FlowMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/flow-measurement/index.ts b/packages/node/src/behaviors/flow-measurement/index.ts index 761e46f7e5..21003b8019 100644 --- a/packages/node/src/behaviors/flow-measurement/index.ts +++ b/packages/node/src/behaviors/flow-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/formaldehyde-concentration-measurement/FormaldehydeConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/formaldehyde-concentration-measurement/FormaldehydeConcentrationMeasurementBehavior.ts index f9c374d778..a2a5be410e 100644 --- a/packages/node/src/behaviors/formaldehyde-concentration-measurement/FormaldehydeConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/formaldehyde-concentration-measurement/FormaldehydeConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/formaldehyde-concentration-measurement/FormaldehydeConcentrationMeasurementServer.ts b/packages/node/src/behaviors/formaldehyde-concentration-measurement/FormaldehydeConcentrationMeasurementServer.ts index 21350967aa..93e8ad86da 100644 --- a/packages/node/src/behaviors/formaldehyde-concentration-measurement/FormaldehydeConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/formaldehyde-concentration-measurement/FormaldehydeConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/formaldehyde-concentration-measurement/index.ts b/packages/node/src/behaviors/formaldehyde-concentration-measurement/index.ts index 07ad1d12ef..f99676d6f6 100644 --- a/packages/node/src/behaviors/formaldehyde-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/formaldehyde-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/general-commissioning/GeneralCommissioningBehavior.ts b/packages/node/src/behaviors/general-commissioning/GeneralCommissioningBehavior.ts index f2da0311ba..f03fd942ff 100644 --- a/packages/node/src/behaviors/general-commissioning/GeneralCommissioningBehavior.ts +++ b/packages/node/src/behaviors/general-commissioning/GeneralCommissioningBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,9 @@ import { GeneralCommissioningInterface } from "./GeneralCommissioningInterface.j /** * GeneralCommissioningBehavior is the base class for objects that support interaction with {@link * GeneralCommissioning.Cluster}. + * + * This class does not have optional features of GeneralCommissioning.Cluster enabled. You can enable additional + * features using GeneralCommissioningBehavior.with. */ export const GeneralCommissioningBehavior = ClusterBehavior .withInterface() diff --git a/packages/node/src/behaviors/general-commissioning/GeneralCommissioningInterface.ts b/packages/node/src/behaviors/general-commissioning/GeneralCommissioningInterface.ts index 49492592b1..4f68d7d92d 100644 --- a/packages/node/src/behaviors/general-commissioning/GeneralCommissioningInterface.ts +++ b/packages/node/src/behaviors/general-commissioning/GeneralCommissioningInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -25,9 +25,8 @@ export namespace GeneralCommissioningInterface { * ExpiryLengthSeconds, or disarm it, depending on the situation: * * • If ExpiryLengthSeconds is 0 and the fail-safe timer was already armed and the accessing fabric matches - * the Fabric currently associated with the fail-safe context, then the fail-safe timer - * - * shall be immediately expired (see further below for side-effects of expiration). + * the Fabric currently associated with the fail-safe context, then the fail-safe timer shall be + * immediately expired (see further below for side-effects of expiration). * * • If ExpiryLengthSeconds is 0 and the fail-safe timer was not armed, then this command invocation shall * lead to a success response with no side-effects against the fail-safe context. @@ -43,8 +42,7 @@ export namespace GeneralCommissioningInterface { * ArmFailSafeResponse containing an ErrorCode value of BusyWithOtherAdmin, indicating a likely conflict * between commissioners. * - * The value of the Breadcrumb field shall be written to the Breadcrumb Attribute on successful execution of - * the command. + * The value of the Breadcrumb field shall be written to the Breadcrumb on successful execution of the command. * * If the receiver restarts unexpectedly (e.g., power interruption, software crash, or other reset) the * receiver shall behave as if the fail-safe timer expired and perform the sequence of clean-up steps listed @@ -88,7 +86,7 @@ export namespace GeneralCommissioningInterface { * (CFSC timer) serves to limit the lifetime of any particular Fail Safe Context; it shall NOT be extended or * modified on subsequent invocations of ArmFailSafe associated with this Fail Safe Context. Upon expiry of the * CFSC timer, the receiver shall execute cleanup behavior equivalent to that of fail-safe timer expiration as - * detailed in Section 11.10.6.2.2, “Behavior on expiry of Fail-Safe timer”. Termination of the session prior + * detailed in Section 11.10.7.2.2, “Behavior on expiry of Fail-Safe timer”. Termination of the session prior * to the expiration of that timer for any reason (including a successful end of commissioning or an expiry of * a fail-safe timer) shall also delete the CFSC timer. * @@ -99,12 +97,12 @@ export namespace GeneralCommissioningInterface { * * 1. Terminate any open PASE secure session by clearing any associated Secure Session Context at the Server. * - * 2. Revoke the temporary administrative privileges granted to any open PASE session (see Section 6.6.2.8, + * 2. Revoke the temporary administrative privileges granted to any open PASE session (see Section 6.6.2.9, * “Bootstrapping of the Access Control Cluster”) at the Server. * * 3. If an AddNOC or UpdateNOC command has been successfully invoked, terminate all CASE sessions associated - * with the Fabric whose Fabric Index is recorded in the Fail-Safe context (see Section 11.10.6.2, - * “ArmFailSafe Command”) by clearing any associated Secure Session Context at the Server. + * with the Fabric whose Fabric Index is recorded in the Fail-Safe context (see ArmFailSafe) by clearing + * any associated Secure Session Context at the Server. * * 4. Reset the configuration of all Network Commissioning Networks attribute to their state prior to the * Fail-Safe being armed. @@ -129,11 +127,10 @@ export namespace GeneralCommissioningInterface { * * 9. Reset the Breadcrumb attribute to zero. * - * 10. Optionally: if no factory-reset resulted from the previous steps, it is recommended that the - * - * Node rollback the state of all non fabric-scoped data present in the Fail-Safe context. + * 10. Optionally: if no factory-reset resulted from the previous steps, it is recommended that the Node + * rollback the state of all non fabric-scoped data present in the Fail-Safe context. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.2 */ armFailSafe(request: GeneralCommissioning.ArmFailSafeRequest): MaybePromise; @@ -152,8 +149,9 @@ export namespace GeneralCommissioningInterface { * Location attribute reflected by the Basic Information Cluster configuration, but the * SetRegulatoryConfigResponse replied shall have the ErrorCode field set to ValueOutsideRange error. * - * If the LocationCapability attribute is not Indoor/Outdoor and the NewRegulatoryConfig value received does - * not match either the Indoor or Outdoor fixed value in LocationCapability, then the + * If the LocationCapability attribute is not Indoor/Outdoor and the NewRegulatoryConfig value + * + * received does not match either the Indoor or Outdoor fixed value in LocationCapability, then the * SetRegulatoryConfigResponse replied shall have the ErrorCode field set to ValueOutsideRange error and the * RegulatoryConfig attribute and associated internal radio configuration shall remain unchanged. * @@ -167,7 +165,7 @@ export namespace GeneralCommissioningInterface { * when SetRegulatoryConfigResponse has the ErrorCode field set to OK. If the command fails, the Breadcrumb * attribute shall be left unchanged. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.4 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.4 */ setRegulatoryConfig(request: GeneralCommissioning.SetRegulatoryConfigRequest): MaybePromise; @@ -182,15 +180,19 @@ export namespace GeneralCommissioningInterface { * needed during the Fail-Safe period, such as commissioning (see Section 5.5, “Commissioning Flows”) or other * Administrator operations requiring usage of the Fail Safe timer. It ensures that the Server is configured in * a state such that it still has all necessary elements to be fully operable within a Fabric, such as ACL - * entries (see Access Control Cluster) and operational credentials (see Section 6.4, “Node Operational - * Credentials Specification”), and that the Node is reach + * entries (see Section 9.10, “Access Control Cluster”) and operational credentials (see Section 6.4, “Node + * Operational Credentials Specification”), and that the Node is reachable using CASE * - * able using CASE (see Section 4.14.2, “Certificate Authenticated Session Establishment (CASE)”) over an - * operational network. + * (CASE)”) over an operational network. * * An ErrorCode of NoFailSafe shall be responded to the invoker if the CommissioningComplete command was * received when no Fail-Safe context exists. * + * If Terms and Conditions are required, then an ErrorCode of TCAcknowledgementsNotReceived shall be responded + * to the invoker if the user acknowledgements to the required Terms and Conditions have not been provided. If + * the TCAcceptedVersion for the provided acknowledgements is less than TCMinRequiredVersion, then an ErrorCode + * of TCMinVersionNotMet shall be responded to the invoker. + * * This command is fabric-scoped, so cannot be issued over a session that does not have an associated fabric, * i.e. over PASE session prior to an AddNOC command. In addition, this command is only permitted over CASE and * must be issued by a node associated with the ongoing Fail-Safe context. An ErrorCode of @@ -217,7 +219,7 @@ export namespace GeneralCommissioningInterface { * 2. The commissioning window at the Server shall be closed. * * 3. Any temporary administrative privileges automatically granted to any open PASE session shall be revoked - * (see Section 6.6.2.8, “Bootstrapping of the Access Control Cluster”). + * (see Section 6.6.2.9, “Bootstrapping of the Access Control Cluster”). * * 4. The Secure Session Context of any PASE session still established at the Server shall be cleared. * @@ -226,10 +228,25 @@ export namespace GeneralCommissioningInterface { * After receipt of a CommissioningCompleteResponse with an ErrorCode value of OK, a client cannot expect any * previously established PASE session to still be usable, due to the server having cleared such sessions. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.6 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.6 */ commissioningComplete(): MaybePromise; } + + export interface TermsAndConditions { + /** + * This command sets the user acknowledgements received in the Enhanced Setup Flow Terms & Conditions into the + * node. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.8 + */ + setTcAcknowledgements(request: GeneralCommissioning.SetTcAcknowledgementsRequest): MaybePromise; + } } -export type GeneralCommissioningInterface = { components: [{ flags: {}, methods: GeneralCommissioningInterface.Base }] }; +export type GeneralCommissioningInterface = { + components: [ + { flags: {}, methods: GeneralCommissioningInterface.Base }, + { flags: { termsAndConditions: true }, methods: GeneralCommissioningInterface.TermsAndConditions } + ] +}; diff --git a/packages/node/src/behaviors/general-commissioning/index.ts b/packages/node/src/behaviors/general-commissioning/index.ts index 56ee228ef2..a86b2d724f 100644 --- a/packages/node/src/behaviors/general-commissioning/index.ts +++ b/packages/node/src/behaviors/general-commissioning/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsBehavior.ts b/packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsBehavior.ts index 2f06a7e23d..61687b5191 100644 --- a/packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsBehavior.ts +++ b/packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsInterface.ts b/packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsInterface.ts index 0b4ed203a1..bc957c279a 100644 --- a/packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsInterface.ts +++ b/packages/node/src/behaviors/general-diagnostics/GeneralDiagnosticsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -25,10 +25,9 @@ export namespace GeneralDiagnosticsInterface { /** * This command may be used by a client to obtain a correlated view of both System Time, and, if currently - * synchronized and supported, "wall clock time" of the server. This can help clients establish - * - * time correlation between their concept of time and the server’s concept of time. This is especially useful - * when processing event histories where some events only contain System Time. + * synchronized and supported, "wall clock time" of the server. This can help clients establish time + * correlation between their concept of time and the server’s concept of time. This is especially useful when + * processing event histories where some events only contain System Time. * * Upon command invocation, the server shall respond with a TimeSnapshotResponse. * diff --git a/packages/node/src/behaviors/general-diagnostics/index.ts b/packages/node/src/behaviors/general-diagnostics/index.ts index 2d9f9bef73..b66e16cf79 100644 --- a/packages/node/src/behaviors/general-diagnostics/index.ts +++ b/packages/node/src/behaviors/general-diagnostics/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/group-key-management/GroupKeyManagementBehavior.ts b/packages/node/src/behaviors/group-key-management/GroupKeyManagementBehavior.ts index b90027ff52..07070a0c68 100644 --- a/packages/node/src/behaviors/group-key-management/GroupKeyManagementBehavior.ts +++ b/packages/node/src/behaviors/group-key-management/GroupKeyManagementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/group-key-management/GroupKeyManagementInterface.ts b/packages/node/src/behaviors/group-key-management/GroupKeyManagementInterface.ts index 2f3951ae23..b4940e6399 100644 --- a/packages/node/src/behaviors/group-key-management/GroupKeyManagementInterface.ts +++ b/packages/node/src/behaviors/group-key-management/GroupKeyManagementInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -57,18 +57,18 @@ export namespace GroupKeyManagementInterface { * being null, then this command shall fail with an INVALID_COMMAND status code responded to the client. * * If there exists a Group Key Set associated with the accessing fabric which has the same GroupKeySetID as - * that provided in the GroupKeySet field, then the contents of that group key set shall be replaced. A - * replacement shall be done by executing the equivalent of entirely removing the previous Group Key Set with - * the given GroupKeySetID, followed by an addition of a Group Key Set with the provided configuration. - * Otherwise, if the GroupKeySetID did not match an existing entry, a new Group Key Set associated with the - * accessing fabric shall be created with the provided data. The Group Key Set shall be written to non-volatile - * storage. + * that provided in the GroupKeySet field, then the contents of that group key set shall be * - * Upon completion, this command shall send a status code back to the initiator: + * replaced. A replacement shall be done by executing the equivalent of entirely removing the previous Group + * Key Set with the given GroupKeySetID, followed by an addition of a Group Key Set with the provided + * configuration. Otherwise, if the GroupKeySetID did not match an existing entry, a new Group Key Set + * associated with the accessing fabric shall be created with the provided data. The Group Key Set shall be + * written to non-volatile storage. * - * • If the Group Key Set was properly installed or updated on the Node, the status code shall be + * Upon completion, this command shall send a status code back to the initiator: * - * set to SUCCESS. + * • If the Group Key Set was properly installed or updated on the Node, the status code shall be set to + * SUCCESS. * * • If there are insufficient resources on the receiver to store an additional Group Key Set, the status * code shall be set to RESOURCE_EXHAUSTED (see group key limits); @@ -100,9 +100,8 @@ export namespace GroupKeyManagementInterface { * * Effect on Receipt * - * If there exists a Group Key Set associated with the accessing fabric which has the same GroupKey - * - * SetID as that provided in the GroupKeySetID field, then the contents of that Group Key Set shall be removed, + * If there exists a Group Key Set associated with the accessing fabric which has the same GroupKeySetID as + * that provided in the GroupKeySetID field, then the contents of that Group Key Set shall be removed, * including all epoch keys it contains. * * If there exist any entries for the accessing fabric within the GroupKeyMap attribute that refer to the @@ -124,8 +123,6 @@ export namespace GroupKeyManagementInterface { * This command is used by Administrators to query a list of all Group Key Sets associated with the accessing * fabric. * - * NOTE Field 0 for this command is reserved and shall NOT be used. - * * Effect on Receipt * * Upon receipt, this command shall iterate all stored GroupKeySetStruct associated with the accessing fabric diff --git a/packages/node/src/behaviors/group-key-management/index.ts b/packages/node/src/behaviors/group-key-management/index.ts index 1f3e074fa3..dacb9eeb12 100644 --- a/packages/node/src/behaviors/group-key-management/index.ts +++ b/packages/node/src/behaviors/group-key-management/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/groups/GroupsBehavior.ts b/packages/node/src/behaviors/groups/GroupsBehavior.ts index f036e0d9ea..f6b251d0ce 100644 --- a/packages/node/src/behaviors/groups/GroupsBehavior.ts +++ b/packages/node/src/behaviors/groups/GroupsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/groups/GroupsInterface.ts b/packages/node/src/behaviors/groups/GroupsInterface.ts index 21c470f1df..3a0af8c540 100644 --- a/packages/node/src/behaviors/groups/GroupsInterface.ts +++ b/packages/node/src/behaviors/groups/GroupsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/groups/GroupsServer.ts b/packages/node/src/behaviors/groups/GroupsServer.ts index 38d49c145f..9e0ec39c66 100644 --- a/packages/node/src/behaviors/groups/GroupsServer.ts +++ b/packages/node/src/behaviors/groups/GroupsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/groups/index.ts b/packages/node/src/behaviors/groups/index.ts index 9452ce927a..b45dd2fc18 100644 --- a/packages/node/src/behaviors/groups/index.ts +++ b/packages/node/src/behaviors/groups/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/hepa-filter-monitoring/HepaFilterMonitoringBehavior.ts b/packages/node/src/behaviors/hepa-filter-monitoring/HepaFilterMonitoringBehavior.ts index 209f54afc6..ce9c75f75b 100644 --- a/packages/node/src/behaviors/hepa-filter-monitoring/HepaFilterMonitoringBehavior.ts +++ b/packages/node/src/behaviors/hepa-filter-monitoring/HepaFilterMonitoringBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/hepa-filter-monitoring/HepaFilterMonitoringServer.ts b/packages/node/src/behaviors/hepa-filter-monitoring/HepaFilterMonitoringServer.ts index 5bb9209d4b..0c9bf20187 100644 --- a/packages/node/src/behaviors/hepa-filter-monitoring/HepaFilterMonitoringServer.ts +++ b/packages/node/src/behaviors/hepa-filter-monitoring/HepaFilterMonitoringServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/hepa-filter-monitoring/index.ts b/packages/node/src/behaviors/hepa-filter-monitoring/index.ts index 3202026e55..ba3cdf2074 100644 --- a/packages/node/src/behaviors/hepa-filter-monitoring/index.ts +++ b/packages/node/src/behaviors/hepa-filter-monitoring/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/icd-management/IcdManagementBehavior.ts b/packages/node/src/behaviors/icd-management/IcdManagementBehavior.ts index be52b9f9ac..125af2fce5 100644 --- a/packages/node/src/behaviors/icd-management/IcdManagementBehavior.ts +++ b/packages/node/src/behaviors/icd-management/IcdManagementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/icd-management/IcdManagementInterface.ts b/packages/node/src/behaviors/icd-management/IcdManagementInterface.ts index d787c2221f..4b8a55c486 100644 --- a/packages/node/src/behaviors/icd-management/IcdManagementInterface.ts +++ b/packages/node/src/behaviors/icd-management/IcdManagementInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/icd-management/IcdManagementServer.ts b/packages/node/src/behaviors/icd-management/IcdManagementServer.ts index 3ed3940147..2f5f8d47fc 100644 --- a/packages/node/src/behaviors/icd-management/IcdManagementServer.ts +++ b/packages/node/src/behaviors/icd-management/IcdManagementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/icd-management/index.ts b/packages/node/src/behaviors/icd-management/index.ts index fe925be58d..cb9935793f 100644 --- a/packages/node/src/behaviors/icd-management/index.ts +++ b/packages/node/src/behaviors/icd-management/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/identify/IdentifyBehavior.ts b/packages/node/src/behaviors/identify/IdentifyBehavior.ts index 43b902e17e..62ed2a76e5 100644 --- a/packages/node/src/behaviors/identify/IdentifyBehavior.ts +++ b/packages/node/src/behaviors/identify/IdentifyBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/identify/IdentifyInterface.ts b/packages/node/src/behaviors/identify/IdentifyInterface.ts index 4706e923b7..e06692e35a 100644 --- a/packages/node/src/behaviors/identify/IdentifyInterface.ts +++ b/packages/node/src/behaviors/identify/IdentifyInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/identify/index.ts b/packages/node/src/behaviors/identify/index.ts index b864aca3eb..e25a6873ff 100644 --- a/packages/node/src/behaviors/identify/index.ts +++ b/packages/node/src/behaviors/identify/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/illuminance-measurement/IlluminanceMeasurementBehavior.ts b/packages/node/src/behaviors/illuminance-measurement/IlluminanceMeasurementBehavior.ts index a3046f62f7..6a0d37de52 100644 --- a/packages/node/src/behaviors/illuminance-measurement/IlluminanceMeasurementBehavior.ts +++ b/packages/node/src/behaviors/illuminance-measurement/IlluminanceMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/illuminance-measurement/IlluminanceMeasurementServer.ts b/packages/node/src/behaviors/illuminance-measurement/IlluminanceMeasurementServer.ts index d4deac70a3..3aee2d0f32 100644 --- a/packages/node/src/behaviors/illuminance-measurement/IlluminanceMeasurementServer.ts +++ b/packages/node/src/behaviors/illuminance-measurement/IlluminanceMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/illuminance-measurement/index.ts b/packages/node/src/behaviors/illuminance-measurement/index.ts index c1a2a2c59c..a17277a59b 100644 --- a/packages/node/src/behaviors/illuminance-measurement/index.ts +++ b/packages/node/src/behaviors/illuminance-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/index.ts b/packages/node/src/behaviors/index.ts index a83c1e746f..f51bd5e892 100644 --- a/packages/node/src/behaviors/index.ts +++ b/packages/node/src/behaviors/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -26,6 +26,7 @@ export * from "./carbon-dioxide-concentration-measurement/index.js"; export * from "./carbon-monoxide-concentration-measurement/index.js"; export * from "./channel/index.js"; export * from "./color-control/index.js"; +export * from "./commissioner-control/index.js"; export * from "./concentration-measurement/index.js"; export * from "./content-app-observer/index.js"; export * from "./content-control/index.js"; @@ -37,6 +38,7 @@ export * from "./diagnostic-logs/index.js"; export * from "./dishwasher-alarm/index.js"; export * from "./dishwasher-mode/index.js"; export * from "./door-lock/index.js"; +export * from "./ecosystem-information/index.js"; export * from "./electrical-energy-measurement/index.js"; export * from "./electrical-power-measurement/index.js"; export * from "./energy-evse-mode/index.js"; @@ -55,6 +57,8 @@ export * from "./hepa-filter-monitoring/index.js"; export * from "./icd-management/index.js"; export * from "./identify/index.js"; export * from "./illuminance-measurement/index.js"; +export * from "./joint-fabric-datastore-cluster/index.js"; +export * from "./joint-fabric-pki/index.js"; export * from "./keypad-input/index.js"; export * from "./label/index.js"; export * from "./laundry-dryer-controls/index.js"; @@ -90,7 +94,6 @@ export * from "./power-topology/index.js"; export * from "./pressure-measurement/index.js"; export * from "./proxy-configuration/index.js"; export * from "./proxy-discovery/index.js"; -export * from "./pulse-width-modulation/index.js"; export * from "./pump-configuration-and-control/index.js"; export * from "./radon-concentration-measurement/index.js"; export * from "./refrigerator-alarm/index.js"; @@ -101,6 +104,7 @@ export * from "./rvc-clean-mode/index.js"; export * from "./rvc-operational-state/index.js"; export * from "./rvc-run-mode/index.js"; export * from "./scenes-management/index.js"; +export * from "./service-area/index.js"; export * from "./smoke-co-alarm/index.js"; export * from "./software-diagnostics/index.js"; export * from "./switch/index.js"; @@ -109,7 +113,9 @@ export * from "./temperature-control/index.js"; export * from "./temperature-measurement/index.js"; export * from "./thermostat-user-interface-configuration/index.js"; export * from "./thermostat/index.js"; +export * from "./thread-border-router-management/index.js"; export * from "./thread-network-diagnostics/index.js"; +export * from "./thread-network-directory/index.js"; export * from "./time-format-localization/index.js"; export * from "./time-synchronization/index.js"; export * from "./total-volatile-organic-compounds-concentration-measurement/index.js"; @@ -118,5 +124,9 @@ export * from "./user-label/index.js"; export * from "./valid-proxies/index.js"; export * from "./valve-configuration-and-control/index.js"; export * from "./wake-on-lan/index.js"; +export * from "./water-heater-management/index.js"; +export * from "./water-heater-mode/index.js"; +export * from "./water-tank-level-monitoring/index.js"; export * from "./wi-fi-network-diagnostics/index.js"; +export * from "./wi-fi-network-management/index.js"; export * from "./window-covering/index.js"; diff --git a/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterBehavior.ts b/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterBehavior.ts new file mode 100644 index 0000000000..ca38560eb6 --- /dev/null +++ b/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterBehavior.ts @@ -0,0 +1,24 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { JointFabricDatastoreCluster } from "#clusters/joint-fabric-datastore-cluster"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { JointFabricDatastoreClusterInterface } from "./JointFabricDatastoreClusterInterface.js"; + +/** + * JointFabricDatastoreClusterBehavior is the base class for objects that support interaction with {@link + * JointFabricDatastoreCluster.Cluster}. + */ +export const JointFabricDatastoreClusterBehavior = ClusterBehavior + .withInterface() + .for(JointFabricDatastoreCluster.Cluster); + +type JointFabricDatastoreClusterBehaviorType = InstanceType; +export interface JointFabricDatastoreClusterBehavior extends JointFabricDatastoreClusterBehaviorType {} +type StateType = InstanceType; +export namespace JointFabricDatastoreClusterBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterInterface.ts b/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterInterface.ts new file mode 100644 index 0000000000..7ef7b0ff82 --- /dev/null +++ b/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterInterface.ts @@ -0,0 +1,117 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; + +export namespace JointFabricDatastoreClusterInterface { + export interface Base { + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112471(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112472(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112473(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112474(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112475(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112476(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112477(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112478(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112479(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124710(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124711(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124712(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124713(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124714(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124715(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124716(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124717(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124718(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124719(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124720(): MaybePromise; + } +} + +export type JointFabricDatastoreClusterInterface = { + components: [{ flags: {}, methods: JointFabricDatastoreClusterInterface.Base }] +}; diff --git a/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterServer.ts b/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterServer.ts new file mode 100644 index 0000000000..76085c0eca --- /dev/null +++ b/packages/node/src/behaviors/joint-fabric-datastore-cluster/JointFabricDatastoreClusterServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { JointFabricDatastoreClusterBehavior } from "./JointFabricDatastoreClusterBehavior.js"; + +/** + * This is the default server implementation of {@link JointFabricDatastoreClusterBehavior}. + */ +export class JointFabricDatastoreClusterServer extends JointFabricDatastoreClusterBehavior {} diff --git a/packages/node/src/behaviors/joint-fabric-datastore-cluster/index.ts b/packages/node/src/behaviors/joint-fabric-datastore-cluster/index.ts new file mode 100644 index 0000000000..7ced1047c1 --- /dev/null +++ b/packages/node/src/behaviors/joint-fabric-datastore-cluster/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./JointFabricDatastoreClusterInterface.js"; +export * from "./JointFabricDatastoreClusterBehavior.js"; +export * from "./JointFabricDatastoreClusterServer.js"; diff --git a/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiBehavior.ts b/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiBehavior.ts new file mode 100644 index 0000000000..7fe7a2fb34 --- /dev/null +++ b/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiBehavior.ts @@ -0,0 +1,23 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { JointFabricPki } from "#clusters/joint-fabric-pki"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { JointFabricPkiInterface } from "./JointFabricPkiInterface.js"; + +/** + * JointFabricPkiBehavior is the base class for objects that support interaction with {@link JointFabricPki.Cluster}. + */ +export const JointFabricPkiBehavior = ClusterBehavior + .withInterface() + .for(JointFabricPki.Cluster); + +type JointFabricPkiBehaviorType = InstanceType; +export interface JointFabricPkiBehavior extends JointFabricPkiBehaviorType {} +type StateType = InstanceType; +export namespace JointFabricPkiBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiInterface.ts b/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiInterface.ts new file mode 100644 index 0000000000..a9245f1311 --- /dev/null +++ b/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiInterface.ts @@ -0,0 +1,36 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; +import { JointFabricPki } from "#clusters/joint-fabric-pki"; + +export namespace JointFabricPkiInterface { + export interface Base { + /** + * This command shall be generated and executed during the Joint Commissioning Method steps and subsequently + * respond in the form of an ICACSRResponse command. + * + * Check ICA Cross Signing for details about the generation and contents of the ICACSR. + * + * @see {@link MatterSpecification.v13.Core} § 11.25.5.1 + */ + icacsrRequest(request: JointFabricPki.IcacsrRequest): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.25.5 + */ + transferAnchorRequest(): MaybePromise; + + /** + * @see {@link MatterSpecification.v13.Core} § 11.25.5 + */ + transferAnchorComplete(): MaybePromise; + } +} + +export type JointFabricPkiInterface = { components: [{ flags: {}, methods: JointFabricPkiInterface.Base }] }; diff --git a/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiServer.ts b/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiServer.ts new file mode 100644 index 0000000000..d3a0f99902 --- /dev/null +++ b/packages/node/src/behaviors/joint-fabric-pki/JointFabricPkiServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { JointFabricPkiBehavior } from "./JointFabricPkiBehavior.js"; + +/** + * This is the default server implementation of {@link JointFabricPkiBehavior}. + */ +export class JointFabricPkiServer extends JointFabricPkiBehavior {} diff --git a/packages/node/src/behaviors/joint-fabric-pki/index.ts b/packages/node/src/behaviors/joint-fabric-pki/index.ts new file mode 100644 index 0000000000..ddc3a3d970 --- /dev/null +++ b/packages/node/src/behaviors/joint-fabric-pki/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./JointFabricPkiInterface.js"; +export * from "./JointFabricPkiBehavior.js"; +export * from "./JointFabricPkiServer.js"; diff --git a/packages/node/src/behaviors/keypad-input/KeypadInputBehavior.ts b/packages/node/src/behaviors/keypad-input/KeypadInputBehavior.ts index cb424b0dd5..9f85710125 100644 --- a/packages/node/src/behaviors/keypad-input/KeypadInputBehavior.ts +++ b/packages/node/src/behaviors/keypad-input/KeypadInputBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/keypad-input/KeypadInputInterface.ts b/packages/node/src/behaviors/keypad-input/KeypadInputInterface.ts index 0193da9534..a032c7d560 100644 --- a/packages/node/src/behaviors/keypad-input/KeypadInputInterface.ts +++ b/packages/node/src/behaviors/keypad-input/KeypadInputInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/keypad-input/KeypadInputServer.ts b/packages/node/src/behaviors/keypad-input/KeypadInputServer.ts index 652f9085e8..121bbbcac3 100644 --- a/packages/node/src/behaviors/keypad-input/KeypadInputServer.ts +++ b/packages/node/src/behaviors/keypad-input/KeypadInputServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/keypad-input/index.ts b/packages/node/src/behaviors/keypad-input/index.ts index dead2583e0..f23e696019 100644 --- a/packages/node/src/behaviors/keypad-input/index.ts +++ b/packages/node/src/behaviors/keypad-input/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/label/index.ts b/packages/node/src/behaviors/label/index.ts index f9d791ac10..87e7d08960 100644 --- a/packages/node/src/behaviors/label/index.ts +++ b/packages/node/src/behaviors/label/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/laundry-dryer-controls/LaundryDryerControlsBehavior.ts b/packages/node/src/behaviors/laundry-dryer-controls/LaundryDryerControlsBehavior.ts index 640e242107..dd2188e0e5 100644 --- a/packages/node/src/behaviors/laundry-dryer-controls/LaundryDryerControlsBehavior.ts +++ b/packages/node/src/behaviors/laundry-dryer-controls/LaundryDryerControlsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/laundry-dryer-controls/LaundryDryerControlsServer.ts b/packages/node/src/behaviors/laundry-dryer-controls/LaundryDryerControlsServer.ts index b848481f94..f21513ec4c 100644 --- a/packages/node/src/behaviors/laundry-dryer-controls/LaundryDryerControlsServer.ts +++ b/packages/node/src/behaviors/laundry-dryer-controls/LaundryDryerControlsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/laundry-dryer-controls/index.ts b/packages/node/src/behaviors/laundry-dryer-controls/index.ts index 6660a19636..b72d5af0b9 100644 --- a/packages/node/src/behaviors/laundry-dryer-controls/index.ts +++ b/packages/node/src/behaviors/laundry-dryer-controls/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/laundry-washer-controls/LaundryWasherControlsBehavior.ts b/packages/node/src/behaviors/laundry-washer-controls/LaundryWasherControlsBehavior.ts index 2535c24392..7cda1d4968 100644 --- a/packages/node/src/behaviors/laundry-washer-controls/LaundryWasherControlsBehavior.ts +++ b/packages/node/src/behaviors/laundry-washer-controls/LaundryWasherControlsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,15 +8,16 @@ import { LaundryWasherControls } from "#clusters/laundry-washer-controls"; import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { ClusterType } from "#types"; /** * LaundryWasherControlsBehavior is the base class for objects that support interaction with {@link * LaundryWasherControls.Cluster}. * - * This class does not have optional features of LaundryWasherControls.Cluster enabled. You can enable additional - * features using LaundryWasherControlsBehavior.with. + * LaundryWasherControls.Cluster requires you to enable one or more optional features. You can do so using {@link + * LaundryWasherControlsBehavior.with}. */ -export const LaundryWasherControlsBehavior = ClusterBehavior.for(LaundryWasherControls.Cluster); +export const LaundryWasherControlsBehavior = ClusterBehavior.for(ClusterType(LaundryWasherControls.Base)); type LaundryWasherControlsBehaviorType = InstanceType; export interface LaundryWasherControlsBehavior extends LaundryWasherControlsBehaviorType {} diff --git a/packages/node/src/behaviors/laundry-washer-controls/LaundryWasherControlsServer.ts b/packages/node/src/behaviors/laundry-washer-controls/LaundryWasherControlsServer.ts index 715fe4d1c6..f6bef57f90 100644 --- a/packages/node/src/behaviors/laundry-washer-controls/LaundryWasherControlsServer.ts +++ b/packages/node/src/behaviors/laundry-washer-controls/LaundryWasherControlsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,5 +10,9 @@ import { LaundryWasherControlsBehavior } from "./LaundryWasherControlsBehavior.j /** * This is the default server implementation of {@link LaundryWasherControlsBehavior}. + * + * The Matter specification requires the LaundryWasherControls cluster to support features we do not enable by default. + * You should use {@link LaundryWasherControlsServer.with} to specialize the class for the features your implementation + * supports. */ export class LaundryWasherControlsServer extends LaundryWasherControlsBehavior {} diff --git a/packages/node/src/behaviors/laundry-washer-controls/index.ts b/packages/node/src/behaviors/laundry-washer-controls/index.ts index 353e6480ee..7680b4d6d5 100644 --- a/packages/node/src/behaviors/laundry-washer-controls/index.ts +++ b/packages/node/src/behaviors/laundry-washer-controls/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/laundry-washer-mode/LaundryWasherModeBehavior.ts b/packages/node/src/behaviors/laundry-washer-mode/LaundryWasherModeBehavior.ts index 0d33ade3ed..20a3121d63 100644 --- a/packages/node/src/behaviors/laundry-washer-mode/LaundryWasherModeBehavior.ts +++ b/packages/node/src/behaviors/laundry-washer-mode/LaundryWasherModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/laundry-washer-mode/LaundryWasherModeServer.ts b/packages/node/src/behaviors/laundry-washer-mode/LaundryWasherModeServer.ts index 2b8f083334..85ddd04705 100644 --- a/packages/node/src/behaviors/laundry-washer-mode/LaundryWasherModeServer.ts +++ b/packages/node/src/behaviors/laundry-washer-mode/LaundryWasherModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/laundry-washer-mode/index.ts b/packages/node/src/behaviors/laundry-washer-mode/index.ts index 79a3036c1b..9741511fef 100644 --- a/packages/node/src/behaviors/laundry-washer-mode/index.ts +++ b/packages/node/src/behaviors/laundry-washer-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/level-control/LevelControlBehavior.ts b/packages/node/src/behaviors/level-control/LevelControlBehavior.ts index df6575d03a..cb72c410be 100644 --- a/packages/node/src/behaviors/level-control/LevelControlBehavior.ts +++ b/packages/node/src/behaviors/level-control/LevelControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/level-control/LevelControlInterface.ts b/packages/node/src/behaviors/level-control/LevelControlInterface.ts index fd24b792a2..d58d3bc3c6 100644 --- a/packages/node/src/behaviors/level-control/LevelControlInterface.ts +++ b/packages/node/src/behaviors/level-control/LevelControlInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/level-control/index.ts b/packages/node/src/behaviors/level-control/index.ts index 33b5de1274..ce705b7e06 100644 --- a/packages/node/src/behaviors/level-control/index.ts +++ b/packages/node/src/behaviors/level-control/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/localization-configuration/LocalizationConfigurationBehavior.ts b/packages/node/src/behaviors/localization-configuration/LocalizationConfigurationBehavior.ts index 75be1f2032..5edbde9b2e 100644 --- a/packages/node/src/behaviors/localization-configuration/LocalizationConfigurationBehavior.ts +++ b/packages/node/src/behaviors/localization-configuration/LocalizationConfigurationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/localization-configuration/index.ts b/packages/node/src/behaviors/localization-configuration/index.ts index 0d4835265c..314d09a113 100644 --- a/packages/node/src/behaviors/localization-configuration/index.ts +++ b/packages/node/src/behaviors/localization-configuration/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/low-power/LowPowerBehavior.ts b/packages/node/src/behaviors/low-power/LowPowerBehavior.ts index fb4b0d730b..956e82f263 100644 --- a/packages/node/src/behaviors/low-power/LowPowerBehavior.ts +++ b/packages/node/src/behaviors/low-power/LowPowerBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/low-power/LowPowerInterface.ts b/packages/node/src/behaviors/low-power/LowPowerInterface.ts index 4582ec4c10..87f429ad2c 100644 --- a/packages/node/src/behaviors/low-power/LowPowerInterface.ts +++ b/packages/node/src/behaviors/low-power/LowPowerInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/low-power/index.ts b/packages/node/src/behaviors/low-power/index.ts index a9a3ae8cd9..54a5140d4e 100644 --- a/packages/node/src/behaviors/low-power/index.ts +++ b/packages/node/src/behaviors/low-power/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/media-input/MediaInputBehavior.ts b/packages/node/src/behaviors/media-input/MediaInputBehavior.ts index f69260a4e7..0136de6d00 100644 --- a/packages/node/src/behaviors/media-input/MediaInputBehavior.ts +++ b/packages/node/src/behaviors/media-input/MediaInputBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/media-input/MediaInputInterface.ts b/packages/node/src/behaviors/media-input/MediaInputInterface.ts index 2e6bd72c13..3d0866ce10 100644 --- a/packages/node/src/behaviors/media-input/MediaInputInterface.ts +++ b/packages/node/src/behaviors/media-input/MediaInputInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,8 +12,9 @@ import { MediaInput } from "#clusters/media-input"; export namespace MediaInputInterface { export interface Base { /** - * Upon receipt, this command shall change the media input on the device to the input at a specific index in - * the Input List. + * Upon receipt, this command shall change the media input on the device to the input at a specific + * + * index in the Input List. * * @see {@link MatterSpecification.v13.Cluster} § 6.9.7.1 */ diff --git a/packages/node/src/behaviors/media-input/MediaInputServer.ts b/packages/node/src/behaviors/media-input/MediaInputServer.ts index 6fa95ca1c2..cd05eb9b75 100644 --- a/packages/node/src/behaviors/media-input/MediaInputServer.ts +++ b/packages/node/src/behaviors/media-input/MediaInputServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/media-input/index.ts b/packages/node/src/behaviors/media-input/index.ts index f9ba39b317..eb5fbac869 100644 --- a/packages/node/src/behaviors/media-input/index.ts +++ b/packages/node/src/behaviors/media-input/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/media-playback/MediaPlaybackBehavior.ts b/packages/node/src/behaviors/media-playback/MediaPlaybackBehavior.ts index ddeaa81e43..8bf04481e9 100644 --- a/packages/node/src/behaviors/media-playback/MediaPlaybackBehavior.ts +++ b/packages/node/src/behaviors/media-playback/MediaPlaybackBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/media-playback/MediaPlaybackInterface.ts b/packages/node/src/behaviors/media-playback/MediaPlaybackInterface.ts index c361b52ad1..2273b0ebcb 100644 --- a/packages/node/src/behaviors/media-playback/MediaPlaybackInterface.ts +++ b/packages/node/src/behaviors/media-playback/MediaPlaybackInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/media-playback/MediaPlaybackServer.ts b/packages/node/src/behaviors/media-playback/MediaPlaybackServer.ts index 535026b103..d25d7ab232 100644 --- a/packages/node/src/behaviors/media-playback/MediaPlaybackServer.ts +++ b/packages/node/src/behaviors/media-playback/MediaPlaybackServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/media-playback/index.ts b/packages/node/src/behaviors/media-playback/index.ts index 2c9e002c34..0bef0500bc 100644 --- a/packages/node/src/behaviors/media-playback/index.ts +++ b/packages/node/src/behaviors/media-playback/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/messages/MessagesBehavior.ts b/packages/node/src/behaviors/messages/MessagesBehavior.ts index 8571be8132..8ea5fa2ef1 100644 --- a/packages/node/src/behaviors/messages/MessagesBehavior.ts +++ b/packages/node/src/behaviors/messages/MessagesBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/messages/MessagesInterface.ts b/packages/node/src/behaviors/messages/MessagesInterface.ts index 8ce4873976..042b5d9c3f 100644 --- a/packages/node/src/behaviors/messages/MessagesInterface.ts +++ b/packages/node/src/behaviors/messages/MessagesInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/messages/MessagesServer.ts b/packages/node/src/behaviors/messages/MessagesServer.ts index 779179a5bc..e8e8248624 100644 --- a/packages/node/src/behaviors/messages/MessagesServer.ts +++ b/packages/node/src/behaviors/messages/MessagesServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/messages/index.ts b/packages/node/src/behaviors/messages/index.ts index 8f192b9b05..2d69a47e78 100644 --- a/packages/node/src/behaviors/messages/index.ts +++ b/packages/node/src/behaviors/messages/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlBehavior.ts b/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlBehavior.ts index 76631e4ea8..3c3a5efa50 100644 --- a/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlBehavior.ts +++ b/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlInterface.ts b/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlInterface.ts index 82abb30996..6fc7cbedaa 100644 --- a/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlInterface.ts +++ b/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,9 +12,8 @@ import { MicrowaveOvenControl } from "#clusters/microwave-oven-control"; export namespace MicrowaveOvenControlInterface { export interface Base { /** - * This command is used to set the cooking parameters associated with the operation of the device. - * - * This command supports the following fields: + * This command is used to set the cooking parameters associated with the operation of the device. This command + * supports the following fields: * * @see {@link MatterSpecification.v13.Cluster} § 8.13.6.2 */ diff --git a/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlServer.ts b/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlServer.ts index ca9fb411b9..7ea8cf7ccb 100644 --- a/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlServer.ts +++ b/packages/node/src/behaviors/microwave-oven-control/MicrowaveOvenControlServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/microwave-oven-control/index.ts b/packages/node/src/behaviors/microwave-oven-control/index.ts index 2be9725402..0e79caf140 100644 --- a/packages/node/src/behaviors/microwave-oven-control/index.ts +++ b/packages/node/src/behaviors/microwave-oven-control/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeBehavior.ts b/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeBehavior.ts index a688133d4a..3d1d9a593e 100644 --- a/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeBehavior.ts +++ b/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeInterface.ts b/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeInterface.ts index c1215c3718..3a5b60c113 100644 --- a/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeInterface.ts +++ b/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeServer.ts b/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeServer.ts index febc9b0bb4..217e12a401 100644 --- a/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeServer.ts +++ b/packages/node/src/behaviors/microwave-oven-mode/MicrowaveOvenModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/microwave-oven-mode/index.ts b/packages/node/src/behaviors/microwave-oven-mode/index.ts index d53c57f92e..0392806415 100644 --- a/packages/node/src/behaviors/microwave-oven-mode/index.ts +++ b/packages/node/src/behaviors/microwave-oven-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/mode-base/ModeBaseInterface.ts b/packages/node/src/behaviors/mode-base/ModeBaseInterface.ts index 0ecb0fab51..844725d841 100644 --- a/packages/node/src/behaviors/mode-base/ModeBaseInterface.ts +++ b/packages/node/src/behaviors/mode-base/ModeBaseInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/mode-base/index.ts b/packages/node/src/behaviors/mode-base/index.ts index 130ecc2901..4b84e62b1a 100644 --- a/packages/node/src/behaviors/mode-base/index.ts +++ b/packages/node/src/behaviors/mode-base/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/mode-select/ModeSelectBehavior.ts b/packages/node/src/behaviors/mode-select/ModeSelectBehavior.ts index b230e80324..74ebddbd88 100644 --- a/packages/node/src/behaviors/mode-select/ModeSelectBehavior.ts +++ b/packages/node/src/behaviors/mode-select/ModeSelectBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/mode-select/ModeSelectInterface.ts b/packages/node/src/behaviors/mode-select/ModeSelectInterface.ts index ff25577abc..1ab21d73ad 100644 --- a/packages/node/src/behaviors/mode-select/ModeSelectInterface.ts +++ b/packages/node/src/behaviors/mode-select/ModeSelectInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/mode-select/index.ts b/packages/node/src/behaviors/mode-select/index.ts index ade6f3d7f4..677a18f591 100644 --- a/packages/node/src/behaviors/mode-select/index.ts +++ b/packages/node/src/behaviors/mode-select/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/network-commissioning/NetworkCommissioningBehavior.ts b/packages/node/src/behaviors/network-commissioning/NetworkCommissioningBehavior.ts index 79be95d9e1..d2157f0f37 100644 --- a/packages/node/src/behaviors/network-commissioning/NetworkCommissioningBehavior.ts +++ b/packages/node/src/behaviors/network-commissioning/NetworkCommissioningBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/network-commissioning/NetworkCommissioningInterface.ts b/packages/node/src/behaviors/network-commissioning/NetworkCommissioningInterface.ts index 65ef1adad4..8d72eb98d5 100644 --- a/packages/node/src/behaviors/network-commissioning/NetworkCommissioningInterface.ts +++ b/packages/node/src/behaviors/network-commissioning/NetworkCommissioningInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -27,8 +27,8 @@ export namespace NetworkCommissioningInterface { * SSID) is provided in the command arguments. Directed scanning shall restrict the result set to the specified * network only. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * The client shall NOT expect the server to be done scanning and have responded with ScanNetworksResponse * before ScanMaxTimeSeconds seconds have elapsed. Enough transport time affordances for retries SHOULD be @@ -43,9 +43,8 @@ export namespace NetworkCommissioningInterface { * ConnectNetwork having the specified SSID were to take place. This command is useful for clients to determine * reachability capabilities as seen by the server’s own radios. * - * For Wi-Fi-supporting servers the server shall always scan on all bands supported by the interface - * - * associated with the cluster instance on which the command was invoked. + * For Wi-Fi-supporting servers the server shall always scan on all bands supported by the interface associated + * with the cluster instance on which the command was invoked. * * If the command was invoked over the same link whose configuration is managed by a given server cluster * instance, there may be an impact on other communication from the invoking client, as well as other clients, @@ -62,8 +61,8 @@ export namespace NetworkCommissioningInterface { * * attribute shall remain unchanged, except for the removal of the requested network configuration. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If the Networks attribute does not contain a matching entry, the command shall immediately respond with * NetworkConfigResponse having NetworkingStatus status field set to NetworkIdNotFound. @@ -84,8 +83,16 @@ export namespace NetworkCommissioningInterface { * to proceed with such an operation, such as if it is currently attempting to connect in the background, or is * already proceeding with a prior ConnectNetwork. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * + * Before connecting to the new network, the Node shall disconnect the operational network connections managed + * by any other Network Commissioning cluster instances (whether under the Root Node or a Secondary Network + * Interface), where those connections are not represented by an entry in the Networks attribute of the + * corresponding cluster instance. This ensures that an Administrator or Commissioner can reliably reconfigure + * the operational network connection of a device that has one or more Secondary Network interfaces, for + * example by removing the active network configuration from one cluster instance, followed by adding a new + * configuration and calling ConnectNetwork on a different cluster instance. * * Success or failure of this command shall be communicated by the ConnectNetworkResponse command, unless some * data model validations caused a FAILURE status to be sent prior to finishing execution of the command. The @@ -109,11 +116,12 @@ export namespace NetworkCommissioningInterface { * The precedence order of any entry subject to ConnectNetwork shall NOT change within the Networks attribute. * * Even after successfully connecting to a network, the configuration shall revert to the prior state of - * configuration if the CommissioningComplete command (see Section 11.10.6.6, “CommissioningComplete Command”) - * is not successfully invoked before expiry of the Fail-Safe timer. + * configuration if the CommissioningComplete command (see CommissioningComplete) is not successfully invoked + * before expiry of the Fail-Safe timer. + * + * When non-concurrent commissioning is being used by a Commissioner or Administrator, the Con * - * When non-concurrent commissioning is being used by a Commissioner or Administrator, the - * ConnectNetworkResponse shall be sent with the NetworkingStatus field set to Success prior to closing the + * nectNetworkResponse shall be sent with the NetworkingStatus field set to Success prior to closing the * commissioning channel, even if not yet connected to the operational network, unless the device would be * incapable of joining that network, in which case the usual failure path described in the prior paragraphs * shall be followed. Once the commissioning channel is closed, the operational channel will be started. It is @@ -121,8 +129,8 @@ export namespace NetworkCommissioningInterface { * the new operational network. Therefore, before invoking the ConnectNetwork command, the client SHOULD * re-invoke the Arm Fail-Safe command with a duration that meets the following: * - * 1. Sufficient time to meet the minimum required time (see Section 11.9.6.4, “ConnectMaxTimeSeconds - * Attribute”) that may be taken by the server to connect to the desired network. + * 1. Sufficient time to meet the minimum required time (see ConnectMaxTimeSeconds) that may be taken by the + * server to connect to the desired network. * * 2. Sufficient time to account for possible message-layer retries when a response is requested. * @@ -158,8 +166,8 @@ export namespace NetworkCommissioningInterface { /** * This command shall be used to add or modify Wi-Fi network configurations. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * The Credentials associated with the network are not readable after execution of this command, as they do not * appear in the Networks attribute, for security reasons. @@ -179,8 +187,8 @@ export namespace NetworkCommissioningInterface { /** * This command shall be used to add or modify Thread network configurations. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * See Section 11.9.7.5, “Common processing of AddOrUpdateWiFiNetwork and AddOrUpdateThreadNetwork” for * behavior of addition/update. diff --git a/packages/node/src/behaviors/network-commissioning/NetworkCommissioningServer.ts b/packages/node/src/behaviors/network-commissioning/NetworkCommissioningServer.ts index 9d1b0a2209..f5dcd56f7f 100644 --- a/packages/node/src/behaviors/network-commissioning/NetworkCommissioningServer.ts +++ b/packages/node/src/behaviors/network-commissioning/NetworkCommissioningServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/network-commissioning/index.ts b/packages/node/src/behaviors/network-commissioning/index.ts index 73149504ce..2d8aca67a3 100644 --- a/packages/node/src/behaviors/network-commissioning/index.ts +++ b/packages/node/src/behaviors/network-commissioning/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/NitrogenDioxideConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/NitrogenDioxideConcentrationMeasurementBehavior.ts index 9a414ba300..7ad67eaf99 100644 --- a/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/NitrogenDioxideConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/NitrogenDioxideConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/NitrogenDioxideConcentrationMeasurementServer.ts b/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/NitrogenDioxideConcentrationMeasurementServer.ts index 70396d8bf8..ebf43b888e 100644 --- a/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/NitrogenDioxideConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/NitrogenDioxideConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/index.ts b/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/index.ts index 677f50c11c..17ef301986 100644 --- a/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/nitrogen-dioxide-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/occupancy-sensing/OccupancySensingBehavior.ts b/packages/node/src/behaviors/occupancy-sensing/OccupancySensingBehavior.ts index 6e2d30b462..483bc6ba07 100644 --- a/packages/node/src/behaviors/occupancy-sensing/OccupancySensingBehavior.ts +++ b/packages/node/src/behaviors/occupancy-sensing/OccupancySensingBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,12 +8,16 @@ import { OccupancySensing } from "#clusters/occupancy-sensing"; import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { ClusterType } from "#types"; /** * OccupancySensingBehavior is the base class for objects that support interaction with {@link * OccupancySensing.Cluster}. + * + * OccupancySensing.Cluster requires you to enable one or more optional features. You can do so using {@link + * OccupancySensingBehavior.with}. */ -export const OccupancySensingBehavior = ClusterBehavior.for(OccupancySensing.Cluster); +export const OccupancySensingBehavior = ClusterBehavior.for(ClusterType(OccupancySensing.Base)); type OccupancySensingBehaviorType = InstanceType; export interface OccupancySensingBehavior extends OccupancySensingBehaviorType {} diff --git a/packages/node/src/behaviors/occupancy-sensing/OccupancySensingServer.ts b/packages/node/src/behaviors/occupancy-sensing/OccupancySensingServer.ts index 611acba10b..94270241db 100644 --- a/packages/node/src/behaviors/occupancy-sensing/OccupancySensingServer.ts +++ b/packages/node/src/behaviors/occupancy-sensing/OccupancySensingServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,5 +10,8 @@ import { OccupancySensingBehavior } from "./OccupancySensingBehavior.js"; /** * This is the default server implementation of {@link OccupancySensingBehavior}. + * + * The Matter specification requires the OccupancySensing cluster to support features we do not enable by default. You + * should use {@link OccupancySensingServer.with} to specialize the class for the features your implementation supports. */ export class OccupancySensingServer extends OccupancySensingBehavior {} diff --git a/packages/node/src/behaviors/occupancy-sensing/index.ts b/packages/node/src/behaviors/occupancy-sensing/index.ts index c4935b3beb..dd1aa06c43 100644 --- a/packages/node/src/behaviors/occupancy-sensing/index.ts +++ b/packages/node/src/behaviors/occupancy-sensing/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/on-off/OnOffBehavior.ts b/packages/node/src/behaviors/on-off/OnOffBehavior.ts index 1d7b8c939b..c3b2ae303b 100644 --- a/packages/node/src/behaviors/on-off/OnOffBehavior.ts +++ b/packages/node/src/behaviors/on-off/OnOffBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/on-off/OnOffInterface.ts b/packages/node/src/behaviors/on-off/OnOffInterface.ts index 079ce0b427..3fb7aa9d2d 100644 --- a/packages/node/src/behaviors/on-off/OnOffInterface.ts +++ b/packages/node/src/behaviors/on-off/OnOffInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/on-off/index.ts b/packages/node/src/behaviors/on-off/index.ts index dee1878dc1..786a356225 100644 --- a/packages/node/src/behaviors/on-off/index.ts +++ b/packages/node/src/behaviors/on-off/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/operational-credentials/OperationalCredentialsBehavior.ts b/packages/node/src/behaviors/operational-credentials/OperationalCredentialsBehavior.ts index 42e079dab3..7edeee672b 100644 --- a/packages/node/src/behaviors/operational-credentials/OperationalCredentialsBehavior.ts +++ b/packages/node/src/behaviors/operational-credentials/OperationalCredentialsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/operational-credentials/OperationalCredentialsInterface.ts b/packages/node/src/behaviors/operational-credentials/OperationalCredentialsInterface.ts index 98f67fb193..f463734264 100644 --- a/packages/node/src/behaviors/operational-credentials/OperationalCredentialsInterface.ts +++ b/packages/node/src/behaviors/operational-credentials/OperationalCredentialsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -44,8 +44,8 @@ export namespace OperationalCredentialsInterface { * shall be tagged as being for a subsequent UpdateNOC, otherwise the internal state of the CSR shall be tagged * as being for a subsequent AddNOC. See AddNOC and UpdateNOC for details about the processing. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, then * this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. @@ -85,8 +85,8 @@ export namespace OperationalCredentialsInterface { * * Effect When Received * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, then * this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. @@ -98,9 +98,8 @@ export namespace OperationalCredentialsInterface { * If the prior CSRRequest state that preceded UpdateNOC had the IsForUpdateNOC field indicated as false, then * this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. * - * If any of the following conditions arise, the Node shall process an error by responding with an - * - * NOCResponse with a StatusCode of InvalidNOC as described in Section 11.18.6.7.2, “Handling Errors”: + * If any of the following conditions arise, the Node shall process an error by responding with an NOCResponse + * with a StatusCode of InvalidNOC as described in Section 11.18.6.7.2, “Handling Errors”: * * • The NOC provided in the NOCValue does not refer in its subject to the FabricID associated with the * accessing fabric. @@ -181,12 +180,14 @@ export namespace OperationalCredentialsInterface { * If the certificate from the RootCACertificate field is already installed, based on exact byte-for-byte * equality, then this command shall succeed with no change to the list. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If a prior AddTrustedRootCertificate command was successfully invoked within the fail-safe timer period, - * which would cause the new invocation to add a second root certificate within a given fail- safe timer - * period, then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. + * which would cause the new invocation to add a second root certificate within a given fail- + * + * safe timer period, then this command shall fail with a CONSTRAINT_ERROR status code sent back to the + * initiator. * * If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, then * this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. diff --git a/packages/node/src/behaviors/operational-credentials/index.ts b/packages/node/src/behaviors/operational-credentials/index.ts index 76391076fc..78db442b24 100644 --- a/packages/node/src/behaviors/operational-credentials/index.ts +++ b/packages/node/src/behaviors/operational-credentials/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/operational-state/OperationalStateBehavior.ts b/packages/node/src/behaviors/operational-state/OperationalStateBehavior.ts index d63ea461c7..15e06060bd 100644 --- a/packages/node/src/behaviors/operational-state/OperationalStateBehavior.ts +++ b/packages/node/src/behaviors/operational-state/OperationalStateBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/operational-state/OperationalStateInterface.ts b/packages/node/src/behaviors/operational-state/OperationalStateInterface.ts index 01d2535a92..602245b109 100644 --- a/packages/node/src/behaviors/operational-state/OperationalStateInterface.ts +++ b/packages/node/src/behaviors/operational-state/OperationalStateInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/operational-state/OperationalStateServer.ts b/packages/node/src/behaviors/operational-state/OperationalStateServer.ts index 7a37ff75ff..64a1a04ab1 100644 --- a/packages/node/src/behaviors/operational-state/OperationalStateServer.ts +++ b/packages/node/src/behaviors/operational-state/OperationalStateServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/operational-state/index.ts b/packages/node/src/behaviors/operational-state/index.ts index b3f1e09cfb..5762015edf 100644 --- a/packages/node/src/behaviors/operational-state/index.ts +++ b/packages/node/src/behaviors/operational-state/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ota-software-update-provider/OtaSoftwareUpdateProviderBehavior.ts b/packages/node/src/behaviors/ota-software-update-provider/OtaSoftwareUpdateProviderBehavior.ts index fbc95a14c7..52bd9e9de1 100644 --- a/packages/node/src/behaviors/ota-software-update-provider/OtaSoftwareUpdateProviderBehavior.ts +++ b/packages/node/src/behaviors/ota-software-update-provider/OtaSoftwareUpdateProviderBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ota-software-update-provider/OtaSoftwareUpdateProviderInterface.ts b/packages/node/src/behaviors/ota-software-update-provider/OtaSoftwareUpdateProviderInterface.ts index 69ab8e8f41..10e49aae00 100644 --- a/packages/node/src/behaviors/ota-software-update-provider/OtaSoftwareUpdateProviderInterface.ts +++ b/packages/node/src/behaviors/ota-software-update-provider/OtaSoftwareUpdateProviderInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ota-software-update-provider/index.ts b/packages/node/src/behaviors/ota-software-update-provider/index.ts index d5a883f9c8..6da1dbc57d 100644 --- a/packages/node/src/behaviors/ota-software-update-provider/index.ts +++ b/packages/node/src/behaviors/ota-software-update-provider/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ota-software-update-requestor/OtaSoftwareUpdateRequestorBehavior.ts b/packages/node/src/behaviors/ota-software-update-requestor/OtaSoftwareUpdateRequestorBehavior.ts index 1494df0060..f19c36c406 100644 --- a/packages/node/src/behaviors/ota-software-update-requestor/OtaSoftwareUpdateRequestorBehavior.ts +++ b/packages/node/src/behaviors/ota-software-update-requestor/OtaSoftwareUpdateRequestorBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ota-software-update-requestor/OtaSoftwareUpdateRequestorInterface.ts b/packages/node/src/behaviors/ota-software-update-requestor/OtaSoftwareUpdateRequestorInterface.ts index eb668f4f73..3d22dd6966 100644 --- a/packages/node/src/behaviors/ota-software-update-requestor/OtaSoftwareUpdateRequestorInterface.ts +++ b/packages/node/src/behaviors/ota-software-update-requestor/OtaSoftwareUpdateRequestorInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ota-software-update-requestor/index.ts b/packages/node/src/behaviors/ota-software-update-requestor/index.ts index 096cce3e2a..99b51204d6 100644 --- a/packages/node/src/behaviors/ota-software-update-requestor/index.ts +++ b/packages/node/src/behaviors/ota-software-update-requestor/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateBehavior.ts b/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateBehavior.ts index cb7c250796..32d9cceadc 100644 --- a/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateBehavior.ts +++ b/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,12 +8,15 @@ import { OvenCavityOperationalState } from "#clusters/oven-cavity-operational-state"; import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { OvenCavityOperationalStateInterface } from "./OvenCavityOperationalStateInterface.js"; /** * OvenCavityOperationalStateBehavior is the base class for objects that support interaction with {@link * OvenCavityOperationalState.Cluster}. */ -export const OvenCavityOperationalStateBehavior = ClusterBehavior.for(OvenCavityOperationalState.Cluster); +export const OvenCavityOperationalStateBehavior = ClusterBehavior + .withInterface() + .for(OvenCavityOperationalState.Cluster); type OvenCavityOperationalStateBehaviorType = InstanceType; export interface OvenCavityOperationalStateBehavior extends OvenCavityOperationalStateBehaviorType {} diff --git a/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateInterface.ts b/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateInterface.ts new file mode 100644 index 0000000000..0dd4c9d607 --- /dev/null +++ b/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateInterface.ts @@ -0,0 +1,10 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +export namespace OvenCavityOperationalStateInterface {} +export type OvenCavityOperationalStateInterface = { components: [] }; diff --git a/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateServer.ts b/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateServer.ts index 85fa6771eb..35f4e72825 100644 --- a/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateServer.ts +++ b/packages/node/src/behaviors/oven-cavity-operational-state/OvenCavityOperationalStateServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/oven-cavity-operational-state/index.ts b/packages/node/src/behaviors/oven-cavity-operational-state/index.ts index 4e09110d7a..ab4dce0ac2 100644 --- a/packages/node/src/behaviors/oven-cavity-operational-state/index.ts +++ b/packages/node/src/behaviors/oven-cavity-operational-state/index.ts @@ -1,10 +1,11 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ +export * from "./OvenCavityOperationalStateInterface.js"; export * from "./OvenCavityOperationalStateBehavior.js"; export * from "./OvenCavityOperationalStateServer.js"; diff --git a/packages/node/src/behaviors/oven-mode/OvenModeBehavior.ts b/packages/node/src/behaviors/oven-mode/OvenModeBehavior.ts index 5727a9fd6e..a28917a60b 100644 --- a/packages/node/src/behaviors/oven-mode/OvenModeBehavior.ts +++ b/packages/node/src/behaviors/oven-mode/OvenModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,9 +11,6 @@ import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; /** * OvenModeBehavior is the base class for objects that support interaction with {@link OvenMode.Cluster}. - * - * This class does not have optional features of OvenMode.Cluster enabled. You can enable additional features using - * OvenModeBehavior.with. */ export const OvenModeBehavior = ClusterBehavior.for(OvenMode.Cluster); diff --git a/packages/node/src/behaviors/oven-mode/OvenModeServer.ts b/packages/node/src/behaviors/oven-mode/OvenModeServer.ts index 486cc26bcc..0bf26877db 100644 --- a/packages/node/src/behaviors/oven-mode/OvenModeServer.ts +++ b/packages/node/src/behaviors/oven-mode/OvenModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/oven-mode/index.ts b/packages/node/src/behaviors/oven-mode/index.ts index 8174f7bc07..09d1f27727 100644 --- a/packages/node/src/behaviors/oven-mode/index.ts +++ b/packages/node/src/behaviors/oven-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ozone-concentration-measurement/OzoneConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/ozone-concentration-measurement/OzoneConcentrationMeasurementBehavior.ts index e2c011f572..183f4f6ddf 100644 --- a/packages/node/src/behaviors/ozone-concentration-measurement/OzoneConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/ozone-concentration-measurement/OzoneConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ozone-concentration-measurement/OzoneConcentrationMeasurementServer.ts b/packages/node/src/behaviors/ozone-concentration-measurement/OzoneConcentrationMeasurementServer.ts index d0cfaa827c..017db8ef04 100644 --- a/packages/node/src/behaviors/ozone-concentration-measurement/OzoneConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/ozone-concentration-measurement/OzoneConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/ozone-concentration-measurement/index.ts b/packages/node/src/behaviors/ozone-concentration-measurement/index.ts index 84bb1c839e..e26b8192d0 100644 --- a/packages/node/src/behaviors/ozone-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/ozone-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm1-concentration-measurement/Pm1ConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/pm1-concentration-measurement/Pm1ConcentrationMeasurementBehavior.ts index 97e91e2820..41d8cceedd 100644 --- a/packages/node/src/behaviors/pm1-concentration-measurement/Pm1ConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/pm1-concentration-measurement/Pm1ConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm1-concentration-measurement/Pm1ConcentrationMeasurementServer.ts b/packages/node/src/behaviors/pm1-concentration-measurement/Pm1ConcentrationMeasurementServer.ts index 0e1d1f6a7f..75b912e439 100644 --- a/packages/node/src/behaviors/pm1-concentration-measurement/Pm1ConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/pm1-concentration-measurement/Pm1ConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm1-concentration-measurement/index.ts b/packages/node/src/behaviors/pm1-concentration-measurement/index.ts index 5b82d2dcff..1fa61b68ee 100644 --- a/packages/node/src/behaviors/pm1-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/pm1-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm10-concentration-measurement/Pm10ConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/pm10-concentration-measurement/Pm10ConcentrationMeasurementBehavior.ts index 3e54a57f7d..8c9dc53d64 100644 --- a/packages/node/src/behaviors/pm10-concentration-measurement/Pm10ConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/pm10-concentration-measurement/Pm10ConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm10-concentration-measurement/Pm10ConcentrationMeasurementServer.ts b/packages/node/src/behaviors/pm10-concentration-measurement/Pm10ConcentrationMeasurementServer.ts index a8984ddd35..880719842f 100644 --- a/packages/node/src/behaviors/pm10-concentration-measurement/Pm10ConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/pm10-concentration-measurement/Pm10ConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm10-concentration-measurement/index.ts b/packages/node/src/behaviors/pm10-concentration-measurement/index.ts index ab1cc2e0e6..03e2a990da 100644 --- a/packages/node/src/behaviors/pm10-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/pm10-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm25-concentration-measurement/Pm25ConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/pm25-concentration-measurement/Pm25ConcentrationMeasurementBehavior.ts index ac19080702..caa2642e1b 100644 --- a/packages/node/src/behaviors/pm25-concentration-measurement/Pm25ConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/pm25-concentration-measurement/Pm25ConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm25-concentration-measurement/Pm25ConcentrationMeasurementServer.ts b/packages/node/src/behaviors/pm25-concentration-measurement/Pm25ConcentrationMeasurementServer.ts index 407dfc95ec..2f59bc1521 100644 --- a/packages/node/src/behaviors/pm25-concentration-measurement/Pm25ConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/pm25-concentration-measurement/Pm25ConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pm25-concentration-measurement/index.ts b/packages/node/src/behaviors/pm25-concentration-measurement/index.ts index 13d6234fac..c350915e03 100644 --- a/packages/node/src/behaviors/pm25-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/pm25-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/power-source-configuration/PowerSourceConfigurationBehavior.ts b/packages/node/src/behaviors/power-source-configuration/PowerSourceConfigurationBehavior.ts index df06d93013..e943ecbf52 100644 --- a/packages/node/src/behaviors/power-source-configuration/PowerSourceConfigurationBehavior.ts +++ b/packages/node/src/behaviors/power-source-configuration/PowerSourceConfigurationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/power-source-configuration/PowerSourceConfigurationServer.ts b/packages/node/src/behaviors/power-source-configuration/PowerSourceConfigurationServer.ts index bf8a9eb37c..908217c85c 100644 --- a/packages/node/src/behaviors/power-source-configuration/PowerSourceConfigurationServer.ts +++ b/packages/node/src/behaviors/power-source-configuration/PowerSourceConfigurationServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/power-source-configuration/index.ts b/packages/node/src/behaviors/power-source-configuration/index.ts index e99448fa9c..7fb5c26825 100644 --- a/packages/node/src/behaviors/power-source-configuration/index.ts +++ b/packages/node/src/behaviors/power-source-configuration/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/power-source/PowerSourceBehavior.ts b/packages/node/src/behaviors/power-source/PowerSourceBehavior.ts index 2fc461ef6b..3e25211842 100644 --- a/packages/node/src/behaviors/power-source/PowerSourceBehavior.ts +++ b/packages/node/src/behaviors/power-source/PowerSourceBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,14 +8,15 @@ import { PowerSource } from "#clusters/power-source"; import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { ClusterType } from "#types"; /** * PowerSourceBehavior is the base class for objects that support interaction with {@link PowerSource.Cluster}. * - * This class does not have optional features of PowerSource.Cluster enabled. You can enable additional features using - * PowerSourceBehavior.with. + * PowerSource.Cluster requires you to enable one or more optional features. You can do so using {@link + * PowerSourceBehavior.with}. */ -export const PowerSourceBehavior = ClusterBehavior.for(PowerSource.Cluster); +export const PowerSourceBehavior = ClusterBehavior.for(ClusterType(PowerSource.Base)); type PowerSourceBehaviorType = InstanceType; export interface PowerSourceBehavior extends PowerSourceBehaviorType {} diff --git a/packages/node/src/behaviors/power-source/index.ts b/packages/node/src/behaviors/power-source/index.ts index a94b31c416..651998304a 100644 --- a/packages/node/src/behaviors/power-source/index.ts +++ b/packages/node/src/behaviors/power-source/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/power-topology/PowerTopologyBehavior.ts b/packages/node/src/behaviors/power-topology/PowerTopologyBehavior.ts index 83be00df81..7af894add6 100644 --- a/packages/node/src/behaviors/power-topology/PowerTopologyBehavior.ts +++ b/packages/node/src/behaviors/power-topology/PowerTopologyBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/power-topology/index.ts b/packages/node/src/behaviors/power-topology/index.ts index 95252336cf..5e8661846f 100644 --- a/packages/node/src/behaviors/power-topology/index.ts +++ b/packages/node/src/behaviors/power-topology/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pressure-measurement/PressureMeasurementBehavior.ts b/packages/node/src/behaviors/pressure-measurement/PressureMeasurementBehavior.ts index 21fb7f806c..a7b19e2400 100644 --- a/packages/node/src/behaviors/pressure-measurement/PressureMeasurementBehavior.ts +++ b/packages/node/src/behaviors/pressure-measurement/PressureMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pressure-measurement/PressureMeasurementServer.ts b/packages/node/src/behaviors/pressure-measurement/PressureMeasurementServer.ts index 700e7bc994..19638997c8 100644 --- a/packages/node/src/behaviors/pressure-measurement/PressureMeasurementServer.ts +++ b/packages/node/src/behaviors/pressure-measurement/PressureMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pressure-measurement/index.ts b/packages/node/src/behaviors/pressure-measurement/index.ts index 62dd7b1355..f2a39e18d6 100644 --- a/packages/node/src/behaviors/pressure-measurement/index.ts +++ b/packages/node/src/behaviors/pressure-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/proxy-configuration/ProxyConfigurationBehavior.ts b/packages/node/src/behaviors/proxy-configuration/ProxyConfigurationBehavior.ts index 6e38a1cf3f..420a234ab9 100644 --- a/packages/node/src/behaviors/proxy-configuration/ProxyConfigurationBehavior.ts +++ b/packages/node/src/behaviors/proxy-configuration/ProxyConfigurationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/proxy-configuration/ProxyConfigurationServer.ts b/packages/node/src/behaviors/proxy-configuration/ProxyConfigurationServer.ts index 970e5d14d5..923bf52972 100644 --- a/packages/node/src/behaviors/proxy-configuration/ProxyConfigurationServer.ts +++ b/packages/node/src/behaviors/proxy-configuration/ProxyConfigurationServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/proxy-configuration/index.ts b/packages/node/src/behaviors/proxy-configuration/index.ts index adaaf95567..d8efffce9d 100644 --- a/packages/node/src/behaviors/proxy-configuration/index.ts +++ b/packages/node/src/behaviors/proxy-configuration/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryBehavior.ts b/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryBehavior.ts index 44574ac3a8..176e53d921 100644 --- a/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryBehavior.ts +++ b/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryInterface.ts b/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryInterface.ts index 5a0455459a..596fc115d9 100644 --- a/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryInterface.ts +++ b/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryServer.ts b/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryServer.ts index d3064890f3..d93218c0b6 100644 --- a/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryServer.ts +++ b/packages/node/src/behaviors/proxy-discovery/ProxyDiscoveryServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/proxy-discovery/index.ts b/packages/node/src/behaviors/proxy-discovery/index.ts index 0141572fd3..587aa245bb 100644 --- a/packages/node/src/behaviors/proxy-discovery/index.ts +++ b/packages/node/src/behaviors/proxy-discovery/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationBehavior.ts b/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationBehavior.ts deleted file mode 100644 index c9f95aea89..0000000000 --- a/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationBehavior.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @license - * Copyright 2022-2024 Matter.js Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ - -import { PulseWidthModulation } from "#clusters/pulse-width-modulation"; -import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; -import { LevelControlInterface } from "../level-control/LevelControlInterface.js"; - -/** - * PulseWidthModulationBehavior is the base class for objects that support interaction with {@link - * PulseWidthModulation.Cluster}. - * - * This class does not have optional features of PulseWidthModulation.Cluster enabled. You can enable additional - * features using PulseWidthModulationBehavior.with. - */ -export const PulseWidthModulationBehavior = ClusterBehavior - .withInterface() - .for(PulseWidthModulation.Cluster); - -type PulseWidthModulationBehaviorType = InstanceType; -export interface PulseWidthModulationBehavior extends PulseWidthModulationBehaviorType {} -type StateType = InstanceType; -export namespace PulseWidthModulationBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationInterface.ts b/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationInterface.ts deleted file mode 100644 index 354094cccb..0000000000 --- a/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationInterface.ts +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @license - * Copyright 2022-2024 Matter.js Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ - -import { LevelControl } from "#clusters/level-control"; -import { MaybePromise } from "#general"; -import { TypeFromSchema } from "#types"; - -/** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.1 - */ -export type MoveToLevelRequest = TypeFromSchema; - -/** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.2 - */ -export type MoveRequest = TypeFromSchema; - -/** - * The StepMode field shall be one of the non-reserved values in Values of the StepMode Field. - * - * The TransitionTime field specifies the time that shall be taken to perform the step, in tenths of a second. A step - * is a change in the CurrentLevel of StepSize units. The actual time taken SHOULD be as close to this as the device is - * able. If the TransitionTime field is equal to null, the device SHOULD move as fast as it is able. - * - * If the device is not able to move at a variable rate, the TransitionTime field may be disregarded. - * - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.3 - */ -export type StepRequest = TypeFromSchema; - -/** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.4 - */ -export type StopRequest = TypeFromSchema; - -/** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.5 - */ -export type MoveToClosestFrequencyRequest = TypeFromSchema; - -export namespace PulseWidthModulationInterface { - export interface Base { - /** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.1 - */ - moveToLevel(request: MoveToLevelRequest): MaybePromise; - - /** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.2 - */ - move(request: MoveRequest): MaybePromise; - - /** - * The StepMode field shall be one of the non-reserved values in Values of the StepMode Field. - * - * The TransitionTime field specifies the time that shall be taken to perform the step, in tenths of a second. - * A step is a change in the CurrentLevel of StepSize units. The actual time taken SHOULD be as close to this - * as the device is able. If the TransitionTime field is equal to null, the device SHOULD move as fast as it is - * able. - * - * If the device is not able to move at a variable rate, the TransitionTime field may be disregarded. - * - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.3 - */ - step(request: StepRequest): MaybePromise; - - /** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.4 - */ - stop(request: StopRequest): MaybePromise; - - /** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6 - */ - moveToLevelWithOnOff(): MaybePromise; - - /** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6 - */ - moveWithOnOff(): MaybePromise; - - /** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6 - */ - stepWithOnOff(): MaybePromise; - - /** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6 - */ - stopWithOnOff(): MaybePromise; - } - - export interface Frequency { - /** - * @see {@link MatterSpecification.v11.Cluster} § 1.6.6.5 - */ - moveToClosestFrequency(request: MoveToClosestFrequencyRequest): MaybePromise; - } -} - -export type PulseWidthModulationInterface = { - components: [ - { flags: {}; methods: PulseWidthModulationInterface.Base }, - { flags: { frequency: true }; methods: PulseWidthModulationInterface.Frequency }, - ]; -}; diff --git a/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationServer.ts b/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationServer.ts deleted file mode 100644 index cbdc3a2ecd..0000000000 --- a/packages/node/src/behaviors/pulse-width-modulation/PulseWidthModulationServer.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @license - * Copyright 2022-2024 Matter.js Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ - -import { PulseWidthModulationBehavior } from "./PulseWidthModulationBehavior.js"; - -/** - * This is the default server implementation of {@link PulseWidthModulationBehavior}. - */ -export class PulseWidthModulationServer extends PulseWidthModulationBehavior {} diff --git a/packages/node/src/behaviors/pulse-width-modulation/index.ts b/packages/node/src/behaviors/pulse-width-modulation/index.ts deleted file mode 100644 index 03bcbffbb0..0000000000 --- a/packages/node/src/behaviors/pulse-width-modulation/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -/** - * @license - * Copyright 2022-2024 Matter.js Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ - -export * from "./PulseWidthModulationBehavior.js"; -export * from "./PulseWidthModulationServer.js"; diff --git a/packages/node/src/behaviors/pump-configuration-and-control/PumpConfigurationAndControlBehavior.ts b/packages/node/src/behaviors/pump-configuration-and-control/PumpConfigurationAndControlBehavior.ts index 647ebbcc82..3758ebba98 100644 --- a/packages/node/src/behaviors/pump-configuration-and-control/PumpConfigurationAndControlBehavior.ts +++ b/packages/node/src/behaviors/pump-configuration-and-control/PumpConfigurationAndControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pump-configuration-and-control/PumpConfigurationAndControlServer.ts b/packages/node/src/behaviors/pump-configuration-and-control/PumpConfigurationAndControlServer.ts index d3327fbd50..e050657ca8 100644 --- a/packages/node/src/behaviors/pump-configuration-and-control/PumpConfigurationAndControlServer.ts +++ b/packages/node/src/behaviors/pump-configuration-and-control/PumpConfigurationAndControlServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/pump-configuration-and-control/index.ts b/packages/node/src/behaviors/pump-configuration-and-control/index.ts index 70fbf91826..e92d9da63c 100644 --- a/packages/node/src/behaviors/pump-configuration-and-control/index.ts +++ b/packages/node/src/behaviors/pump-configuration-and-control/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/radon-concentration-measurement/RadonConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/radon-concentration-measurement/RadonConcentrationMeasurementBehavior.ts index 87a1356480..f3c4a2f626 100644 --- a/packages/node/src/behaviors/radon-concentration-measurement/RadonConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/radon-concentration-measurement/RadonConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/radon-concentration-measurement/RadonConcentrationMeasurementServer.ts b/packages/node/src/behaviors/radon-concentration-measurement/RadonConcentrationMeasurementServer.ts index 69bc796096..ece75090c9 100644 --- a/packages/node/src/behaviors/radon-concentration-measurement/RadonConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/radon-concentration-measurement/RadonConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/radon-concentration-measurement/index.ts b/packages/node/src/behaviors/radon-concentration-measurement/index.ts index 10ebde02ac..065b58705e 100644 --- a/packages/node/src/behaviors/radon-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/radon-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmBehavior.ts b/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmBehavior.ts index e40915ad99..af832ef1cb 100644 --- a/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmBehavior.ts +++ b/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmInterface.ts b/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmInterface.ts index b07a30ac1f..c23aebc46c 100644 --- a/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmInterface.ts +++ b/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmServer.ts b/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmServer.ts index bb59de831e..a181fe1037 100644 --- a/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmServer.ts +++ b/packages/node/src/behaviors/refrigerator-alarm/RefrigeratorAlarmServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/refrigerator-alarm/index.ts b/packages/node/src/behaviors/refrigerator-alarm/index.ts index b2dd194acf..9353ab65c7 100644 --- a/packages/node/src/behaviors/refrigerator-alarm/index.ts +++ b/packages/node/src/behaviors/refrigerator-alarm/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/RefrigeratorAndTemperatureControlledCabinetModeBehavior.ts b/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/RefrigeratorAndTemperatureControlledCabinetModeBehavior.ts index 1f9fd45526..7d982abc1c 100644 --- a/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/RefrigeratorAndTemperatureControlledCabinetModeBehavior.ts +++ b/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/RefrigeratorAndTemperatureControlledCabinetModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/RefrigeratorAndTemperatureControlledCabinetModeServer.ts b/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/RefrigeratorAndTemperatureControlledCabinetModeServer.ts index 22e6191601..bc477a7eec 100644 --- a/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/RefrigeratorAndTemperatureControlledCabinetModeServer.ts +++ b/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/RefrigeratorAndTemperatureControlledCabinetModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/index.ts b/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/index.ts index b2354a87cf..1b5a0d5a96 100644 --- a/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/index.ts +++ b/packages/node/src/behaviors/refrigerator-and-temperature-controlled-cabinet-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/relative-humidity-measurement/RelativeHumidityMeasurementBehavior.ts b/packages/node/src/behaviors/relative-humidity-measurement/RelativeHumidityMeasurementBehavior.ts index 651f4cda31..d351699250 100644 --- a/packages/node/src/behaviors/relative-humidity-measurement/RelativeHumidityMeasurementBehavior.ts +++ b/packages/node/src/behaviors/relative-humidity-measurement/RelativeHumidityMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/relative-humidity-measurement/RelativeHumidityMeasurementServer.ts b/packages/node/src/behaviors/relative-humidity-measurement/RelativeHumidityMeasurementServer.ts index f373577918..f12b9d7e7c 100644 --- a/packages/node/src/behaviors/relative-humidity-measurement/RelativeHumidityMeasurementServer.ts +++ b/packages/node/src/behaviors/relative-humidity-measurement/RelativeHumidityMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/relative-humidity-measurement/index.ts b/packages/node/src/behaviors/relative-humidity-measurement/index.ts index 9aaeaf56c3..804f57bbd9 100644 --- a/packages/node/src/behaviors/relative-humidity-measurement/index.ts +++ b/packages/node/src/behaviors/relative-humidity-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/resource-monitoring/ResourceMonitoringInterface.ts b/packages/node/src/behaviors/resource-monitoring/ResourceMonitoringInterface.ts index 8705955a0d..5a35c58c9f 100644 --- a/packages/node/src/behaviors/resource-monitoring/ResourceMonitoringInterface.ts +++ b/packages/node/src/behaviors/resource-monitoring/ResourceMonitoringInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/resource-monitoring/index.ts b/packages/node/src/behaviors/resource-monitoring/index.ts index 4a2f701952..5c63f5c7bd 100644 --- a/packages/node/src/behaviors/resource-monitoring/index.ts +++ b/packages/node/src/behaviors/resource-monitoring/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-clean-mode/RvcCleanModeBehavior.ts b/packages/node/src/behaviors/rvc-clean-mode/RvcCleanModeBehavior.ts index 1ac8e7957d..81f26b9ea3 100644 --- a/packages/node/src/behaviors/rvc-clean-mode/RvcCleanModeBehavior.ts +++ b/packages/node/src/behaviors/rvc-clean-mode/RvcCleanModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-clean-mode/RvcCleanModeServer.ts b/packages/node/src/behaviors/rvc-clean-mode/RvcCleanModeServer.ts index 8542930206..6e62ac7ce0 100644 --- a/packages/node/src/behaviors/rvc-clean-mode/RvcCleanModeServer.ts +++ b/packages/node/src/behaviors/rvc-clean-mode/RvcCleanModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-clean-mode/index.ts b/packages/node/src/behaviors/rvc-clean-mode/index.ts index 6737f590e9..78dabdc468 100644 --- a/packages/node/src/behaviors/rvc-clean-mode/index.ts +++ b/packages/node/src/behaviors/rvc-clean-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateBehavior.ts b/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateBehavior.ts index db65200579..e95fafa33c 100644 --- a/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateBehavior.ts +++ b/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateInterface.ts b/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateInterface.ts index fcb5c367b3..9a4693d4ea 100644 --- a/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateInterface.ts +++ b/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateServer.ts b/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateServer.ts index c2cb810369..2eae7b94e0 100644 --- a/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateServer.ts +++ b/packages/node/src/behaviors/rvc-operational-state/RvcOperationalStateServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-operational-state/index.ts b/packages/node/src/behaviors/rvc-operational-state/index.ts index fc89f846ab..1dddacd394 100644 --- a/packages/node/src/behaviors/rvc-operational-state/index.ts +++ b/packages/node/src/behaviors/rvc-operational-state/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-run-mode/RvcRunModeBehavior.ts b/packages/node/src/behaviors/rvc-run-mode/RvcRunModeBehavior.ts index f8015c6317..99ffc20a56 100644 --- a/packages/node/src/behaviors/rvc-run-mode/RvcRunModeBehavior.ts +++ b/packages/node/src/behaviors/rvc-run-mode/RvcRunModeBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-run-mode/RvcRunModeServer.ts b/packages/node/src/behaviors/rvc-run-mode/RvcRunModeServer.ts index ed91e843e9..f09d3edd65 100644 --- a/packages/node/src/behaviors/rvc-run-mode/RvcRunModeServer.ts +++ b/packages/node/src/behaviors/rvc-run-mode/RvcRunModeServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/rvc-run-mode/index.ts b/packages/node/src/behaviors/rvc-run-mode/index.ts index 04a082f5b6..65a9f985bc 100644 --- a/packages/node/src/behaviors/rvc-run-mode/index.ts +++ b/packages/node/src/behaviors/rvc-run-mode/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/scenes-management/ScenesManagementBehavior.ts b/packages/node/src/behaviors/scenes-management/ScenesManagementBehavior.ts index c8ad616f8d..f80fe81f3d 100644 --- a/packages/node/src/behaviors/scenes-management/ScenesManagementBehavior.ts +++ b/packages/node/src/behaviors/scenes-management/ScenesManagementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/scenes-management/ScenesManagementInterface.ts b/packages/node/src/behaviors/scenes-management/ScenesManagementInterface.ts index 53d4d1c72d..20a08077b8 100644 --- a/packages/node/src/behaviors/scenes-management/ScenesManagementInterface.ts +++ b/packages/node/src/behaviors/scenes-management/ScenesManagementInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/scenes-management/ScenesManagementServer.ts b/packages/node/src/behaviors/scenes-management/ScenesManagementServer.ts index f881a9fd55..f40ef4e336 100644 --- a/packages/node/src/behaviors/scenes-management/ScenesManagementServer.ts +++ b/packages/node/src/behaviors/scenes-management/ScenesManagementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/scenes-management/index.ts b/packages/node/src/behaviors/scenes-management/index.ts index c931f8b009..74b0ee6760 100644 --- a/packages/node/src/behaviors/scenes-management/index.ts +++ b/packages/node/src/behaviors/scenes-management/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/service-area/ServiceAreaBehavior.ts b/packages/node/src/behaviors/service-area/ServiceAreaBehavior.ts new file mode 100644 index 0000000000..8fbf36165f --- /dev/null +++ b/packages/node/src/behaviors/service-area/ServiceAreaBehavior.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { ServiceArea } from "#clusters/service-area"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { ServiceAreaInterface } from "./ServiceAreaInterface.js"; + +/** + * ServiceAreaBehavior is the base class for objects that support interaction with {@link ServiceArea.Cluster}. + * + * This class does not have optional features of ServiceArea.Cluster enabled. You can enable additional features using + * ServiceAreaBehavior.with. + */ +export const ServiceAreaBehavior = ClusterBehavior + .withInterface() + .for(ServiceArea.Cluster); + +type ServiceAreaBehaviorType = InstanceType; +export interface ServiceAreaBehavior extends ServiceAreaBehaviorType {} +type StateType = InstanceType; +export namespace ServiceAreaBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/service-area/ServiceAreaInterface.ts b/packages/node/src/behaviors/service-area/ServiceAreaInterface.ts new file mode 100644 index 0000000000..168b315551 --- /dev/null +++ b/packages/node/src/behaviors/service-area/ServiceAreaInterface.ts @@ -0,0 +1,38 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; +import { ServiceArea } from "#clusters/service-area"; + +export namespace ServiceAreaInterface { + export interface Base { + /** + * This command is used to select a set of device areas, where the device is to operate. + * + * On receipt of this command the device shall respond with a SelectAreasResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.1 + */ + selectAreas(request: ServiceArea.SelectAreasRequest): MaybePromise; + + /** + * This command is used to skip the given area, and to attempt operating at other areas on the SupportedAreas + * attribute list. + * + * This command shall NOT be implemented if the CurrentArea attribute and the Progress attribute are both not + * implemented. Else, this command shall be optionally implemented. + * + * On receipt of this command the device shall respond with a SkipAreaResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.3 + */ + skipArea(request: ServiceArea.SkipAreaRequest): MaybePromise; + } +} + +export type ServiceAreaInterface = { components: [{ flags: {}, methods: ServiceAreaInterface.Base }] }; diff --git a/packages/node/src/behaviors/service-area/ServiceAreaServer.ts b/packages/node/src/behaviors/service-area/ServiceAreaServer.ts new file mode 100644 index 0000000000..a586381819 --- /dev/null +++ b/packages/node/src/behaviors/service-area/ServiceAreaServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { ServiceAreaBehavior } from "./ServiceAreaBehavior.js"; + +/** + * This is the default server implementation of {@link ServiceAreaBehavior}. + */ +export class ServiceAreaServer extends ServiceAreaBehavior {} diff --git a/packages/node/src/behaviors/service-area/index.ts b/packages/node/src/behaviors/service-area/index.ts new file mode 100644 index 0000000000..219cfab74c --- /dev/null +++ b/packages/node/src/behaviors/service-area/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./ServiceAreaInterface.js"; +export * from "./ServiceAreaBehavior.js"; +export * from "./ServiceAreaServer.js"; diff --git a/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmBehavior.ts b/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmBehavior.ts index bb2d02b389..daf4af6bbd 100644 --- a/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmBehavior.ts +++ b/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmInterface.ts b/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmInterface.ts index 54ee71c3c6..7bef418e38 100644 --- a/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmInterface.ts +++ b/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,9 +13,8 @@ export namespace SmokeCoAlarmInterface { /** * This command shall initiate a device self-test. The return status shall indicate whether the test was * successfully initiated. Only one SelfTestRequest may be processed at a time. When the value of the - * ExpressedState attribute is any of SmokeAlarm, COAlarm, Testing, InterconnectSmoke, Inter - * - * connectCO, the device shall NOT execute the self-test, and shall return status code BUSY. + * ExpressedState attribute is any of SmokeAlarm, COAlarm, Testing, InterconnectSmoke, InterconnectCO, the + * device shall NOT execute the self-test, and shall return status code BUSY. * * Upon successful acceptance of SelfTestRequest, the TestInProgress attribute shall be set to True and * ExpressedState attribute shall be set to Testing. Any faults identified during the test shall be reflected diff --git a/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmServer.ts b/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmServer.ts index cc97d55659..04a82656bb 100644 --- a/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmServer.ts +++ b/packages/node/src/behaviors/smoke-co-alarm/SmokeCoAlarmServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/smoke-co-alarm/index.ts b/packages/node/src/behaviors/smoke-co-alarm/index.ts index 89d2d5211a..fc32dc4ba6 100644 --- a/packages/node/src/behaviors/smoke-co-alarm/index.ts +++ b/packages/node/src/behaviors/smoke-co-alarm/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsBehavior.ts b/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsBehavior.ts index f98e41eac3..2a617dc6c5 100644 --- a/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsBehavior.ts +++ b/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsInterface.ts b/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsInterface.ts index 00b96be118..34d3ee8e3c 100644 --- a/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsInterface.ts +++ b/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsServer.ts b/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsServer.ts index 2cecc0eed2..9880bf4ae3 100644 --- a/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsServer.ts +++ b/packages/node/src/behaviors/software-diagnostics/SoftwareDiagnosticsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/software-diagnostics/index.ts b/packages/node/src/behaviors/software-diagnostics/index.ts index 9d2c910498..385dd8a8c5 100644 --- a/packages/node/src/behaviors/software-diagnostics/index.ts +++ b/packages/node/src/behaviors/software-diagnostics/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/switch/SwitchBehavior.ts b/packages/node/src/behaviors/switch/SwitchBehavior.ts index 4b778734aa..5b374c9027 100644 --- a/packages/node/src/behaviors/switch/SwitchBehavior.ts +++ b/packages/node/src/behaviors/switch/SwitchBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/switch/index.ts b/packages/node/src/behaviors/switch/index.ts index 15fa1a454c..f14ef7d8bf 100644 --- a/packages/node/src/behaviors/switch/index.ts +++ b/packages/node/src/behaviors/switch/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/target-navigator/TargetNavigatorBehavior.ts b/packages/node/src/behaviors/target-navigator/TargetNavigatorBehavior.ts index 47b2fa6792..c18c38e1ed 100644 --- a/packages/node/src/behaviors/target-navigator/TargetNavigatorBehavior.ts +++ b/packages/node/src/behaviors/target-navigator/TargetNavigatorBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/target-navigator/TargetNavigatorInterface.ts b/packages/node/src/behaviors/target-navigator/TargetNavigatorInterface.ts index 1eefebe5bd..1239f12a0c 100644 --- a/packages/node/src/behaviors/target-navigator/TargetNavigatorInterface.ts +++ b/packages/node/src/behaviors/target-navigator/TargetNavigatorInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/target-navigator/TargetNavigatorServer.ts b/packages/node/src/behaviors/target-navigator/TargetNavigatorServer.ts index 532dbc4013..b71f27223a 100644 --- a/packages/node/src/behaviors/target-navigator/TargetNavigatorServer.ts +++ b/packages/node/src/behaviors/target-navigator/TargetNavigatorServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/target-navigator/index.ts b/packages/node/src/behaviors/target-navigator/index.ts index 2511d25365..2f72ce9cf6 100644 --- a/packages/node/src/behaviors/target-navigator/index.ts +++ b/packages/node/src/behaviors/target-navigator/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/temperature-control/TemperatureControlBehavior.ts b/packages/node/src/behaviors/temperature-control/TemperatureControlBehavior.ts index 4183b2f4e5..f46a1e5058 100644 --- a/packages/node/src/behaviors/temperature-control/TemperatureControlBehavior.ts +++ b/packages/node/src/behaviors/temperature-control/TemperatureControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/temperature-control/TemperatureControlInterface.ts b/packages/node/src/behaviors/temperature-control/TemperatureControlInterface.ts index 8b4aa36766..368b4d6f5c 100644 --- a/packages/node/src/behaviors/temperature-control/TemperatureControlInterface.ts +++ b/packages/node/src/behaviors/temperature-control/TemperatureControlInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/temperature-control/TemperatureControlServer.ts b/packages/node/src/behaviors/temperature-control/TemperatureControlServer.ts index 27fb632f72..2d33143d25 100644 --- a/packages/node/src/behaviors/temperature-control/TemperatureControlServer.ts +++ b/packages/node/src/behaviors/temperature-control/TemperatureControlServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/temperature-control/index.ts b/packages/node/src/behaviors/temperature-control/index.ts index 31ae099eb2..1f81261032 100644 --- a/packages/node/src/behaviors/temperature-control/index.ts +++ b/packages/node/src/behaviors/temperature-control/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/temperature-measurement/TemperatureMeasurementBehavior.ts b/packages/node/src/behaviors/temperature-measurement/TemperatureMeasurementBehavior.ts index ac7b6f665a..cf87b67b4f 100644 --- a/packages/node/src/behaviors/temperature-measurement/TemperatureMeasurementBehavior.ts +++ b/packages/node/src/behaviors/temperature-measurement/TemperatureMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/temperature-measurement/TemperatureMeasurementServer.ts b/packages/node/src/behaviors/temperature-measurement/TemperatureMeasurementServer.ts index 674c5a0767..28b1904812 100644 --- a/packages/node/src/behaviors/temperature-measurement/TemperatureMeasurementServer.ts +++ b/packages/node/src/behaviors/temperature-measurement/TemperatureMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/temperature-measurement/index.ts b/packages/node/src/behaviors/temperature-measurement/index.ts index fc78829813..8eb57c0b83 100644 --- a/packages/node/src/behaviors/temperature-measurement/index.ts +++ b/packages/node/src/behaviors/temperature-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationBehavior.ts b/packages/node/src/behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationBehavior.ts index 679a41975c..2fc4fec321 100644 --- a/packages/node/src/behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationBehavior.ts +++ b/packages/node/src/behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationServer.ts b/packages/node/src/behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationServer.ts index 2c9c77faf7..c990d16922 100644 --- a/packages/node/src/behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationServer.ts +++ b/packages/node/src/behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thermostat-user-interface-configuration/index.ts b/packages/node/src/behaviors/thermostat-user-interface-configuration/index.ts index 1576369d1e..bf85370461 100644 --- a/packages/node/src/behaviors/thermostat-user-interface-configuration/index.ts +++ b/packages/node/src/behaviors/thermostat-user-interface-configuration/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thermostat/ThermostatBehavior.ts b/packages/node/src/behaviors/thermostat/ThermostatBehavior.ts index 2c8685fbc3..c1346d401a 100644 --- a/packages/node/src/behaviors/thermostat/ThermostatBehavior.ts +++ b/packages/node/src/behaviors/thermostat/ThermostatBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thermostat/ThermostatInterface.ts b/packages/node/src/behaviors/thermostat/ThermostatInterface.ts index 6419b660df..4864e87554 100644 --- a/packages/node/src/behaviors/thermostat/ThermostatInterface.ts +++ b/packages/node/src/behaviors/thermostat/ThermostatInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,11 +12,6 @@ import { Thermostat } from "#clusters/thermostat"; export namespace ThermostatInterface { export interface Base { /** - * Upon receipt, the attributes for the indicated setpoint(s) shall have the amount specified in the Amount - * field added to them. If the resulting value is outside the limits imposed by MinCoolSetpointLimit, - * MaxCoolSetpointLimit, MinHeatSetpointLimit and MaxHeatSetpointLimit, the value is clamped to those limits. - * This is not considered an error condition. - * * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.1 */ setpointRaiseLower(request: Thermostat.SetpointRaiseLowerRequest): MaybePromise; @@ -24,46 +19,20 @@ export namespace ThermostatInterface { export interface ScheduleConfiguration { /** - * Upon receipt, the weekly schedule for updating setpoints shall be stored in the thermostat and SHOULD begin - * at the time of receipt. A status code shall be sent in response. - * - * When a command is received that requires a total number of transitions greater than the device supports, the - * status of the response shall be INSUFFICIENT_SPACE. - * - * When any of the setpoints sent in the sequence is out of range (AbsMin/MaxSetPointLimit), or when the Mode - * for Sequence field includes a mode not supported by the device, the status of the response shall be - * CONSTRAINT_ERROR and no setpoints from the entire sequence SHOULD be used. - * - * When an overlapping transition is detected, the status of the response shall be FAILURE. - * - * When a device which does not support multiple days in a command receives a command with more than one bit - * set in the DayOfWeekForSequence field, or when a device which does not support multiple modes in a command - * receives a command with more than one bit set in the ModeForSequence field, or when the contents of the - * Transitions field does not agree with NumberOfTransitionsForSequence, DayOfWeekForSequence or - * ModeForSequence, the status of the response shall be INVALID_COMMAND. + * This command is used to update the thermostat weekly setpoint schedule from a management system. If the + * thermostat already has a weekly setpoint schedule programmed, then it SHOULD replace each daily setpoint set + * as it receives the updates from the management system. For example, if the thermostat has 4 setpoints for + * every day of the week and is sent a SetWeeklySchedule command with one setpoint for Saturday then the + * thermostat SHOULD remove all 4 setpoints for Saturday and replace those with the updated setpoint but leave + * all other days unchanged. If the schedule is larger than what fits in one frame or contains more than 10 + * transitions, the schedule shall then be sent using multiple SetWeeklySchedule Commands. * - * When the transitions could be added successfully, the status of the response shall be SUCCESS. - * - * The set weekly schedule command is used to update the thermostat weekly setpoint schedule from a management - * system. If the thermostat already has a weekly setpoint schedule programmed, then it SHOULD replace each - * daily setpoint set as it receives the updates from the management system. For example, if the thermostat has - * 4 setpoints for every day of the week and is sent a Set Weekly Schedule command with one setpoint for - * Saturday then the thermostat SHOULD remove all 4 setpoints for Saturday and replace those with the updated - * setpoint but leave all other days unchanged. If the schedule is larger than what fits in one frame or - * contains more than 10 transitions, the schedule shall then be sent using multiple Set Weekly Schedule - * Commands. - * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.2 */ setWeeklySchedule(request: Thermostat.SetWeeklyScheduleRequest): MaybePromise; /** - * Upon receipt, the unit SHOULD send in return the Get Weekly Schedule Response command. The Days to Return - * and Mode to Return fields are defined as bitmask for the flexibility to support multiple days and multiple - * modes within one command. If thermostat cannot handle incoming command with multiple days and/or multiple - * modes within one command, it shall send default response of INVALID_COMMAND in return. - * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.5 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.3 */ getWeeklySchedule(request: Thermostat.GetWeeklyScheduleRequest): MaybePromise; @@ -73,15 +42,31 @@ export namespace ThermostatInterface { * Upon receipt, all transitions currently stored shall be cleared and a default response of SUCCESS shall be * sent in response. There are no error responses to this command. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.7 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.5 */ clearWeeklySchedule(): MaybePromise; } + + export interface Presets { + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.9 + */ + setActivePresetRequest(request: Thermostat.SetActivePresetRequest): MaybePromise; + } + + export interface MatterScheduleConfiguration { + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.8 + */ + setActiveScheduleRequest(request: Thermostat.SetActiveScheduleRequest): MaybePromise; + } } export type ThermostatInterface = { components: [ { flags: {}, methods: ThermostatInterface.Base }, - { flags: { scheduleConfiguration: true }, methods: ThermostatInterface.ScheduleConfiguration } + { flags: { scheduleConfiguration: true }, methods: ThermostatInterface.ScheduleConfiguration }, + { flags: { presets: true }, methods: ThermostatInterface.Presets }, + { flags: { matterScheduleConfiguration: true }, methods: ThermostatInterface.MatterScheduleConfiguration } ] }; diff --git a/packages/node/src/behaviors/thermostat/ThermostatServer.ts b/packages/node/src/behaviors/thermostat/ThermostatServer.ts index 0624f13a8d..857a0aadc0 100644 --- a/packages/node/src/behaviors/thermostat/ThermostatServer.ts +++ b/packages/node/src/behaviors/thermostat/ThermostatServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thermostat/index.ts b/packages/node/src/behaviors/thermostat/index.ts index 395101f3aa..c2b6c9937a 100644 --- a/packages/node/src/behaviors/thermostat/index.ts +++ b/packages/node/src/behaviors/thermostat/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementBehavior.ts b/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementBehavior.ts new file mode 100644 index 0000000000..48e9293112 --- /dev/null +++ b/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementBehavior.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { ThreadBorderRouterManagement } from "#clusters/thread-border-router-management"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { ThreadBorderRouterManagementInterface } from "./ThreadBorderRouterManagementInterface.js"; + +/** + * ThreadBorderRouterManagementBehavior is the base class for objects that support interaction with {@link + * ThreadBorderRouterManagement.Cluster}. + * + * This class does not have optional features of ThreadBorderRouterManagement.Cluster enabled. You can enable + * additional features using ThreadBorderRouterManagementBehavior.with. + */ +export const ThreadBorderRouterManagementBehavior = ClusterBehavior + .withInterface() + .for(ThreadBorderRouterManagement.Cluster); + +type ThreadBorderRouterManagementBehaviorType = InstanceType; +export interface ThreadBorderRouterManagementBehavior extends ThreadBorderRouterManagementBehaviorType {} +type StateType = InstanceType; +export namespace ThreadBorderRouterManagementBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementInterface.ts b/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementInterface.ts new file mode 100644 index 0000000000..50ab5a7e73 --- /dev/null +++ b/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementInterface.ts @@ -0,0 +1,85 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; +import { ThreadBorderRouterManagement } from "#clusters/thread-border-router-management"; + +export namespace ThreadBorderRouterManagementInterface { + export interface Base { + /** + * This command shall be used to request the active operational dataset of the Thread network to which the + * border router is connected. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * UNSUPPORTED_ACCESS. + * + * If an internal error occurs, then this command shall fail with a FAILURE status code sent back to the + * initiator. + * + * Otherwise, this shall generate a DatasetResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.1 + */ + getActiveDatasetRequest(): MaybePromise; + + /** + * This command shall be used to request the pending dataset of the Thread network to which the border router + * is connected. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * UNSUPPORTED_ACCESS. + * + * If an internal error occurs, then this command shall fail with a FAILURE status code sent back to the + * initiator. + * + * Otherwise, this shall generate a DatasetResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.2 + */ + getPendingDatasetRequest(): MaybePromise; + + /** + * This command shall be used to set the active Dataset of the Thread network to which the Border Router is + * connected, when there is no active dataset already. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.4 + */ + setActiveDatasetRequest(request: ThreadBorderRouterManagement.SetActiveDatasetRequest): MaybePromise; + } + + export interface PanChange { + /** + * This command shall be used to set or update the pending Dataset of the Thread network to which the Border + * Router is connected, if the Border Router supports PAN Change. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * UNSUPPORTED_ACCESS. + * + * This PendingDataset field shall contain the pending dataset to which the Thread network should be updated. + * The format of the data shall be an octet string containing the raw Thread TLV value of the pending dataset, + * as defined in the Thread specification. + * + * If any of the parameters in the PendingDataset is invalid, the command shall fail with a status of + * INVALID_COMMAND. + * + * Otherwise, this command shall configure the pending dataset of the Thread network to which the Border Router + * is connected, with the value given in the PendingDataset parameter. The Border Router will manage activation + * of the pending dataset as defined in the Thread specification. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.5 + */ + setPendingDatasetRequest(request: ThreadBorderRouterManagement.SetPendingDatasetRequest): MaybePromise; + } +} + +export type ThreadBorderRouterManagementInterface = { + components: [ + { flags: {}, methods: ThreadBorderRouterManagementInterface.Base }, + { flags: { panChange: true }, methods: ThreadBorderRouterManagementInterface.PanChange } + ] +}; diff --git a/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementServer.ts b/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementServer.ts new file mode 100644 index 0000000000..a60d41055e --- /dev/null +++ b/packages/node/src/behaviors/thread-border-router-management/ThreadBorderRouterManagementServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { ThreadBorderRouterManagementBehavior } from "./ThreadBorderRouterManagementBehavior.js"; + +/** + * This is the default server implementation of {@link ThreadBorderRouterManagementBehavior}. + */ +export class ThreadBorderRouterManagementServer extends ThreadBorderRouterManagementBehavior {} diff --git a/packages/node/src/behaviors/thread-border-router-management/index.ts b/packages/node/src/behaviors/thread-border-router-management/index.ts new file mode 100644 index 0000000000..15b0b892b9 --- /dev/null +++ b/packages/node/src/behaviors/thread-border-router-management/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./ThreadBorderRouterManagementInterface.js"; +export * from "./ThreadBorderRouterManagementBehavior.js"; +export * from "./ThreadBorderRouterManagementServer.js"; diff --git a/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsBehavior.ts b/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsBehavior.ts index 3d4e5c0e06..6f9394f262 100644 --- a/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsBehavior.ts +++ b/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsInterface.ts b/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsInterface.ts index 1e50f060a7..a0199c8d35 100644 --- a/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsInterface.ts +++ b/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsServer.ts b/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsServer.ts index a6d829b9ac..76a94f3f41 100644 --- a/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsServer.ts +++ b/packages/node/src/behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thread-network-diagnostics/index.ts b/packages/node/src/behaviors/thread-network-diagnostics/index.ts index 06238be1aa..3ac9463f4f 100644 --- a/packages/node/src/behaviors/thread-network-diagnostics/index.ts +++ b/packages/node/src/behaviors/thread-network-diagnostics/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryBehavior.ts b/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryBehavior.ts new file mode 100644 index 0000000000..aa93354943 --- /dev/null +++ b/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryBehavior.ts @@ -0,0 +1,24 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { ThreadNetworkDirectory } from "#clusters/thread-network-directory"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { ThreadNetworkDirectoryInterface } from "./ThreadNetworkDirectoryInterface.js"; + +/** + * ThreadNetworkDirectoryBehavior is the base class for objects that support interaction with {@link + * ThreadNetworkDirectory.Cluster}. + */ +export const ThreadNetworkDirectoryBehavior = ClusterBehavior + .withInterface() + .for(ThreadNetworkDirectory.Cluster); + +type ThreadNetworkDirectoryBehaviorType = InstanceType; +export interface ThreadNetworkDirectoryBehavior extends ThreadNetworkDirectoryBehaviorType {} +type StateType = InstanceType; +export namespace ThreadNetworkDirectoryBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryInterface.ts b/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryInterface.ts new file mode 100644 index 0000000000..978da5314f --- /dev/null +++ b/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryInterface.ts @@ -0,0 +1,43 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; +import { ThreadNetworkDirectory } from "#clusters/thread-network-directory"; + +export namespace ThreadNetworkDirectoryInterface { + export interface Base { + /** + * Adds an entry to the ThreadNetworks attribute with the specified Thread Operational Dataset. + * + * If there is an existing entry with the Extended PAN ID then the Thread Operational Dataset for that entry is + * replaced. As a result, changes to the network parameters (e.g. Channel, Network Name, PSKc, …) of an + * existing entry with a given Extended PAN ID can be made using this command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.1 + */ + addNetwork(request: ThreadNetworkDirectory.AddNetworkRequest): MaybePromise; + + /** + * Removes the network with the given Extended PAN ID from the ThreadNetworks attribute. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.2 + */ + removeNetwork(request: ThreadNetworkDirectory.RemoveNetworkRequest): MaybePromise; + + /** + * Retrieves the Thread Operational Dataset with the given Extended PAN ID. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.3 + */ + getOperationalDataset(request: ThreadNetworkDirectory.GetOperationalDatasetRequest): MaybePromise; + } +} + +export type ThreadNetworkDirectoryInterface = { + components: [{ flags: {}, methods: ThreadNetworkDirectoryInterface.Base }] +}; diff --git a/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryServer.ts b/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryServer.ts new file mode 100644 index 0000000000..abab76c333 --- /dev/null +++ b/packages/node/src/behaviors/thread-network-directory/ThreadNetworkDirectoryServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { ThreadNetworkDirectoryBehavior } from "./ThreadNetworkDirectoryBehavior.js"; + +/** + * This is the default server implementation of {@link ThreadNetworkDirectoryBehavior}. + */ +export class ThreadNetworkDirectoryServer extends ThreadNetworkDirectoryBehavior {} diff --git a/packages/node/src/behaviors/thread-network-directory/index.ts b/packages/node/src/behaviors/thread-network-directory/index.ts new file mode 100644 index 0000000000..466cf7d008 --- /dev/null +++ b/packages/node/src/behaviors/thread-network-directory/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./ThreadNetworkDirectoryInterface.js"; +export * from "./ThreadNetworkDirectoryBehavior.js"; +export * from "./ThreadNetworkDirectoryServer.js"; diff --git a/packages/node/src/behaviors/time-format-localization/TimeFormatLocalizationBehavior.ts b/packages/node/src/behaviors/time-format-localization/TimeFormatLocalizationBehavior.ts index 0bf27d6cb3..d63104337c 100644 --- a/packages/node/src/behaviors/time-format-localization/TimeFormatLocalizationBehavior.ts +++ b/packages/node/src/behaviors/time-format-localization/TimeFormatLocalizationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/time-format-localization/index.ts b/packages/node/src/behaviors/time-format-localization/index.ts index df81f3dc6a..709763e6cf 100644 --- a/packages/node/src/behaviors/time-format-localization/index.ts +++ b/packages/node/src/behaviors/time-format-localization/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/time-synchronization/TimeSynchronizationBehavior.ts b/packages/node/src/behaviors/time-synchronization/TimeSynchronizationBehavior.ts index ab56a46a42..971a8f6ac1 100644 --- a/packages/node/src/behaviors/time-synchronization/TimeSynchronizationBehavior.ts +++ b/packages/node/src/behaviors/time-synchronization/TimeSynchronizationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/time-synchronization/TimeSynchronizationInterface.ts b/packages/node/src/behaviors/time-synchronization/TimeSynchronizationInterface.ts index ece2402d28..3c41badb74 100644 --- a/packages/node/src/behaviors/time-synchronization/TimeSynchronizationInterface.ts +++ b/packages/node/src/behaviors/time-synchronization/TimeSynchronizationInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -16,8 +16,9 @@ export namespace TimeSynchronizationInterface { * source, it may send a Granularity of NoTimeGranularity. * * Upon receipt of this command, the node may update its UTCTime attribute to match the time specified in the - * command, if the stated Granularity and TimeSource are acceptable. The node shall update its UTCTime - * attribute if its current Granularity is NoTimeGranularity. + * command, if the stated Granularity and TimeSource are acceptable. The node shall + * + * update its UTCTime attribute if its current Granularity is NoTimeGranularity. * * If the time is updated, the node shall also update its Granularity attribute based on the granularity * specified in the command and the expected clock drift of the node. This SHOULD normally be one level lower @@ -35,11 +36,14 @@ export namespace TimeSynchronizationInterface { export interface TimeSyncClient { /** - * This command shall set the TrustedTimeSource attribute. Upon receipt of this command, * If the - * TrustedTimeSource field in the command is null, the node shall set the TrustedTimeSource attribute to null - * and shall generate a MissingTrustedTimeSource event. * Otherwise, the node shall set the TrustedTimeSource - * attribute to a struct which has NodeID and Endpoint fields matching those in the TrustedTimeSource field and - * has its FabricIndex field set to the command’s accessing fabric index. + * This command shall set the TrustedTimeSource attribute. Upon receipt of this command: + * + * • If the TrustedTimeSource field in the command is null, the node shall set the TrustedTimeSource + * attribute to null and shall generate a MissingTrustedTimeSource event. + * + * • Otherwise, the node shall set the TrustedTimeSource attribute to a struct which has NodeID and Endpoint + * fields matching those in the TrustedTimeSource field and has its FabricIndex field set to the command’s + * accessing fabric index. * * @see {@link MatterSpecification.v13.Core} § 11.17.9.2 */ @@ -85,7 +89,8 @@ export namespace TimeSynchronizationInterface { * This command is used to set the DST offsets for a node. * * • If the length of DSTOffset is larger than DSTOffsetListMaxSize, the node shall respond with - * RESOURCE_EXHAUSTED. + * + * RESOURCE_EXHAUSTED. * * • Else if the list entries do not conform to the list requirements for DSTOffset attribute, the node shall * respond with CONSTRAINT_ERROR. diff --git a/packages/node/src/behaviors/time-synchronization/TimeSynchronizationServer.ts b/packages/node/src/behaviors/time-synchronization/TimeSynchronizationServer.ts index ad54c7e3b1..e6ac5b770d 100644 --- a/packages/node/src/behaviors/time-synchronization/TimeSynchronizationServer.ts +++ b/packages/node/src/behaviors/time-synchronization/TimeSynchronizationServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/time-synchronization/index.ts b/packages/node/src/behaviors/time-synchronization/index.ts index 1f1ee2d72e..60131770f6 100644 --- a/packages/node/src/behaviors/time-synchronization/index.ts +++ b/packages/node/src/behaviors/time-synchronization/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/TotalVolatileOrganicCompoundsConcentrationMeasurementBehavior.ts b/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/TotalVolatileOrganicCompoundsConcentrationMeasurementBehavior.ts index 2917d27376..5ff69f1d00 100644 --- a/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/TotalVolatileOrganicCompoundsConcentrationMeasurementBehavior.ts +++ b/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/TotalVolatileOrganicCompoundsConcentrationMeasurementBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/TotalVolatileOrganicCompoundsConcentrationMeasurementServer.ts b/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/TotalVolatileOrganicCompoundsConcentrationMeasurementServer.ts index 7a6766e7be..c73364efdc 100644 --- a/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/TotalVolatileOrganicCompoundsConcentrationMeasurementServer.ts +++ b/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/TotalVolatileOrganicCompoundsConcentrationMeasurementServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/index.ts b/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/index.ts index 22ee1a7a59..0f27c643ee 100644 --- a/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/index.ts +++ b/packages/node/src/behaviors/total-volatile-organic-compounds-concentration-measurement/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/unit-localization/UnitLocalizationBehavior.ts b/packages/node/src/behaviors/unit-localization/UnitLocalizationBehavior.ts index 67a8cb1d0e..3e74576970 100644 --- a/packages/node/src/behaviors/unit-localization/UnitLocalizationBehavior.ts +++ b/packages/node/src/behaviors/unit-localization/UnitLocalizationBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/unit-localization/index.ts b/packages/node/src/behaviors/unit-localization/index.ts index 9ae912ae9b..196cd3f4bb 100644 --- a/packages/node/src/behaviors/unit-localization/index.ts +++ b/packages/node/src/behaviors/unit-localization/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/user-label/UserLabelBehavior.ts b/packages/node/src/behaviors/user-label/UserLabelBehavior.ts index ea40d56db1..b70592be1c 100644 --- a/packages/node/src/behaviors/user-label/UserLabelBehavior.ts +++ b/packages/node/src/behaviors/user-label/UserLabelBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/user-label/UserLabelServer.ts b/packages/node/src/behaviors/user-label/UserLabelServer.ts index 2f4ab94fd4..57bb5fd735 100644 --- a/packages/node/src/behaviors/user-label/UserLabelServer.ts +++ b/packages/node/src/behaviors/user-label/UserLabelServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/user-label/index.ts b/packages/node/src/behaviors/user-label/index.ts index 6d1358ed5e..2fa6a5133e 100644 --- a/packages/node/src/behaviors/user-label/index.ts +++ b/packages/node/src/behaviors/user-label/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/valid-proxies/ValidProxiesBehavior.ts b/packages/node/src/behaviors/valid-proxies/ValidProxiesBehavior.ts index cefeacbb8e..281c85b78a 100644 --- a/packages/node/src/behaviors/valid-proxies/ValidProxiesBehavior.ts +++ b/packages/node/src/behaviors/valid-proxies/ValidProxiesBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/valid-proxies/ValidProxiesInterface.ts b/packages/node/src/behaviors/valid-proxies/ValidProxiesInterface.ts index 4edb47165b..2597ef8234 100644 --- a/packages/node/src/behaviors/valid-proxies/ValidProxiesInterface.ts +++ b/packages/node/src/behaviors/valid-proxies/ValidProxiesInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/valid-proxies/ValidProxiesServer.ts b/packages/node/src/behaviors/valid-proxies/ValidProxiesServer.ts index bf9e6a1a9c..0e221d8b1e 100644 --- a/packages/node/src/behaviors/valid-proxies/ValidProxiesServer.ts +++ b/packages/node/src/behaviors/valid-proxies/ValidProxiesServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/valid-proxies/index.ts b/packages/node/src/behaviors/valid-proxies/index.ts index 7ed1c62709..d733f5cf22 100644 --- a/packages/node/src/behaviors/valid-proxies/index.ts +++ b/packages/node/src/behaviors/valid-proxies/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlBehavior.ts b/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlBehavior.ts index 38789170b8..f92c9effc8 100644 --- a/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlBehavior.ts +++ b/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlInterface.ts b/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlInterface.ts index c45ceefd86..b8934fdc8c 100644 --- a/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlInterface.ts +++ b/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlServer.ts b/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlServer.ts index eac5f1c1fd..7d22e14c8c 100644 --- a/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlServer.ts +++ b/packages/node/src/behaviors/valve-configuration-and-control/ValveConfigurationAndControlServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/valve-configuration-and-control/index.ts b/packages/node/src/behaviors/valve-configuration-and-control/index.ts index dc76a426fe..bb77924f6f 100644 --- a/packages/node/src/behaviors/valve-configuration-and-control/index.ts +++ b/packages/node/src/behaviors/valve-configuration-and-control/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/wake-on-lan/WakeOnLanBehavior.ts b/packages/node/src/behaviors/wake-on-lan/WakeOnLanBehavior.ts index 6b2d674864..4239a43f39 100644 --- a/packages/node/src/behaviors/wake-on-lan/WakeOnLanBehavior.ts +++ b/packages/node/src/behaviors/wake-on-lan/WakeOnLanBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/wake-on-lan/WakeOnLanServer.ts b/packages/node/src/behaviors/wake-on-lan/WakeOnLanServer.ts index 3ee79d18d8..578357fa6c 100644 --- a/packages/node/src/behaviors/wake-on-lan/WakeOnLanServer.ts +++ b/packages/node/src/behaviors/wake-on-lan/WakeOnLanServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/wake-on-lan/index.ts b/packages/node/src/behaviors/wake-on-lan/index.ts index 29d7f075a7..29ed90819e 100644 --- a/packages/node/src/behaviors/wake-on-lan/index.ts +++ b/packages/node/src/behaviors/wake-on-lan/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementBehavior.ts b/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementBehavior.ts new file mode 100644 index 0000000000..efde826474 --- /dev/null +++ b/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementBehavior.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { WaterHeaterManagement } from "#clusters/water-heater-management"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { WaterHeaterManagementInterface } from "./WaterHeaterManagementInterface.js"; + +/** + * WaterHeaterManagementBehavior is the base class for objects that support interaction with {@link + * WaterHeaterManagement.Cluster}. + * + * This class does not have optional features of WaterHeaterManagement.Cluster enabled. You can enable additional + * features using WaterHeaterManagementBehavior.with. + */ +export const WaterHeaterManagementBehavior = ClusterBehavior + .withInterface() + .for(WaterHeaterManagement.Cluster); + +type WaterHeaterManagementBehaviorType = InstanceType; +export interface WaterHeaterManagementBehavior extends WaterHeaterManagementBehaviorType {} +type StateType = InstanceType; +export namespace WaterHeaterManagementBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementInterface.ts b/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementInterface.ts new file mode 100644 index 0000000000..4476bf9bc7 --- /dev/null +++ b/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementInterface.ts @@ -0,0 +1,30 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; +import { WaterHeaterManagement } from "#clusters/water-heater-management"; + +export namespace WaterHeaterManagementInterface { + export interface Base { + /** + * Allows a client to request that the water heater is put into a Boost state. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.8.1 + */ + boost(request: WaterHeaterManagement.BoostRequest): MaybePromise; + + /** + * Allows a client to cancel an ongoing Boost operation. This command has no payload. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.8.2 + */ + cancelBoost(): MaybePromise; + } +} + +export type WaterHeaterManagementInterface = { components: [{ flags: {}, methods: WaterHeaterManagementInterface.Base }] }; diff --git a/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementServer.ts b/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementServer.ts new file mode 100644 index 0000000000..b00548514c --- /dev/null +++ b/packages/node/src/behaviors/water-heater-management/WaterHeaterManagementServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { WaterHeaterManagementBehavior } from "./WaterHeaterManagementBehavior.js"; + +/** + * This is the default server implementation of {@link WaterHeaterManagementBehavior}. + */ +export class WaterHeaterManagementServer extends WaterHeaterManagementBehavior {} diff --git a/packages/node/src/behaviors/water-heater-management/index.ts b/packages/node/src/behaviors/water-heater-management/index.ts new file mode 100644 index 0000000000..859ec91ff3 --- /dev/null +++ b/packages/node/src/behaviors/water-heater-management/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./WaterHeaterManagementInterface.js"; +export * from "./WaterHeaterManagementBehavior.js"; +export * from "./WaterHeaterManagementServer.js"; diff --git a/packages/node/src/behaviors/water-heater-mode/WaterHeaterModeBehavior.ts b/packages/node/src/behaviors/water-heater-mode/WaterHeaterModeBehavior.ts new file mode 100644 index 0000000000..e778f9bf49 --- /dev/null +++ b/packages/node/src/behaviors/water-heater-mode/WaterHeaterModeBehavior.ts @@ -0,0 +1,20 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { WaterHeaterMode } from "#clusters/water-heater-mode"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; + +/** + * WaterHeaterModeBehavior is the base class for objects that support interaction with {@link WaterHeaterMode.Cluster}. + */ +export const WaterHeaterModeBehavior = ClusterBehavior.for(WaterHeaterMode.Cluster); + +type WaterHeaterModeBehaviorType = InstanceType; +export interface WaterHeaterModeBehavior extends WaterHeaterModeBehaviorType {} +type StateType = InstanceType; +export namespace WaterHeaterModeBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/water-heater-mode/WaterHeaterModeServer.ts b/packages/node/src/behaviors/water-heater-mode/WaterHeaterModeServer.ts new file mode 100644 index 0000000000..de04d969ef --- /dev/null +++ b/packages/node/src/behaviors/water-heater-mode/WaterHeaterModeServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { WaterHeaterModeBehavior } from "./WaterHeaterModeBehavior.js"; + +/** + * This is the default server implementation of {@link WaterHeaterModeBehavior}. + */ +export class WaterHeaterModeServer extends WaterHeaterModeBehavior {} diff --git a/packages/node/src/behaviors/water-heater-mode/index.ts b/packages/node/src/behaviors/water-heater-mode/index.ts new file mode 100644 index 0000000000..193e93d03b --- /dev/null +++ b/packages/node/src/behaviors/water-heater-mode/index.ts @@ -0,0 +1,10 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./WaterHeaterModeBehavior.js"; +export * from "./WaterHeaterModeServer.js"; diff --git a/packages/node/src/behaviors/water-tank-level-monitoring/WaterTankLevelMonitoringBehavior.ts b/packages/node/src/behaviors/water-tank-level-monitoring/WaterTankLevelMonitoringBehavior.ts new file mode 100644 index 0000000000..10b9b3f246 --- /dev/null +++ b/packages/node/src/behaviors/water-tank-level-monitoring/WaterTankLevelMonitoringBehavior.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { WaterTankLevelMonitoring } from "#clusters/water-tank-level-monitoring"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { ResourceMonitoringInterface } from "../resource-monitoring/ResourceMonitoringInterface.js"; + +/** + * WaterTankLevelMonitoringBehavior is the base class for objects that support interaction with {@link + * WaterTankLevelMonitoring.Cluster}. + * + * This class does not have optional features of WaterTankLevelMonitoring.Cluster enabled. You can enable additional + * features using WaterTankLevelMonitoringBehavior.with. + */ +export const WaterTankLevelMonitoringBehavior = ClusterBehavior + .withInterface() + .for(WaterTankLevelMonitoring.Cluster); + +type WaterTankLevelMonitoringBehaviorType = InstanceType; +export interface WaterTankLevelMonitoringBehavior extends WaterTankLevelMonitoringBehaviorType {} +type StateType = InstanceType; +export namespace WaterTankLevelMonitoringBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/water-tank-level-monitoring/WaterTankLevelMonitoringServer.ts b/packages/node/src/behaviors/water-tank-level-monitoring/WaterTankLevelMonitoringServer.ts new file mode 100644 index 0000000000..cc18017be3 --- /dev/null +++ b/packages/node/src/behaviors/water-tank-level-monitoring/WaterTankLevelMonitoringServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { WaterTankLevelMonitoringBehavior } from "./WaterTankLevelMonitoringBehavior.js"; + +/** + * This is the default server implementation of {@link WaterTankLevelMonitoringBehavior}. + */ +export class WaterTankLevelMonitoringServer extends WaterTankLevelMonitoringBehavior {} diff --git a/packages/node/src/behaviors/water-tank-level-monitoring/index.ts b/packages/node/src/behaviors/water-tank-level-monitoring/index.ts new file mode 100644 index 0000000000..0944b459f2 --- /dev/null +++ b/packages/node/src/behaviors/water-tank-level-monitoring/index.ts @@ -0,0 +1,10 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./WaterTankLevelMonitoringBehavior.js"; +export * from "./WaterTankLevelMonitoringServer.js"; diff --git a/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsBehavior.ts b/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsBehavior.ts index 371abf8eee..e1609af98a 100644 --- a/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsBehavior.ts +++ b/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsInterface.ts b/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsInterface.ts index 27d978dbdb..eb811609d3 100644 --- a/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsInterface.ts +++ b/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsServer.ts b/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsServer.ts index 9fb74e2f59..4da79f3f11 100644 --- a/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsServer.ts +++ b/packages/node/src/behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsServer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/wi-fi-network-diagnostics/index.ts b/packages/node/src/behaviors/wi-fi-network-diagnostics/index.ts index 49fec3e7ed..2d7b7884e6 100644 --- a/packages/node/src/behaviors/wi-fi-network-diagnostics/index.ts +++ b/packages/node/src/behaviors/wi-fi-network-diagnostics/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementBehavior.ts b/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementBehavior.ts new file mode 100644 index 0000000000..65442db25c --- /dev/null +++ b/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementBehavior.ts @@ -0,0 +1,24 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { WiFiNetworkManagement } from "#clusters/wi-fi-network-management"; +import { ClusterBehavior } from "../../behavior/cluster/ClusterBehavior.js"; +import { WiFiNetworkManagementInterface } from "./WiFiNetworkManagementInterface.js"; + +/** + * WiFiNetworkManagementBehavior is the base class for objects that support interaction with {@link + * WiFiNetworkManagement.Cluster}. + */ +export const WiFiNetworkManagementBehavior = ClusterBehavior + .withInterface() + .for(WiFiNetworkManagement.Cluster); + +type WiFiNetworkManagementBehaviorType = InstanceType; +export interface WiFiNetworkManagementBehavior extends WiFiNetworkManagementBehaviorType {} +type StateType = InstanceType; +export namespace WiFiNetworkManagementBehavior { export interface State extends StateType {} } diff --git a/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementInterface.ts b/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementInterface.ts new file mode 100644 index 0000000000..97bbbffa98 --- /dev/null +++ b/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementInterface.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MaybePromise } from "#general"; + +export namespace WiFiNetworkManagementInterface { + export interface Base { + /** + * This command is used to request the current WPA-Personal passphrase or PSK associated with the Wi-Fi network + * provided by this device. + * + * If the command is not executed via a CASE session, the command shall be rejected with a status of + * UNSUPPORTED_ACCESS. + * + * If no primary Wi-Fi network is available (the SSID attribute is null), the command shall be rejected with a + * status of INVALID_IN_STATE. + * + * Otherwise a NetworkPassphraseResponse shall be generated. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.2.5.1 + */ + networkPassphraseRequest(): MaybePromise; + } +} + +export type WiFiNetworkManagementInterface = { components: [{ flags: {}, methods: WiFiNetworkManagementInterface.Base }] }; diff --git a/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementServer.ts b/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementServer.ts new file mode 100644 index 0000000000..4899b8be6d --- /dev/null +++ b/packages/node/src/behaviors/wi-fi-network-management/WiFiNetworkManagementServer.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +import { WiFiNetworkManagementBehavior } from "./WiFiNetworkManagementBehavior.js"; + +/** + * This is the default server implementation of {@link WiFiNetworkManagementBehavior}. + */ +export class WiFiNetworkManagementServer extends WiFiNetworkManagementBehavior {} diff --git a/packages/node/src/behaviors/wi-fi-network-management/index.ts b/packages/node/src/behaviors/wi-fi-network-management/index.ts new file mode 100644 index 0000000000..747313ead0 --- /dev/null +++ b/packages/node/src/behaviors/wi-fi-network-management/index.ts @@ -0,0 +1,11 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE WILL BE REGENERATED IF YOU DO NOT REMOVE THIS MESSAGE ***/ + +export * from "./WiFiNetworkManagementInterface.js"; +export * from "./WiFiNetworkManagementBehavior.js"; +export * from "./WiFiNetworkManagementServer.js"; diff --git a/packages/node/src/behaviors/window-covering/WindowCoveringBehavior.ts b/packages/node/src/behaviors/window-covering/WindowCoveringBehavior.ts index fd605bb4ba..d1c7e48e7c 100644 --- a/packages/node/src/behaviors/window-covering/WindowCoveringBehavior.ts +++ b/packages/node/src/behaviors/window-covering/WindowCoveringBehavior.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/window-covering/WindowCoveringInterface.ts b/packages/node/src/behaviors/window-covering/WindowCoveringInterface.ts index c40c8a68c2..39a07ace6d 100644 --- a/packages/node/src/behaviors/window-covering/WindowCoveringInterface.ts +++ b/packages/node/src/behaviors/window-covering/WindowCoveringInterface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/behaviors/window-covering/index.ts b/packages/node/src/behaviors/window-covering/index.ts index 61edc9886c..1ba89c2ec0 100644 --- a/packages/node/src/behaviors/window-covering/index.ts +++ b/packages/node/src/behaviors/window-covering/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/air-purifier.ts b/packages/node/src/devices/air-purifier.ts index cfae42eed9..4ab94be196 100644 --- a/packages/node/src/devices/air-purifier.ts +++ b/packages/node/src/devices/air-purifier.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; import { FanControlServer as BaseFanControlServer } from "../behaviors/fan-control/FanControlServer.js"; import { GroupsServer as BaseGroupsServer } from "../behaviors/groups/GroupsServer.js"; +import { OnOffServer as BaseOnOffServer } from "../behaviors/on-off/OnOffServer.js"; import { HepaFilterMonitoringServer as BaseHepaFilterMonitoringServer } from "../behaviors/hepa-filter-monitoring/HepaFilterMonitoringServer.js"; @@ -51,6 +52,13 @@ export namespace AirPurifierRequirements { */ export const GroupsServer = BaseGroupsServer; + /** + * The OnOff cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link OnOffServer} for convenience. + */ + export const OnOffServer = BaseOnOffServer; + /** * The HepaFilterMonitoring cluster is optional per the Matter specification. * @@ -71,8 +79,10 @@ export namespace AirPurifierRequirements { */ export const server = { mandatory: { Identify: IdentifyServer, FanControl: FanControlServer }, + optional: { Groups: GroupsServer, + OnOff: OnOffServer, HepaFilterMonitoring: HepaFilterMonitoringServer, ActivatedCarbonFilterMonitoring: ActivatedCarbonFilterMonitoringServer } @@ -82,7 +92,7 @@ export namespace AirPurifierRequirements { export const AirPurifierDeviceDefinition = MutableEndpoint({ name: "AirPurifier", deviceType: 0x2d, - deviceRevision: 1, + deviceRevision: 2, requirements: AirPurifierRequirements, behaviors: SupportedBehaviors( AirPurifierRequirements.server.mandatory.Identify, diff --git a/packages/node/src/devices/air-quality-sensor.ts b/packages/node/src/devices/air-quality-sensor.ts index 5583cd7792..71d1b72f74 100644 --- a/packages/node/src/devices/air-quality-sensor.ts +++ b/packages/node/src/devices/air-quality-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/basic-video-player.ts b/packages/node/src/devices/basic-video-player.ts index 723b9232b6..ae2f2e12d2 100644 --- a/packages/node/src/devices/basic-video-player.ts +++ b/packages/node/src/devices/basic-video-player.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/battery-storage.ts b/packages/node/src/devices/battery-storage.ts new file mode 100644 index 0000000000..2eb440008c --- /dev/null +++ b/packages/node/src/devices/battery-storage.ts @@ -0,0 +1,47 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A Battery Storage device is a device that allows a DC battery, which can optionally be comprised of a set parallel + * strings of battery packs and associated controller, and an AC inverter, to be monitored and controlled by an Energy + * Management System in order to manage the peaks and troughs of supply and demand, and/or to optimize cost of the + * energy consumed in premises. It is not intended to be used for a UPS directly supplying a set of appliances, nor for + * portable battery storage devices. + * + * @see {@link MatterSpecification.v13.Device} § 14.4 + */ +export interface BatteryStorageDevice extends Identity {} + +export namespace BatteryStorageRequirements { + /** + * The Identify cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link IdentifyServer} for convenience. + */ + export const IdentifyServer = BaseIdentifyServer; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { optional: { Identify: IdentifyServer }, mandatory: {} }; +} + +export const BatteryStorageDeviceDefinition = MutableEndpoint({ + name: "BatteryStorage", + deviceType: 0x18, + deviceRevision: 1, + requirements: BatteryStorageRequirements, + behaviors: SupportedBehaviors() +}); + +export const BatteryStorageDevice: BatteryStorageDevice = BatteryStorageDeviceDefinition; diff --git a/packages/node/src/devices/casting-video-client.ts b/packages/node/src/devices/casting-video-client.ts index 1a96657e77..c84574e76b 100644 --- a/packages/node/src/devices/casting-video-client.ts +++ b/packages/node/src/devices/casting-video-client.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/casting-video-player.ts b/packages/node/src/devices/casting-video-player.ts index 37036152eb..0b9f76a946 100644 --- a/packages/node/src/devices/casting-video-player.ts +++ b/packages/node/src/devices/casting-video-player.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/color-dimmer-switch.ts b/packages/node/src/devices/color-dimmer-switch.ts index df2f00dbb2..9b8b88496e 100644 --- a/packages/node/src/devices/color-dimmer-switch.ts +++ b/packages/node/src/devices/color-dimmer-switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/color-temperature-light.ts b/packages/node/src/devices/color-temperature-light.ts index 5660b683d4..7c51afe704 100644 --- a/packages/node/src/devices/color-temperature-light.ts +++ b/packages/node/src/devices/color-temperature-light.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/contact-sensor.ts b/packages/node/src/devices/contact-sensor.ts index f2a7810456..19ab21471e 100644 --- a/packages/node/src/devices/contact-sensor.ts +++ b/packages/node/src/devices/contact-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/content-app.ts b/packages/node/src/devices/content-app.ts index b0966489fb..0e70711d7c 100644 --- a/packages/node/src/devices/content-app.ts +++ b/packages/node/src/devices/content-app.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/control-bridge.ts b/packages/node/src/devices/control-bridge.ts index efe5c54dd3..9b827ab9df 100644 --- a/packages/node/src/devices/control-bridge.ts +++ b/packages/node/src/devices/control-bridge.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/cook-surface.ts b/packages/node/src/devices/cook-surface.ts index 3a1017a891..d554fc9f9e 100644 --- a/packages/node/src/devices/cook-surface.ts +++ b/packages/node/src/devices/cook-surface.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/cooktop.ts b/packages/node/src/devices/cooktop.ts index 92392909d3..f5104b6992 100644 --- a/packages/node/src/devices/cooktop.ts +++ b/packages/node/src/devices/cooktop.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/dimmable-light.ts b/packages/node/src/devices/dimmable-light.ts index bee84d1b68..aefb7fec2c 100644 --- a/packages/node/src/devices/dimmable-light.ts +++ b/packages/node/src/devices/dimmable-light.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/dimmable-plug-in-unit.ts b/packages/node/src/devices/dimmable-plug-in-unit.ts index c8fb1ff9e8..85b1a7ca47 100644 --- a/packages/node/src/devices/dimmable-plug-in-unit.ts +++ b/packages/node/src/devices/dimmable-plug-in-unit.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/dimmer-switch.ts b/packages/node/src/devices/dimmer-switch.ts index 149cf8053e..e88b237c8e 100644 --- a/packages/node/src/devices/dimmer-switch.ts +++ b/packages/node/src/devices/dimmer-switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/dishwasher.ts b/packages/node/src/devices/dishwasher.ts index 12a1b744b3..8b435d58f7 100644 --- a/packages/node/src/devices/dishwasher.ts +++ b/packages/node/src/devices/dishwasher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/door-lock-controller.ts b/packages/node/src/devices/door-lock-controller.ts index 08e293e9c7..bce69a7228 100644 --- a/packages/node/src/devices/door-lock-controller.ts +++ b/packages/node/src/devices/door-lock-controller.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/door-lock.ts b/packages/node/src/devices/door-lock.ts index 30043eec99..f9678e506b 100644 --- a/packages/node/src/devices/door-lock.ts +++ b/packages/node/src/devices/door-lock.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/energy-evse.ts b/packages/node/src/devices/energy-evse.ts new file mode 100644 index 0000000000..670778fede --- /dev/null +++ b/packages/node/src/devices/energy-evse.ts @@ -0,0 +1,77 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { EnergyEvseServer as BaseEnergyEvseServer } from "../behaviors/energy-evse/EnergyEvseServer.js"; +import { EnergyEvseModeServer as BaseEnergyEvseModeServer } from "../behaviors/energy-evse-mode/EnergyEvseModeServer.js"; +import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; +import { + TemperatureMeasurementServer as BaseTemperatureMeasurementServer +} from "../behaviors/temperature-measurement/TemperatureMeasurementServer.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * An EVSE (Electric Vehicle Supply Equipment) is a device that allows an EV (Electric Vehicle) to be connected to the + * mains electricity supply to allow it to be charged (or discharged in case of Vehicle to Grid / Vehicle to Home + * applications). + * + * @see {@link MatterSpecification.v13.Device} § 14.1 + */ +export interface EnergyEvseDevice extends Identity {} + +export namespace EnergyEvseRequirements { + /** + * The EnergyEvse cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link EnergyEvseServer} for convenience. + */ + export const EnergyEvseServer = BaseEnergyEvseServer; + + /** + * The EnergyEvseMode cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link EnergyEvseModeServer} for convenience. + */ + export const EnergyEvseModeServer = BaseEnergyEvseModeServer; + + /** + * The Identify cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link IdentifyServer} for convenience. + */ + export const IdentifyServer = BaseIdentifyServer; + + /** + * The TemperatureMeasurement cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link TemperatureMeasurementServer} for convenience. + */ + export const TemperatureMeasurementServer = BaseTemperatureMeasurementServer; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { + mandatory: { EnergyEvse: EnergyEvseServer, EnergyEvseMode: EnergyEvseModeServer }, + optional: { Identify: IdentifyServer, TemperatureMeasurement: TemperatureMeasurementServer } + }; +} + +export const EnergyEvseDeviceDefinition = MutableEndpoint({ + name: "EnergyEvse", + deviceType: 0x50c, + deviceRevision: 2, + requirements: EnergyEvseRequirements, + behaviors: SupportedBehaviors( + EnergyEvseRequirements.server.mandatory.EnergyEvse, + EnergyEvseRequirements.server.mandatory.EnergyEvseMode + ) +}); + +export const EnergyEvseDevice: EnergyEvseDevice = EnergyEvseDeviceDefinition; diff --git a/packages/node/src/devices/extended-color-light.ts b/packages/node/src/devices/extended-color-light.ts index 8092fae47d..8a0a1a9ad6 100644 --- a/packages/node/src/devices/extended-color-light.ts +++ b/packages/node/src/devices/extended-color-light.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/extractor-hood.ts b/packages/node/src/devices/extractor-hood.ts index 925af73266..2e033fd66a 100644 --- a/packages/node/src/devices/extractor-hood.ts +++ b/packages/node/src/devices/extractor-hood.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/fan.ts b/packages/node/src/devices/fan.ts index f74b1977d4..bcaf311a3e 100644 --- a/packages/node/src/devices/fan.ts +++ b/packages/node/src/devices/fan.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; import { GroupsServer as BaseGroupsServer } from "../behaviors/groups/GroupsServer.js"; import { FanControlServer as BaseFanControlServer } from "../behaviors/fan-control/FanControlServer.js"; +import { OnOffServer as BaseOnOffServer } from "../behaviors/on-off/OnOffServer.js"; import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; import { Identity } from "#general"; @@ -42,16 +43,26 @@ export namespace FanRequirements { */ export const FanControlServer = BaseFanControlServer; + /** + * The OnOff cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link OnOffServer} for convenience. + */ + export const OnOffServer = BaseOnOffServer; + /** * An implementation for each server cluster supported by the endpoint per the Matter specification. */ - export const server = { mandatory: { Identify: IdentifyServer, Groups: GroupsServer, FanControl: FanControlServer } }; + export const server = { + mandatory: { Identify: IdentifyServer, Groups: GroupsServer, FanControl: FanControlServer }, + optional: { OnOff: OnOffServer } + }; } export const FanDeviceDefinition = MutableEndpoint({ name: "Fan", deviceType: 0x2b, - deviceRevision: 2, + deviceRevision: 3, requirements: FanRequirements, behaviors: SupportedBehaviors( FanRequirements.server.mandatory.Identify, diff --git a/packages/node/src/devices/flow-sensor.ts b/packages/node/src/devices/flow-sensor.ts index 0bc8e25230..7f359c26db 100644 --- a/packages/node/src/devices/flow-sensor.ts +++ b/packages/node/src/devices/flow-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/generic-switch.ts b/packages/node/src/devices/generic-switch.ts index b91dbd520f..3f595792d4 100644 --- a/packages/node/src/devices/generic-switch.ts +++ b/packages/node/src/devices/generic-switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/heat-pump.ts b/packages/node/src/devices/heat-pump.ts new file mode 100644 index 0000000000..bdf1122319 --- /dev/null +++ b/packages/node/src/devices/heat-pump.ts @@ -0,0 +1,61 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; +import { ThermostatBehavior as BaseThermostatBehavior } from "../behaviors/thermostat/ThermostatBehavior.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A Heat Pump device is a device that uses electrical energy to heat either spaces or water tanks using ground, water + * or air as the heat source. These typically can heat the air or can pump water via central heating radiators or + * underfloor heating systems. It is typical to also heat hot water and store the heat in a hot water tank. + * + * Note that the Water Heater device type can also be heated by a heat pump and has similar requirements, but that + * cannot be used for space heating. + * + * @see {@link MatterSpecification.v13.Device} § 14.5 + */ +export interface HeatPumpDevice extends Identity {} + +export namespace HeatPumpRequirements { + /** + * The Identify cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link IdentifyServer} for convenience. + */ + export const IdentifyServer = BaseIdentifyServer; + + /** + * The Thermostat cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link ThermostatBehavior} for convenience. + */ + export const ThermostatBehavior = BaseThermostatBehavior; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { optional: { Identify: IdentifyServer }, mandatory: {} }; + + /** + * A definition for each client cluster supported by the endpoint per the Matter specification. + */ + export const client = { optional: { Thermostat: ThermostatBehavior }, mandatory: {} }; +} + +export const HeatPumpDeviceDefinition = MutableEndpoint({ + name: "HeatPump", + deviceType: 0x309, + deviceRevision: 1, + requirements: HeatPumpRequirements, + behaviors: SupportedBehaviors() +}); + +export const HeatPumpDevice: HeatPumpDevice = HeatPumpDeviceDefinition; diff --git a/packages/node/src/devices/humidity-sensor.ts b/packages/node/src/devices/humidity-sensor.ts index 2a17f68078..6d1c14f653 100644 --- a/packages/node/src/devices/humidity-sensor.ts +++ b/packages/node/src/devices/humidity-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/index.ts b/packages/node/src/devices/index.ts index 96f58190db..33ea8b49f5 100644 --- a/packages/node/src/devices/index.ts +++ b/packages/node/src/devices/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ export * from "./air-purifier.js"; export * from "./air-quality-sensor.js"; export * from "./basic-video-player.js"; +export * from "./battery-storage.js"; export * from "./casting-video-client.js"; export * from "./casting-video-player.js"; export * from "./color-dimmer-switch.js"; @@ -24,17 +25,22 @@ export * from "./dimmer-switch.js"; export * from "./dishwasher.js"; export * from "./door-lock-controller.js"; export * from "./door-lock.js"; +export * from "./energy-evse.js"; export * from "./extended-color-light.js"; export * from "./extractor-hood.js"; export * from "./fan.js"; export * from "./flow-sensor.js"; export * from "./generic-switch.js"; +export * from "./heat-pump.js"; export * from "./humidity-sensor.js"; export * from "./laundry-dryer.js"; export * from "./laundry-washer.js"; export * from "./light-sensor.js"; export * from "./microwave-oven.js"; export * from "./mode-select.js"; +export * from "./mounted-dimmable-load-control.js"; +export * from "./mounted-on-off-control.js"; +export * from "./network-infrastructure-manager.js"; export * from "./occupancy-sensor.js"; export * from "./on-off-light.js"; export * from "./on-off-light-switch.js"; @@ -49,12 +55,14 @@ export * from "./refrigerator.js"; export * from "./robotic-vacuum-cleaner.js"; export * from "./room-air-conditioner.js"; export * from "./smoke-co-alarm.js"; +export * from "./solar-power.js"; export * from "./speaker.js"; export * from "./temperature-controlled-cabinet.js"; export * from "./temperature-sensor.js"; export * from "./thermostat.js"; export * from "./video-remote-control.js"; export * from "./water-freeze-detector.js"; +export * from "./water-heater.js"; export * from "./water-leak-detector.js"; export * from "./water-valve.js"; export * from "./window-covering-controller.js"; diff --git a/packages/node/src/devices/laundry-dryer.ts b/packages/node/src/devices/laundry-dryer.ts index 25a24fe654..c46fa3b6c5 100644 --- a/packages/node/src/devices/laundry-dryer.ts +++ b/packages/node/src/devices/laundry-dryer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/laundry-washer.ts b/packages/node/src/devices/laundry-washer.ts index bfeb4f3e1a..252cc90f43 100644 --- a/packages/node/src/devices/laundry-washer.ts +++ b/packages/node/src/devices/laundry-washer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/light-sensor.ts b/packages/node/src/devices/light-sensor.ts index 734136e377..32903912f5 100644 --- a/packages/node/src/devices/light-sensor.ts +++ b/packages/node/src/devices/light-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/microwave-oven.ts b/packages/node/src/devices/microwave-oven.ts index bd7ef2a024..87dbce11ae 100644 --- a/packages/node/src/devices/microwave-oven.ts +++ b/packages/node/src/devices/microwave-oven.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/mode-select.ts b/packages/node/src/devices/mode-select.ts index f31f7319a2..68b3caefb2 100644 --- a/packages/node/src/devices/mode-select.ts +++ b/packages/node/src/devices/mode-select.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/mounted-dimmable-load-control.ts b/packages/node/src/devices/mounted-dimmable-load-control.ts new file mode 100644 index 0000000000..45b1ca7047 --- /dev/null +++ b/packages/node/src/devices/mounted-dimmable-load-control.ts @@ -0,0 +1,117 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; +import { GroupsServer as BaseGroupsServer } from "../behaviors/groups/GroupsServer.js"; +import { OnOffServer as BaseOnOffServer } from "../behaviors/on-off/OnOffServer.js"; +import { LevelControlServer as BaseLevelControlServer } from "../behaviors/level-control/LevelControlServer.js"; +import { + ScenesManagementServer as BaseScenesManagementServer +} from "../behaviors/scenes-management/ScenesManagementServer.js"; +import { + OccupancySensingBehavior as BaseOccupancySensingBehavior +} from "../behaviors/occupancy-sensing/OccupancySensingBehavior.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A Mounted Dimmable Load Control is a fixed device that provides power to another device that is plugged into it, and + * is capable of being switched on or off and have its level adjusted. The Mounted Dimmable Load Control is typically + * used to control a conventional non-communicating light through its mains connection using phase cutting. + * + * @see {@link MatterSpecification.v13.Device} § 5.4 + */ +export interface MountedDimmableLoadControlDevice extends Identity {} + +export namespace MountedDimmableLoadControlRequirements { + /** + * The Identify cluster is required by the Matter specification. + * + * This version of {@link IdentifyServer} is specialized per the specification. + */ + export const IdentifyServer = BaseIdentifyServer.alter({ commands: { triggerEffect: { optional: false } } }); + + /** + * The Groups cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link GroupsServer} for convenience. + */ + export const GroupsServer = BaseGroupsServer; + + /** + * The OnOff cluster is required by the Matter specification. + * + * This version of {@link OnOffServer} is specialized per the specification. + */ + export const OnOffServer = BaseOnOffServer.with("Lighting"); + + /** + * The LevelControl cluster is required by the Matter specification. + * + * This version of {@link LevelControlServer} is specialized per the specification. + */ + export const LevelControlServer = BaseLevelControlServer + .with("OnOff", "Lighting") + .alter({ + attributes: { + currentLevel: { min: 1, max: 254 }, + minLevel: { default: 1, min: 1, max: 2 }, + maxLevel: { default: 254, min: 254, max: 255 } + } + }); + + /** + * The ScenesManagement cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link ScenesManagementServer} for convenience. + */ + export const ScenesManagementServer = BaseScenesManagementServer; + + /** + * The OccupancySensing cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link OccupancySensingBehavior} for convenience. + */ + export const OccupancySensingBehavior = BaseOccupancySensingBehavior; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { + mandatory: { + Identify: IdentifyServer, + Groups: GroupsServer, + OnOff: OnOffServer, + LevelControl: LevelControlServer + }, + + optional: { ScenesManagement: ScenesManagementServer } + }; + + /** + * A definition for each client cluster supported by the endpoint per the Matter specification. + */ + export const client = { optional: { OccupancySensing: OccupancySensingBehavior }, mandatory: {} }; +} + +export const MountedDimmableLoadControlDeviceDefinition = MutableEndpoint({ + name: "MountedDimmableLoadControl", + deviceType: 0x110, + deviceRevision: 1, + requirements: MountedDimmableLoadControlRequirements, + + behaviors: SupportedBehaviors( + MountedDimmableLoadControlRequirements.server.mandatory.Identify, + MountedDimmableLoadControlRequirements.server.mandatory.Groups, + MountedDimmableLoadControlRequirements.server.mandatory.OnOff, + MountedDimmableLoadControlRequirements.server.mandatory.LevelControl + ) +}); + +export const MountedDimmableLoadControlDevice: MountedDimmableLoadControlDevice = MountedDimmableLoadControlDeviceDefinition; diff --git a/packages/node/src/devices/mounted-on-off-control.ts b/packages/node/src/devices/mounted-on-off-control.ts new file mode 100644 index 0000000000..4fc4c08d86 --- /dev/null +++ b/packages/node/src/devices/mounted-on-off-control.ts @@ -0,0 +1,108 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; +import { GroupsServer as BaseGroupsServer } from "../behaviors/groups/GroupsServer.js"; +import { OnOffServer as BaseOnOffServer } from "../behaviors/on-off/OnOffServer.js"; +import { + ScenesManagementServer as BaseScenesManagementServer +} from "../behaviors/scenes-management/ScenesManagementServer.js"; +import { LevelControlServer as BaseLevelControlServer } from "../behaviors/level-control/LevelControlServer.js"; +import { + OccupancySensingBehavior as BaseOccupancySensingBehavior +} from "../behaviors/occupancy-sensing/OccupancySensingBehavior.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A Mounted On/Off Control is a fixed device that provides power to another device that is plugged into it, and is + * capable of switching that provided power on or off. + * + * @see {@link MatterSpecification.v13.Device} § 5.3 + */ +export interface MountedOnOffControlDevice extends Identity {} + +export namespace MountedOnOffControlRequirements { + /** + * The Identify cluster is required by the Matter specification. + * + * This version of {@link IdentifyServer} is specialized per the specification. + */ + export const IdentifyServer = BaseIdentifyServer.alter({ commands: { triggerEffect: { optional: false } } }); + + /** + * The Groups cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link GroupsServer} for convenience. + */ + export const GroupsServer = BaseGroupsServer; + + /** + * The OnOff cluster is required by the Matter specification. + * + * This version of {@link OnOffServer} is specialized per the specification. + */ + export const OnOffServer = BaseOnOffServer.with("Lighting"); + + /** + * The ScenesManagement cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link ScenesManagementServer} for convenience. + */ + export const ScenesManagementServer = BaseScenesManagementServer; + + /** + * The LevelControl cluster is optional per the Matter specification. + * + * This version of {@link LevelControlServer} is specialized per the specification. + */ + export const LevelControlServer = BaseLevelControlServer + .with("OnOff", "Lighting") + .alter({ + attributes: { + currentLevel: { min: 1, max: 254 }, + minLevel: { default: 1, min: 1, max: 2 }, + maxLevel: { default: 254, min: 254, max: 255 } + } + }); + + /** + * The OccupancySensing cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link OccupancySensingBehavior} for convenience. + */ + export const OccupancySensingBehavior = BaseOccupancySensingBehavior; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { + mandatory: { Identify: IdentifyServer, Groups: GroupsServer, OnOff: OnOffServer }, + optional: { ScenesManagement: ScenesManagementServer, LevelControl: LevelControlServer } + }; + + /** + * A definition for each client cluster supported by the endpoint per the Matter specification. + */ + export const client = { optional: { OccupancySensing: OccupancySensingBehavior }, mandatory: {} }; +} + +export const MountedOnOffControlDeviceDefinition = MutableEndpoint({ + name: "MountedOnOffControl", + deviceType: 0x10f, + deviceRevision: 1, + requirements: MountedOnOffControlRequirements, + behaviors: SupportedBehaviors( + MountedOnOffControlRequirements.server.mandatory.Identify, + MountedOnOffControlRequirements.server.mandatory.Groups, + MountedOnOffControlRequirements.server.mandatory.OnOff + ) +}); + +export const MountedOnOffControlDevice: MountedOnOffControlDevice = MountedOnOffControlDeviceDefinition; diff --git a/packages/node/src/devices/network-infrastructure-manager.ts b/packages/node/src/devices/network-infrastructure-manager.ts new file mode 100644 index 0000000000..ce2f084d6e --- /dev/null +++ b/packages/node/src/devices/network-infrastructure-manager.ts @@ -0,0 +1,87 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { + WiFiNetworkManagementServer as BaseWiFiNetworkManagementServer +} from "../behaviors/wi-fi-network-management/WiFiNetworkManagementServer.js"; +import { + ThreadBorderRouterManagementServer as BaseThreadBorderRouterManagementServer +} from "../behaviors/thread-border-router-management/ThreadBorderRouterManagementServer.js"; +import { + ThreadNetworkDirectoryServer as BaseThreadNetworkDirectoryServer +} from "../behaviors/thread-network-directory/ThreadNetworkDirectoryServer.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A Network Infrastructure Manager provides interfaces that allow for the management of the Wi-Fi, Thread, and + * Ethernet networks underlying a Matter deployment, realizing the Star Network Topology described in [MatterCore]. + * + * Examples of physical devices that implement the Matter Network Infrastructure Manager device type include Wi-Fi + * gateway routers. + * + * Relevant hardware and software requirements for Network Infrastructure Manager devices are defined in Section + * 15.2.6, “Other Requirements” and within the clusters mandated by this device type. + * + * A Network Infrastructure Manager device may be managed by a service associated with the device vendor, for example, + * an Internet Service Provider. Sometimes this managing service will have policies that require the use of the Managed + * Device feature of the Access Control Cluster (see Section 15.2.5.1, “Access Control MNGD Conformance”). + * Consequently, Commissioners of this device type should be aware of this feature and its use. + * + * @see {@link MatterSpecification.v13.Device} § 15.2 + */ +export interface NetworkInfrastructureManagerDevice extends Identity {} + +export namespace NetworkInfrastructureManagerRequirements { + /** + * The WiFiNetworkManagement cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link WiFiNetworkManagementServer} for convenience. + */ + export const WiFiNetworkManagementServer = BaseWiFiNetworkManagementServer; + + /** + * The ThreadBorderRouterManagement cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link ThreadBorderRouterManagementServer} for convenience. + */ + export const ThreadBorderRouterManagementServer = BaseThreadBorderRouterManagementServer; + + /** + * The ThreadNetworkDirectory cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link ThreadNetworkDirectoryServer} for convenience. + */ + export const ThreadNetworkDirectoryServer = BaseThreadNetworkDirectoryServer; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { + mandatory: { + WiFiNetworkManagement: WiFiNetworkManagementServer, + ThreadBorderRouterManagement: ThreadBorderRouterManagementServer, + ThreadNetworkDirectory: ThreadNetworkDirectoryServer + } + }; +} + +export const NetworkInfrastructureManagerDeviceDefinition = MutableEndpoint({ + name: "NetworkInfrastructureManager", + deviceType: 0x90, + deviceRevision: 1, + requirements: NetworkInfrastructureManagerRequirements, + behaviors: SupportedBehaviors( + NetworkInfrastructureManagerRequirements.server.mandatory.WiFiNetworkManagement, + NetworkInfrastructureManagerRequirements.server.mandatory.ThreadBorderRouterManagement, + NetworkInfrastructureManagerRequirements.server.mandatory.ThreadNetworkDirectory + ) +}); + +export const NetworkInfrastructureManagerDevice: NetworkInfrastructureManagerDevice = NetworkInfrastructureManagerDeviceDefinition; diff --git a/packages/node/src/devices/occupancy-sensor.ts b/packages/node/src/devices/occupancy-sensor.ts index 5a2d91a93f..b9defedd8e 100644 --- a/packages/node/src/devices/occupancy-sensor.ts +++ b/packages/node/src/devices/occupancy-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,6 +10,9 @@ import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/Iden import { OccupancySensingServer as BaseOccupancySensingServer } from "../behaviors/occupancy-sensing/OccupancySensingServer.js"; +import { + BooleanStateConfigurationServer as BaseBooleanStateConfigurationServer +} from "../behaviors/boolean-state-configuration/BooleanStateConfigurationServer.js"; import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; import { Identity } from "#general"; @@ -18,6 +21,9 @@ import { Identity } from "#general"; * An Occupancy Sensor is a measurement and sensing device that is capable of measuring and reporting the occupancy * state in a designated area. * + * OccupancySensorDevice requires OccupancySensing cluster but OccupancySensing is not added by default because you + * must select the features your device supports. You can add manually using OccupancySensorDevice.with(). + * * @see {@link MatterSpecification.v13.Device} § 7.3 */ export interface OccupancySensorDevice extends Identity {} @@ -37,21 +43,28 @@ export namespace OccupancySensorRequirements { */ export const OccupancySensingServer = BaseOccupancySensingServer; + /** + * The BooleanStateConfiguration cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link BooleanStateConfigurationServer} for convenience. + */ + export const BooleanStateConfigurationServer = BaseBooleanStateConfigurationServer; + /** * An implementation for each server cluster supported by the endpoint per the Matter specification. */ - export const server = { mandatory: { Identify: IdentifyServer, OccupancySensing: OccupancySensingServer } }; + export const server = { + mandatory: { Identify: IdentifyServer, OccupancySensing: OccupancySensingServer }, + optional: { BooleanStateConfiguration: BooleanStateConfigurationServer } + }; } export const OccupancySensorDeviceDefinition = MutableEndpoint({ name: "OccupancySensor", deviceType: 0x107, - deviceRevision: 3, + deviceRevision: 4, requirements: OccupancySensorRequirements, - behaviors: SupportedBehaviors( - OccupancySensorRequirements.server.mandatory.Identify, - OccupancySensorRequirements.server.mandatory.OccupancySensing - ) + behaviors: SupportedBehaviors(OccupancySensorRequirements.server.mandatory.Identify) }); export const OccupancySensorDevice: OccupancySensorDevice = OccupancySensorDeviceDefinition; diff --git a/packages/node/src/devices/on-off-light-switch.ts b/packages/node/src/devices/on-off-light-switch.ts index b3a51517bd..f411d7ba2a 100644 --- a/packages/node/src/devices/on-off-light-switch.ts +++ b/packages/node/src/devices/on-off-light-switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/on-off-light.ts b/packages/node/src/devices/on-off-light.ts index 2c9e49a2ed..31e272be64 100644 --- a/packages/node/src/devices/on-off-light.ts +++ b/packages/node/src/devices/on-off-light.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/on-off-plug-in-unit.ts b/packages/node/src/devices/on-off-plug-in-unit.ts index fb6532e05a..401b9a4165 100644 --- a/packages/node/src/devices/on-off-plug-in-unit.ts +++ b/packages/node/src/devices/on-off-plug-in-unit.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/on-off-sensor.ts b/packages/node/src/devices/on-off-sensor.ts index 1ae857cd89..81a14549be 100644 --- a/packages/node/src/devices/on-off-sensor.ts +++ b/packages/node/src/devices/on-off-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/oven.ts b/packages/node/src/devices/oven.ts index 688721ad58..e4a95520eb 100644 --- a/packages/node/src/devices/oven.ts +++ b/packages/node/src/devices/oven.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -37,7 +37,7 @@ export namespace OvenRequirements { export const OvenDeviceDefinition = MutableEndpoint({ name: "Oven", deviceType: 0x7b, - deviceRevision: 1, + deviceRevision: 2, requirements: OvenRequirements, behaviors: SupportedBehaviors() }); diff --git a/packages/node/src/devices/pressure-sensor.ts b/packages/node/src/devices/pressure-sensor.ts index 1dc33cd947..2c444cfa30 100644 --- a/packages/node/src/devices/pressure-sensor.ts +++ b/packages/node/src/devices/pressure-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/pump-controller.ts b/packages/node/src/devices/pump-controller.ts index 00d35ab929..bd3d2d1f21 100644 --- a/packages/node/src/devices/pump-controller.ts +++ b/packages/node/src/devices/pump-controller.ts @@ -1,13 +1,12 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; -import { BindingBehavior as BaseBindingBehavior } from "../behaviors/binding/BindingBehavior.js"; import { OnOffBehavior as BaseOnOffBehavior } from "../behaviors/on-off/OnOffBehavior.js"; import { PumpConfigurationAndControlBehavior as BasePumpConfigurationAndControlBehavior @@ -46,13 +45,6 @@ export namespace PumpControllerRequirements { */ export const IdentifyServer = BaseIdentifyServer; - /** - * The Binding cluster is required by the Matter specification. - * - * We provide this alias to the default implementation {@link BindingBehavior} for convenience. - */ - export const BindingBehavior = BaseBindingBehavior; - /** * The OnOff cluster is required by the Matter specification. * @@ -125,11 +117,7 @@ export namespace PumpControllerRequirements { * A definition for each client cluster supported by the endpoint per the Matter specification. */ export const client = { - mandatory: { - Binding: BindingBehavior, - OnOff: OnOffBehavior, - PumpConfigurationAndControl: PumpConfigurationAndControlBehavior - }, + mandatory: { OnOff: OnOffBehavior, PumpConfigurationAndControl: PumpConfigurationAndControlBehavior }, optional: { Identify: IdentifyBehavior, @@ -146,7 +134,7 @@ export namespace PumpControllerRequirements { export const PumpControllerDeviceDefinition = MutableEndpoint({ name: "PumpController", deviceType: 0x304, - deviceRevision: 3, + deviceRevision: 4, requirements: PumpControllerRequirements, behaviors: SupportedBehaviors(PumpControllerRequirements.server.mandatory.Identify) }); diff --git a/packages/node/src/devices/pump.ts b/packages/node/src/devices/pump.ts index 302a6bf7cb..d789186eab 100644 --- a/packages/node/src/devices/pump.ts +++ b/packages/node/src/devices/pump.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -46,7 +46,7 @@ import { Identity } from "#general"; * PumpDevice requires PumpConfigurationAndControl cluster but PumpConfigurationAndControl is not added by default * because you must select the features your device supports. You can add manually using PumpDevice.with(). * - * @see {@link MatterSpecification.v13.Device} § 5.3 + * @see {@link MatterSpecification.v13.Device} § 5.5 */ export interface PumpDevice extends Identity {} diff --git a/packages/node/src/devices/rain-sensor.ts b/packages/node/src/devices/rain-sensor.ts index dba56cc0d0..73f92b9b54 100644 --- a/packages/node/src/devices/rain-sensor.ts +++ b/packages/node/src/devices/rain-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/refrigerator.ts b/packages/node/src/devices/refrigerator.ts index 9599edc7f2..cc2b851706 100644 --- a/packages/node/src/devices/refrigerator.ts +++ b/packages/node/src/devices/refrigerator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -65,7 +65,7 @@ export namespace RefrigeratorRequirements { export const RefrigeratorDeviceDefinition = MutableEndpoint({ name: "Refrigerator", deviceType: 0x70, - deviceRevision: 1, + deviceRevision: 2, requirements: RefrigeratorRequirements, behaviors: SupportedBehaviors() }); diff --git a/packages/node/src/devices/robotic-vacuum-cleaner.ts b/packages/node/src/devices/robotic-vacuum-cleaner.ts index d2f4155516..0e27649c27 100644 --- a/packages/node/src/devices/robotic-vacuum-cleaner.ts +++ b/packages/node/src/devices/robotic-vacuum-cleaner.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,6 +12,7 @@ import { RvcOperationalStateServer as BaseRvcOperationalStateServer } from "../behaviors/rvc-operational-state/RvcOperationalStateServer.js"; import { RvcCleanModeServer as BaseRvcCleanModeServer } from "../behaviors/rvc-clean-mode/RvcCleanModeServer.js"; +import { ServiceAreaServer as BaseServiceAreaServer } from "../behaviors/service-area/ServiceAreaServer.js"; import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; import { Identity } from "#general"; @@ -52,6 +53,13 @@ export namespace RoboticVacuumCleanerRequirements { */ export const RvcCleanModeServer = BaseRvcCleanModeServer; + /** + * The ServiceArea cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link ServiceAreaServer} for convenience. + */ + export const ServiceAreaServer = BaseServiceAreaServer; + /** * An implementation for each server cluster supported by the endpoint per the Matter specification. */ @@ -61,14 +69,14 @@ export namespace RoboticVacuumCleanerRequirements { RvcRunMode: RvcRunModeServer, RvcOperationalState: RvcOperationalStateServer }, - optional: { RvcCleanMode: RvcCleanModeServer } + optional: { RvcCleanMode: RvcCleanModeServer, ServiceArea: ServiceAreaServer } }; } export const RoboticVacuumCleanerDeviceDefinition = MutableEndpoint({ name: "RoboticVacuumCleaner", deviceType: 0x74, - deviceRevision: 2, + deviceRevision: 3, requirements: RoboticVacuumCleanerRequirements, behaviors: SupportedBehaviors( RoboticVacuumCleanerRequirements.server.mandatory.Identify, diff --git a/packages/node/src/devices/room-air-conditioner.ts b/packages/node/src/devices/room-air-conditioner.ts index 0d0c7f2b18..fe5647a421 100644 --- a/packages/node/src/devices/room-air-conditioner.ts +++ b/packages/node/src/devices/room-air-conditioner.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/smoke-co-alarm.ts b/packages/node/src/devices/smoke-co-alarm.ts index 783c2f85e1..d49176c2ae 100644 --- a/packages/node/src/devices/smoke-co-alarm.ts +++ b/packages/node/src/devices/smoke-co-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/solar-power.ts b/packages/node/src/devices/solar-power.ts new file mode 100644 index 0000000000..2fb762c705 --- /dev/null +++ b/packages/node/src/devices/solar-power.ts @@ -0,0 +1,45 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A Solar Power device is a device that allows a solar panel array, which can optionally be comprised of a set + * parallel strings of solar panels, and its associated controller and, if appropriate, inverter, to be monitored and + * controlled by an Energy Management System. + * + * @see {@link MatterSpecification.v13.Device} § 14.3 + */ +export interface SolarPowerDevice extends Identity {} + +export namespace SolarPowerRequirements { + /** + * The Identify cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link IdentifyServer} for convenience. + */ + export const IdentifyServer = BaseIdentifyServer; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { optional: { Identify: IdentifyServer }, mandatory: {} }; +} + +export const SolarPowerDeviceDefinition = MutableEndpoint({ + name: "SolarPower", + deviceType: 0x17, + deviceRevision: 1, + requirements: SolarPowerRequirements, + behaviors: SupportedBehaviors() +}); + +export const SolarPowerDevice: SolarPowerDevice = SolarPowerDeviceDefinition; diff --git a/packages/node/src/devices/speaker.ts b/packages/node/src/devices/speaker.ts index eb634abd81..db74d9ac80 100644 --- a/packages/node/src/devices/speaker.ts +++ b/packages/node/src/devices/speaker.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/temperature-controlled-cabinet.ts b/packages/node/src/devices/temperature-controlled-cabinet.ts index f68ec3e140..f53a624028 100644 --- a/packages/node/src/devices/temperature-controlled-cabinet.ts +++ b/packages/node/src/devices/temperature-controlled-cabinet.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -92,7 +92,7 @@ export namespace TemperatureControlledCabinetRequirements { export const TemperatureControlledCabinetDeviceDefinition = MutableEndpoint({ name: "TemperatureControlledCabinet", deviceType: 0x71, - deviceRevision: 2, + deviceRevision: 3, requirements: TemperatureControlledCabinetRequirements, behaviors: SupportedBehaviors() }); diff --git a/packages/node/src/devices/temperature-sensor.ts b/packages/node/src/devices/temperature-sensor.ts index 060298e9da..46068a865f 100644 --- a/packages/node/src/devices/temperature-sensor.ts +++ b/packages/node/src/devices/temperature-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/thermostat.ts b/packages/node/src/devices/thermostat.ts index f0edb1ecd7..69d4660237 100644 --- a/packages/node/src/devices/thermostat.ts +++ b/packages/node/src/devices/thermostat.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -9,28 +9,19 @@ import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; import { ThermostatServer as BaseThermostatServer } from "../behaviors/thermostat/ThermostatServer.js"; import { GroupsServer as BaseGroupsServer } from "../behaviors/groups/GroupsServer.js"; -import { - ScenesManagementServer as BaseScenesManagementServer -} from "../behaviors/scenes-management/ScenesManagementServer.js"; import { ThermostatUserInterfaceConfigurationServer as BaseThermostatUserInterfaceConfigurationServer } from "../behaviors/thermostat-user-interface-configuration/ThermostatUserInterfaceConfigurationServer.js"; import { EnergyPreferenceServer as BaseEnergyPreferenceServer } from "../behaviors/energy-preference/EnergyPreferenceServer.js"; -import { - TimeSynchronizationServer as BaseTimeSynchronizationServer -} from "../behaviors/time-synchronization/TimeSynchronizationServer.js"; -import { - RelativeHumidityMeasurementBehavior as BaseRelativeHumidityMeasurementBehavior -} from "../behaviors/relative-humidity-measurement/RelativeHumidityMeasurementBehavior.js"; -import { - TimeSynchronizationBehavior as BaseTimeSynchronizationBehavior -} from "../behaviors/time-synchronization/TimeSynchronizationBehavior.js"; import { FanControlBehavior as BaseFanControlBehavior } from "../behaviors/fan-control/FanControlBehavior.js"; import { TemperatureMeasurementBehavior as BaseTemperatureMeasurementBehavior } from "../behaviors/temperature-measurement/TemperatureMeasurementBehavior.js"; +import { + RelativeHumidityMeasurementBehavior as BaseRelativeHumidityMeasurementBehavior +} from "../behaviors/relative-humidity-measurement/RelativeHumidityMeasurementBehavior.js"; import { OccupancySensingBehavior as BaseOccupancySensingBehavior } from "../behaviors/occupancy-sensing/OccupancySensingBehavior.js"; @@ -73,13 +64,6 @@ export namespace ThermostatRequirements { */ export const GroupsServer = BaseGroupsServer; - /** - * The ScenesManagement cluster is optional per the Matter specification. - * - * We provide this alias to the default implementation {@link ScenesManagementServer} for convenience. - */ - export const ScenesManagementServer = BaseScenesManagementServer; - /** * The ThermostatUserInterfaceConfiguration cluster is optional per the Matter specification. * @@ -95,27 +79,6 @@ export namespace ThermostatRequirements { */ export const EnergyPreferenceServer = BaseEnergyPreferenceServer; - /** - * The TimeSynchronization cluster is optional per the Matter specification. - * - * We provide this alias to the default implementation {@link TimeSynchronizationServer} for convenience. - */ - export const TimeSynchronizationServer = BaseTimeSynchronizationServer; - - /** - * The RelativeHumidityMeasurement cluster is optional per the Matter specification. - * - * We provide this alias to the default implementation {@link RelativeHumidityMeasurementBehavior} for convenience. - */ - export const RelativeHumidityMeasurementBehavior = BaseRelativeHumidityMeasurementBehavior; - - /** - * The TimeSynchronization cluster is optional per the Matter specification. - * - * We provide this alias to the default implementation {@link TimeSynchronizationBehavior} for convenience. - */ - export const TimeSynchronizationBehavior = BaseTimeSynchronizationBehavior; - /** * The FanControl cluster is optional per the Matter specification. * @@ -130,6 +93,13 @@ export namespace ThermostatRequirements { */ export const TemperatureMeasurementBehavior = BaseTemperatureMeasurementBehavior; + /** + * The RelativeHumidityMeasurement cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link RelativeHumidityMeasurementBehavior} for convenience. + */ + export const RelativeHumidityMeasurementBehavior = BaseRelativeHumidityMeasurementBehavior; + /** * The OccupancySensing cluster is optional per the Matter specification. * @@ -142,13 +112,10 @@ export namespace ThermostatRequirements { */ export const server = { mandatory: { Identify: IdentifyServer, Thermostat: ThermostatServer }, - optional: { Groups: GroupsServer, - ScenesManagement: ScenesManagementServer, ThermostatUserInterfaceConfiguration: ThermostatUserInterfaceConfigurationServer, - EnergyPreference: EnergyPreferenceServer, - TimeSynchronization: TimeSynchronizationServer + EnergyPreference: EnergyPreferenceServer } }; @@ -157,10 +124,9 @@ export namespace ThermostatRequirements { */ export const client = { optional: { - RelativeHumidityMeasurement: RelativeHumidityMeasurementBehavior, - TimeSynchronization: TimeSynchronizationBehavior, FanControl: FanControlBehavior, TemperatureMeasurement: TemperatureMeasurementBehavior, + RelativeHumidityMeasurement: RelativeHumidityMeasurementBehavior, OccupancySensing: OccupancySensingBehavior }, @@ -171,7 +137,7 @@ export namespace ThermostatRequirements { export const ThermostatDeviceDefinition = MutableEndpoint({ name: "Thermostat", deviceType: 0x301, - deviceRevision: 3, + deviceRevision: 4, requirements: ThermostatRequirements, behaviors: SupportedBehaviors(ThermostatRequirements.server.mandatory.Identify) }); diff --git a/packages/node/src/devices/video-remote-control.ts b/packages/node/src/devices/video-remote-control.ts index 343f83cd5b..7da0c190db 100644 --- a/packages/node/src/devices/video-remote-control.ts +++ b/packages/node/src/devices/video-remote-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/water-freeze-detector.ts b/packages/node/src/devices/water-freeze-detector.ts index fae86137f2..24d851bd3e 100644 --- a/packages/node/src/devices/water-freeze-detector.ts +++ b/packages/node/src/devices/water-freeze-detector.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/water-heater.ts b/packages/node/src/devices/water-heater.ts new file mode 100644 index 0000000000..7fac8bb308 --- /dev/null +++ b/packages/node/src/devices/water-heater.ts @@ -0,0 +1,84 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { ThermostatServer as BaseThermostatServer } from "../behaviors/thermostat/ThermostatServer.js"; +import { + WaterHeaterManagementServer as BaseWaterHeaterManagementServer +} from "../behaviors/water-heater-management/WaterHeaterManagementServer.js"; +import { + WaterHeaterModeServer as BaseWaterHeaterModeServer +} from "../behaviors/water-heater-mode/WaterHeaterModeServer.js"; +import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A water heater is a device that is generally installed in properties to heat water for showers, baths etc. + * + * WaterHeaterDevice requires Thermostat cluster but Thermostat is not added by default because you must select the + * features your device supports. You can add manually using WaterHeaterDevice.with(). + * + * @see {@link MatterSpecification.v13.Device} § 14.2 + */ +export interface WaterHeaterDevice extends Identity {} + +export namespace WaterHeaterRequirements { + /** + * The Thermostat cluster is required by the Matter specification. + * + * This version of {@link ThermostatServer} is specialized per the specification. + */ + export const ThermostatServer = BaseThermostatServer.with("Heating"); + + /** + * The WaterHeaterManagement cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link WaterHeaterManagementServer} for convenience. + */ + export const WaterHeaterManagementServer = BaseWaterHeaterManagementServer; + + /** + * The WaterHeaterMode cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link WaterHeaterModeServer} for convenience. + */ + export const WaterHeaterModeServer = BaseWaterHeaterModeServer; + + /** + * The Identify cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link IdentifyServer} for convenience. + */ + export const IdentifyServer = BaseIdentifyServer; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { + mandatory: { + Thermostat: ThermostatServer, + WaterHeaterManagement: WaterHeaterManagementServer, + WaterHeaterMode: WaterHeaterModeServer + }, + optional: { Identify: IdentifyServer } + }; +} + +export const WaterHeaterDeviceDefinition = MutableEndpoint({ + name: "WaterHeater", + deviceType: 0x50f, + deviceRevision: 1, + requirements: WaterHeaterRequirements, + behaviors: SupportedBehaviors( + WaterHeaterRequirements.server.mandatory.WaterHeaterManagement, + WaterHeaterRequirements.server.mandatory.WaterHeaterMode + ) +}); + +export const WaterHeaterDevice: WaterHeaterDevice = WaterHeaterDeviceDefinition; diff --git a/packages/node/src/devices/water-leak-detector.ts b/packages/node/src/devices/water-leak-detector.ts index 526c96fd50..cc3a4f117a 100644 --- a/packages/node/src/devices/water-leak-detector.ts +++ b/packages/node/src/devices/water-leak-detector.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/devices/water-valve.ts b/packages/node/src/devices/water-valve.ts index a48c8639bb..402aecd74d 100644 --- a/packages/node/src/devices/water-valve.ts +++ b/packages/node/src/devices/water-valve.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -21,7 +21,7 @@ import { Identity } from "#general"; /** * This defines conformance to the Water Valve device type. * - * @see {@link MatterSpecification.v13.Device} § 5.4 + * @see {@link MatterSpecification.v13.Device} § 5.6 */ export interface WaterValveDevice extends Identity {} diff --git a/packages/node/src/devices/window-covering-controller.ts b/packages/node/src/devices/window-covering-controller.ts index 48d0f28e2a..96d42ccefc 100644 --- a/packages/node/src/devices/window-covering-controller.ts +++ b/packages/node/src/devices/window-covering-controller.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,9 +12,6 @@ import { } from "../behaviors/window-covering/WindowCoveringBehavior.js"; import { IdentifyBehavior as BaseIdentifyBehavior } from "../behaviors/identify/IdentifyBehavior.js"; import { GroupsBehavior as BaseGroupsBehavior } from "../behaviors/groups/GroupsBehavior.js"; -import { - ScenesManagementBehavior as BaseScenesManagementBehavior -} from "../behaviors/scenes-management/ScenesManagementBehavior.js"; import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; import { Identity } from "#general"; @@ -55,13 +52,6 @@ export namespace WindowCoveringControllerRequirements { */ export const GroupsBehavior = BaseGroupsBehavior; - /** - * The ScenesManagement cluster is optional per the Matter specification. - * - * We provide this alias to the default implementation {@link ScenesManagementBehavior} for convenience. - */ - export const ScenesManagementBehavior = BaseScenesManagementBehavior; - /** * An implementation for each server cluster supported by the endpoint per the Matter specification. */ @@ -72,7 +62,7 @@ export namespace WindowCoveringControllerRequirements { */ export const client = { mandatory: { WindowCovering: WindowCoveringBehavior }, - optional: { Identify: IdentifyBehavior, Groups: GroupsBehavior, ScenesManagement: ScenesManagementBehavior } + optional: { Identify: IdentifyBehavior, Groups: GroupsBehavior } }; } diff --git a/packages/node/src/devices/window-covering.ts b/packages/node/src/devices/window-covering.ts index 6470cce468..12a4b1b49c 100644 --- a/packages/node/src/devices/window-covering.ts +++ b/packages/node/src/devices/window-covering.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -9,9 +9,6 @@ import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; import { WindowCoveringServer as BaseWindowCoveringServer } from "../behaviors/window-covering/WindowCoveringServer.js"; import { GroupsServer as BaseGroupsServer } from "../behaviors/groups/GroupsServer.js"; -import { - ScenesManagementServer as BaseScenesManagementServer -} from "../behaviors/scenes-management/ScenesManagementServer.js"; import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; import { Identity } from "#general"; @@ -48,19 +45,12 @@ export namespace WindowCoveringRequirements { */ export const GroupsServer = BaseGroupsServer; - /** - * The ScenesManagement cluster is optional per the Matter specification. - * - * We provide this alias to the default implementation {@link ScenesManagementServer} for convenience. - */ - export const ScenesManagementServer = BaseScenesManagementServer; - /** * An implementation for each server cluster supported by the endpoint per the Matter specification. */ export const server = { mandatory: { Identify: IdentifyServer, WindowCovering: WindowCoveringServer }, - optional: { Groups: GroupsServer, ScenesManagement: ScenesManagementServer } + optional: { Groups: GroupsServer } }; } diff --git a/packages/node/src/endpoints/aggregator.ts b/packages/node/src/endpoints/aggregator.ts index c60f66cfdc..9c8d467fd5 100644 --- a/packages/node/src/endpoints/aggregator.ts +++ b/packages/node/src/endpoints/aggregator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,13 +10,16 @@ import { PartsBehavior } from "../behavior/system/parts/PartsBehavior.js"; import { IndexBehavior } from "../behavior/system/index/IndexBehavior.js"; import { ActionsServer as BaseActionsServer } from "../behaviors/actions/ActionsServer.js"; import { IdentifyServer as BaseIdentifyServer } from "../behaviors/identify/IdentifyServer.js"; +import { + CommissionerControlServer as BaseCommissionerControlServer +} from "../behaviors/commissioner-control/CommissionerControlServer.js"; import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; import { Identity } from "#general"; /** * This device type aggregates endpoints as a collection. Clusters on the endpoint indicating this device type provide - * functionality for the collection of descendent endpoints present in the PartsList of the endpoint’s descriptor, for + * functionality for the collection of descendant endpoints present in the PartsList of the endpoint’s descriptor, for * example the Actions cluster. * * The purpose of this device type is to aggregate functionality for a collection of endpoints. The definition of the @@ -44,19 +47,26 @@ export namespace AggregatorRequirements { */ export const IdentifyServer = BaseIdentifyServer; + /** + * The CommissionerControl cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link CommissionerControlServer} for convenience. + */ + export const CommissionerControlServer = BaseCommissionerControlServer; + /** * An implementation for each server cluster supported by the endpoint per the Matter specification. */ export const server = { mandatory: { Parts: PartsBehavior, Index: IndexBehavior }, - optional: { Actions: ActionsServer, Identify: IdentifyServer } + optional: { Actions: ActionsServer, Identify: IdentifyServer, CommissionerControl: CommissionerControlServer } }; } export const AggregatorEndpointDefinition = MutableEndpoint({ name: "Aggregator", deviceType: 0xe, - deviceRevision: 1, + deviceRevision: 2, requirements: AggregatorRequirements, behaviors: SupportedBehaviors( AggregatorRequirements.server.mandatory.Parts, diff --git a/packages/node/src/endpoints/base.ts b/packages/node/src/endpoints/base.ts index 7777d855c6..01a2bab6dc 100644 --- a/packages/node/src/endpoints/base.ts +++ b/packages/node/src/endpoints/base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/endpoints/bridged-node.ts b/packages/node/src/endpoints/bridged-node.ts index 1dcae12b51..e3e10ff9c9 100644 --- a/packages/node/src/endpoints/bridged-node.ts +++ b/packages/node/src/endpoints/bridged-node.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,12 @@ import { PowerSourceConfigurationServer as BasePowerSourceConfigurationServer } from "../behaviors/power-source-configuration/PowerSourceConfigurationServer.js"; import { PowerSourceServer as BasePowerSourceServer } from "../behaviors/power-source/PowerSourceServer.js"; +import { + EcosystemInformationServer as BaseEcosystemInformationServer +} from "../behaviors/ecosystem-information/EcosystemInformationServer.js"; +import { + AdministratorCommissioningServer as BaseAdministratorCommissioningServer +} from "../behaviors/administrator-commissioning/AdministratorCommissioningServer.js"; import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; import { DeviceClassification } from "#model"; import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; @@ -51,6 +57,20 @@ export namespace BridgedNodeRequirements { */ export const PowerSourceServer = BasePowerSourceServer; + /** + * The EcosystemInformation cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link EcosystemInformationServer} for convenience. + */ + export const EcosystemInformationServer = BaseEcosystemInformationServer; + + /** + * The AdministratorCommissioning cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link AdministratorCommissioningServer} for convenience. + */ + export const AdministratorCommissioningServer = BaseAdministratorCommissioningServer; + /** * An implementation for each server cluster supported by the endpoint per the Matter specification. */ @@ -60,14 +80,20 @@ export namespace BridgedNodeRequirements { Index: IndexBehavior, BridgedDeviceBasicInformation: BridgedDeviceBasicInformationServer }, - optional: { PowerSourceConfiguration: PowerSourceConfigurationServer, PowerSource: PowerSourceServer } + + optional: { + PowerSourceConfiguration: PowerSourceConfigurationServer, + PowerSource: PowerSourceServer, + EcosystemInformation: EcosystemInformationServer, + AdministratorCommissioning: AdministratorCommissioningServer + } }; } export const BridgedNodeEndpointDefinition = MutableEndpoint({ name: "BridgedNode", deviceType: 0x13, - deviceRevision: 2, + deviceRevision: 3, deviceClass: DeviceClassification.Utility, requirements: BridgedNodeRequirements, behaviors: SupportedBehaviors( diff --git a/packages/node/src/endpoints/device-energy-management.ts b/packages/node/src/endpoints/device-energy-management.ts index 13f85d119c..820345845b 100644 --- a/packages/node/src/endpoints/device-energy-management.ts +++ b/packages/node/src/endpoints/device-energy-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -21,13 +21,17 @@ import { Identity } from "#general"; * A Device Energy Management device provides reporting and optionally adjustment of the electrical power planned on * being consumed or produced by the device. * + * DeviceEnergyManagementEndpoint requires DeviceEnergyManagement cluster but DeviceEnergyManagement is not added by + * default because you must select the features your device supports. You can add manually using + * DeviceEnergyManagementEndpoint.with(). + * * @see {@link MatterSpecification.v13.Device} § 2.7 */ export interface DeviceEnergyManagementEndpoint extends Identity {} export namespace DeviceEnergyManagementRequirements { /** - * The DeviceEnergyManagement cluster is optional per the Matter specification. + * The DeviceEnergyManagement cluster is required by the Matter specification. * * We provide this alias to the default implementation {@link DeviceEnergyManagementServer} for convenience. */ @@ -44,18 +48,15 @@ export namespace DeviceEnergyManagementRequirements { * An implementation for each server cluster supported by the endpoint per the Matter specification. */ export const server = { - optional: { - DeviceEnergyManagement: DeviceEnergyManagementServer, - DeviceEnergyManagementMode: DeviceEnergyManagementModeServer - }, - mandatory: {} + mandatory: { DeviceEnergyManagement: DeviceEnergyManagementServer }, + optional: { DeviceEnergyManagementMode: DeviceEnergyManagementModeServer } }; } export const DeviceEnergyManagementEndpointDefinition = MutableEndpoint({ name: "DeviceEnergyManagement", deviceType: 0x50d, - deviceRevision: 1, + deviceRevision: 2, deviceClass: DeviceClassification.Utility, requirements: DeviceEnergyManagementRequirements, behaviors: SupportedBehaviors() diff --git a/packages/node/src/endpoints/electrical-sensor.ts b/packages/node/src/endpoints/electrical-sensor.ts index 40f2f4cb8b..d78ce0a866 100644 --- a/packages/node/src/endpoints/electrical-sensor.ts +++ b/packages/node/src/endpoints/electrical-sensor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/endpoints/index.ts b/packages/node/src/endpoints/index.ts index 8dbe00d34b..154e460c1b 100644 --- a/packages/node/src/endpoints/index.ts +++ b/packages/node/src/endpoints/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -11,7 +11,9 @@ export * from "./base.js"; export * from "./bridged-node.js"; export * from "./device-energy-management.js"; export * from "./electrical-sensor.js"; +export * from "./joint-fabric-administrator.js"; export * from "./ota-provider.js"; export * from "./ota-requestor.js"; export * from "./power-source.js"; export * from "./root.js"; +export * from "./secondary-network-interface.js"; diff --git a/packages/node/src/endpoints/joint-fabric-administrator.ts b/packages/node/src/endpoints/joint-fabric-administrator.ts new file mode 100644 index 0000000000..80ee24c010 --- /dev/null +++ b/packages/node/src/endpoints/joint-fabric-administrator.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { JointFabricPkiServer as BaseJointFabricPkiServer } from "../behaviors/joint-fabric-pki/JointFabricPkiServer.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { DeviceClassification } from "#model"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A Joint Fabric Administrator device provides capabilities to manage the Joint Fabric Datastore and issue an ICAC + * signed by the Joint Fabric Anchor Root CA. + * + * A client wanting to access the capabilities of the Joint Fabric Administrator may use the Joint Commissioning Method + * to be commissioned onto the Joint Fabric. Once commissioned, a client may access the capabilities of the Joint + * Fabric Administrator. + * + * @see {@link MatterSpecification.v13.Device} § 2.9 + */ +export interface JointFabricAdministratorEndpoint extends Identity {} + +export namespace JointFabricAdministratorRequirements { + /** + * The JointFabricPki cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link JointFabricPkiServer} for convenience. + */ + export const JointFabricPkiServer = BaseJointFabricPkiServer; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { mandatory: { JointFabricPki: JointFabricPkiServer } }; +} + +export const JointFabricAdministratorEndpointDefinition = MutableEndpoint({ + name: "JointFabricAdministrator", + deviceType: 0x130, + deviceRevision: 1, + deviceClass: DeviceClassification.Utility, + requirements: JointFabricAdministratorRequirements, + behaviors: SupportedBehaviors(JointFabricAdministratorRequirements.server.mandatory.JointFabricPki) +}); + +export const JointFabricAdministratorEndpoint: JointFabricAdministratorEndpoint = JointFabricAdministratorEndpointDefinition; diff --git a/packages/node/src/endpoints/ota-provider.ts b/packages/node/src/endpoints/ota-provider.ts index 98e59d9b43..d5e85d4db0 100644 --- a/packages/node/src/endpoints/ota-provider.ts +++ b/packages/node/src/endpoints/ota-provider.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/endpoints/ota-requestor.ts b/packages/node/src/endpoints/ota-requestor.ts index 2aa4f77f48..8545163129 100644 --- a/packages/node/src/endpoints/ota-requestor.ts +++ b/packages/node/src/endpoints/ota-requestor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/endpoints/power-source.ts b/packages/node/src/endpoints/power-source.ts index f63e8fe34c..95b72648fb 100644 --- a/packages/node/src/endpoints/power-source.ts +++ b/packages/node/src/endpoints/power-source.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,9 @@ import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js import { Identity } from "#general"; /** + * PowerSourceEndpoint requires PowerSource cluster but PowerSource is not added by default because you must select the + * features your device supports. You can add manually using PowerSourceEndpoint.with(). + * * @see {@link MatterSpecification.v13.Device} § 2.2 */ export interface PowerSourceEndpoint extends Identity {} @@ -37,7 +40,7 @@ export const PowerSourceEndpointDefinition = MutableEndpoint({ deviceRevision: 1, deviceClass: DeviceClassification.Utility, requirements: PowerSourceRequirements, - behaviors: SupportedBehaviors(PowerSourceRequirements.server.mandatory.PowerSource) + behaviors: SupportedBehaviors() }); export const PowerSourceEndpoint: PowerSourceEndpoint = PowerSourceEndpointDefinition; diff --git a/packages/node/src/endpoints/root.ts b/packages/node/src/endpoints/root.ts index 90bb65061c..0becb6cfad 100644 --- a/packages/node/src/endpoints/root.ts +++ b/packages/node/src/endpoints/root.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -248,7 +248,7 @@ export namespace RootRequirements { export const RootEndpointDefinition = MutableEndpoint({ name: "RootNode", deviceType: 0x16, - deviceRevision: 2, + deviceRevision: 3, deviceClass: DeviceClassification.Node, requirements: RootRequirements, diff --git a/packages/node/src/endpoints/secondary-network-interface.ts b/packages/node/src/endpoints/secondary-network-interface.ts new file mode 100644 index 0000000000..c480b683dd --- /dev/null +++ b/packages/node/src/endpoints/secondary-network-interface.ts @@ -0,0 +1,93 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { + NetworkCommissioningServer as BaseNetworkCommissioningServer +} from "../behaviors/network-commissioning/NetworkCommissioningServer.js"; +import { + EthernetNetworkDiagnosticsServer as BaseEthernetNetworkDiagnosticsServer +} from "../behaviors/ethernet-network-diagnostics/EthernetNetworkDiagnosticsServer.js"; +import { + WiFiNetworkDiagnosticsServer as BaseWiFiNetworkDiagnosticsServer +} from "../behaviors/wi-fi-network-diagnostics/WiFiNetworkDiagnosticsServer.js"; +import { + ThreadNetworkDiagnosticsServer as BaseThreadNetworkDiagnosticsServer +} from "../behaviors/thread-network-diagnostics/ThreadNetworkDiagnosticsServer.js"; +import { MutableEndpoint } from "../endpoint/type/MutableEndpoint.js"; +import { DeviceClassification } from "#model"; +import { SupportedBehaviors } from "../endpoint/properties/SupportedBehaviors.js"; +import { Identity } from "#general"; + +/** + * A Secondary Network Interface device provides an additional network interface supported by the Node, supplementing + * the primary interface hosted by the Root Node endpoint. + * + * A Node supporting multiple network interfaces shall include the primary interface on the Root Node endpoint, along + * with secondary interfaces on other endpoints. The priorities of these network interfaces are determined by the order + * of their endpoints, where interfaces with smaller endpoint numbers are higher priority. + * + * SecondaryNetworkInterfaceEndpoint requires NetworkCommissioning cluster but NetworkCommissioning is not added by + * default because you must select the features your device supports. You can add manually using + * SecondaryNetworkInterfaceEndpoint.with(). + * + * @see {@link MatterSpecification.v13.Device} § 2.8 + */ +export interface SecondaryNetworkInterfaceEndpoint extends Identity {} + +export namespace SecondaryNetworkInterfaceRequirements { + /** + * The NetworkCommissioning cluster is required by the Matter specification. + * + * We provide this alias to the default implementation {@link NetworkCommissioningServer} for convenience. + */ + export const NetworkCommissioningServer = BaseNetworkCommissioningServer; + + /** + * The EthernetNetworkDiagnostics cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link EthernetNetworkDiagnosticsServer} for convenience. + */ + export const EthernetNetworkDiagnosticsServer = BaseEthernetNetworkDiagnosticsServer; + + /** + * The WiFiNetworkDiagnostics cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link WiFiNetworkDiagnosticsServer} for convenience. + */ + export const WiFiNetworkDiagnosticsServer = BaseWiFiNetworkDiagnosticsServer; + + /** + * The ThreadNetworkDiagnostics cluster is optional per the Matter specification. + * + * We provide this alias to the default implementation {@link ThreadNetworkDiagnosticsServer} for convenience. + */ + export const ThreadNetworkDiagnosticsServer = BaseThreadNetworkDiagnosticsServer; + + /** + * An implementation for each server cluster supported by the endpoint per the Matter specification. + */ + export const server = { + mandatory: { NetworkCommissioning: NetworkCommissioningServer }, + optional: { + EthernetNetworkDiagnostics: EthernetNetworkDiagnosticsServer, + WiFiNetworkDiagnostics: WiFiNetworkDiagnosticsServer, + ThreadNetworkDiagnostics: ThreadNetworkDiagnosticsServer + } + }; +} + +export const SecondaryNetworkInterfaceEndpointDefinition = MutableEndpoint({ + name: "SecondaryNetworkInterface", + deviceType: 0x19, + deviceRevision: 1, + deviceClass: DeviceClassification.Utility, + requirements: SecondaryNetworkInterfaceRequirements, + behaviors: SupportedBehaviors() +}); + +export const SecondaryNetworkInterfaceEndpoint: SecondaryNetworkInterfaceEndpoint = SecondaryNetworkInterfaceEndpointDefinition; diff --git a/packages/node/src/tags/AreaNamespaceTag.ts b/packages/node/src/tags/AreaNamespaceTag.ts new file mode 100644 index 0000000000..1c86949e2c --- /dev/null +++ b/packages/node/src/tags/AreaNamespaceTag.ts @@ -0,0 +1,170 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; + +/** + * The tags contained in this namespace may be used in any domain or context, to indicate an association with an indoor + * or outdoor area of a home. + * + * @see {@link MatterSpecification.v13.Namespace} § 13 + */ +export const AreaNamespaceTag = SemanticNamespace({ + id: 0x10, + + tags: { + Aisle: { id: 0x0, label: "Aisle" }, + Attic: { id: 0x1, label: "Attic" }, + BackDoor: { id: 0x2, label: "Back Door" }, + BackYard: { id: 0x3, label: "Back Yard" }, + Balcony: { id: 0x4, label: "Balcony" }, + Ballroom: { id: 0x5, label: "Ballroom" }, + + /** + * Also known as Restroom + */ + Bathroom: { id: 0x6, label: "Bathroom" }, + + Bedroom: { id: 0x7, label: "Bedroom" }, + Border: { id: 0x8, label: "Border" }, + + /** + * A small room typically used for storage + */ + Boxroom: { id: 0x9, label: "Boxroom" }, + + BreakfastRoom: { id: 0xa, label: "Breakfast Room" }, + Carport: { id: 0xb, label: "Carport" }, + Cellar: { id: 0xc, label: "Cellar" }, + Cloakroom: { id: 0xd, label: "Cloakroom" }, + Closet: { id: 0xe, label: "Closet" }, + Conservatory: { id: 0xf, label: "Conservatory" }, + Corridor: { id: 0x10, label: "Corridor" }, + CraftRoom: { id: 0x11, label: "Craft Room" }, + Cupboard: { id: 0x12, label: "Cupboard" }, + Deck: { id: 0x13, label: "Deck" }, + + /** + * A small, comfortable room for individual activities such as work or hobbies + */ + Den: { id: 0x14, label: "Den" }, + + Dining: { id: 0x15, label: "Dining" }, + DrawingRoom: { id: 0x16, label: "Drawing Room" }, + DressingRoom: { id: 0x17, label: "Dressing Room" }, + Driveway: { id: 0x18, label: "Driveway" }, + Elevator: { id: 0x19, label: "Elevator" }, + + /** + * A bathroom directly accessible from a bedroom + */ + Ensuite: { id: 0x1a, label: "Ensuite" }, + + Entrance: { id: 0x1b, label: "Entrance" }, + Entryway: { id: 0x1c, label: "Entryway" }, + FamilyRoom: { id: 0x1d, label: "Family Room" }, + Foyer: { id: 0x1e, label: "Foyer" }, + FrontDoor: { id: 0x1f, label: "Front Door" }, + FrontYard: { id: 0x20, label: "Front Yard" }, + GameRoom: { id: 0x21, label: "Game Room" }, + Garage: { id: 0x22, label: "Garage" }, + GarageDoor: { id: 0x23, label: "Garage Door" }, + Garden: { id: 0x24, label: "Garden" }, + GardenDoor: { id: 0x25, label: "Garden Door" }, + + /** + * Also known as Guest Restroom + */ + GuestBathroom: { id: 0x26, label: "Guest Bathroom" }, + + GuestBedroom: { id: 0x27, label: "Guest Bedroom" }, + GuestRoom: { id: 0x28, label: "Guest Room" }, + Gym: { id: 0x29, label: "Gym" }, + Hallway: { id: 0x2a, label: "Hallway" }, + + /** + * A cozy room containing a fireplace or other point heat source + */ + HearthRoom: { id: 0x2b, label: "Hearth Room" }, + + KidsRoom: { id: 0x2c, label: "Kids Room" }, + KidsBedroom: { id: 0x2d, label: "Kids Bedroom" }, + Kitchen: { id: 0x2e, label: "Kitchen" }, + LaundryRoom: { id: 0x2f, label: "Laundry Room" }, + Lawn: { id: 0x30, label: "Lawn" }, + Library: { id: 0x31, label: "Library" }, + LivingRoom: { id: 0x32, label: "Living Room" }, + Lounge: { id: 0x33, label: "Lounge" }, + MediaTvRoom: { id: 0x34, label: "Media/TV Room" }, + + /** + * A space used to remove soiled garments prior to entering the domicile proper + */ + MudRoom: { id: 0x35, label: "Mud Room" }, + + MusicRoom: { id: 0x36, label: "Music Room" }, + Nursery: { id: 0x37, label: "Nursery" }, + Office: { id: 0x38, label: "Office" }, + OutdoorKitchen: { id: 0x39, label: "Outdoor Kitchen" }, + Outside: { id: 0x3a, label: "Outside" }, + + /** + * AKA a larder, a place where food is stored + */ + Pantry: { id: 0x3b, label: "Pantry" }, + + ParkingLot: { id: 0x3c, label: "Parking Lot" }, + Parlor: { id: 0x3d, label: "Parlor" }, + Patio: { id: 0x3e, label: "Patio" }, + PlayRoom: { id: 0x3f, label: "Play Room" }, + PoolRoom: { id: 0x40, label: "Pool Room" }, + Porch: { id: 0x41, label: "Porch" }, + PrimaryBathroom: { id: 0x42, label: "Primary Bathroom" }, + PrimaryBedroom: { id: 0x43, label: "Primary Bedroom" }, + Ramp: { id: 0x44, label: "Ramp" }, + ReceptionRoom: { id: 0x45, label: "Reception Room" }, + RecreationRoom: { id: 0x46, label: "Recreation Room" }, + Roof: { id: 0x47, label: "Roof" }, + Sauna: { id: 0x48, label: "Sauna" }, + + /** + * A utility space for cleaning dishes and laundry + */ + Scullery: { id: 0x49, label: "Scullery" }, + + SewingRoom: { id: 0x4a, label: "Sewing Room" }, + Shed: { id: 0x4b, label: "Shed" }, + SideDoor: { id: 0x4c, label: "Side Door" }, + SideYard: { id: 0x4d, label: "Side Yard" }, + SittingRoom: { id: 0x4e, label: "Sitting Room" }, + + /** + * An informal space meant to be 'cozy', 'snug', relaxed, meant to share with family or friends + */ + Snug: { id: 0x4f, label: "Snug" }, + + Spa: { id: 0x50, label: "Spa" }, + Staircase: { id: 0x51, label: "Staircase" }, + SteamRoom: { id: 0x52, label: "Steam Room" }, + StorageRoom: { id: 0x53, label: "Storage Room" }, + Studio: { id: 0x54, label: "Studio" }, + Study: { id: 0x55, label: "Study" }, + SunRoom: { id: 0x56, label: "Sun Room" }, + SwimmingPool: { id: 0x57, label: "Swimming Pool" }, + Terrace: { id: 0x58, label: "Terrace" }, + + /** + * A room dedicated to a toilet; a water closet / WC + */ + Toilet: { id: 0x59, label: "Toilet" }, + + UtilityRoom: { id: 0x5a, label: "Utility Room" }, + Ward: { id: 0x5b, label: "Ward" }, + Workshop: { id: 0x5c, label: "Workshop" } + } +}); diff --git a/packages/node/src/tags/ClosureTag.ts b/packages/node/src/tags/ClosureTag.ts index 935427a228..f2d112ed38 100644 --- a/packages/node/src/tags/ClosureTag.ts +++ b/packages/node/src/tags/ClosureTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/tags/CompassDirectionTag.ts b/packages/node/src/tags/CompassDirectionTag.ts index 8af14d2690..e2f4235339 100644 --- a/packages/node/src/tags/CompassDirectionTag.ts +++ b/packages/node/src/tags/CompassDirectionTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/tags/CompassLocationTag.ts b/packages/node/src/tags/CompassLocationTag.ts index 087a7651c3..73c7228d5b 100644 --- a/packages/node/src/tags/CompassLocationTag.ts +++ b/packages/node/src/tags/CompassLocationTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/tags/DirectionTag.ts b/packages/node/src/tags/DirectionTag.ts index 24ec109ec8..ccf66cec88 100644 --- a/packages/node/src/tags/DirectionTag.ts +++ b/packages/node/src/tags/DirectionTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/tags/ElectricalMeasurementTag.ts b/packages/node/src/tags/ElectricalMeasurementTag.ts index 826717a7db..c23485c53f 100644 --- a/packages/node/src/tags/ElectricalMeasurementTag.ts +++ b/packages/node/src/tags/ElectricalMeasurementTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,7 @@ import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; * The tags contained in this namespace are restricted for use in the electrical measurement domain and shall NOT be * used in any other domain or context. * - * @see {@link MatterSpecification.v13.Namespace} § 10 + * @see {@link MatterSpecification.v13.Namespace} § 12 */ export const ElectricalMeasurementTag = SemanticNamespace({ id: 0xa, diff --git a/packages/node/src/tags/LandmarkNamespaceTag.ts b/packages/node/src/tags/LandmarkNamespaceTag.ts new file mode 100644 index 0000000000..5fcab4eada --- /dev/null +++ b/packages/node/src/tags/LandmarkNamespaceTag.ts @@ -0,0 +1,73 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; + +/** + * The tags contained in this namespace may be used in any domain or context, to indicate an association with a home + * landmark. + * + * @see {@link MatterSpecification.v13.Namespace} § 10 + */ +export const LandmarkNamespaceTag = SemanticNamespace({ + id: 0x11, + + tags: { + AirConditioner: { id: 0x0, label: "Air Conditioner" }, + AirPurifier: { id: 0x1, label: "Air Purifier" }, + BackDoor: { id: 0x2, label: "Back Door" }, + BarStool: { id: 0x3, label: "Bar Stool" }, + BathMat: { id: 0x4, label: "Bath Mat" }, + Bathtub: { id: 0x5, label: "Bathtub" }, + Bed: { id: 0x6, label: "Bed" }, + Bookshelf: { id: 0x7, label: "Bookshelf" }, + Chair: { id: 0x8, label: "Chair" }, + ChristmasTree: { id: 0x9, label: "Christmas Tree" }, + CoatRack: { id: 0xa, label: "Coat Rack" }, + CoffeeTable: { id: 0xb, label: "Coffee Table" }, + CookingRange: { id: 0xc, label: "Cooking Range" }, + Couch: { id: 0xd, label: "Couch" }, + Countertop: { id: 0xe, label: "Countertop" }, + Cradle: { id: 0xf, label: "Cradle" }, + Crib: { id: 0x10, label: "Crib" }, + Desk: { id: 0x11, label: "Desk" }, + DiningTable: { id: 0x12, label: "Dining Table" }, + Dishwasher: { id: 0x13, label: "Dishwasher" }, + Door: { id: 0x14, label: "Door" }, + Dresser: { id: 0x15, label: "Dresser" }, + LaundryDryer: { id: 0x16, label: "Laundry Dryer" }, + Fan: { id: 0x17, label: "Fan" }, + Fireplace: { id: 0x18, label: "Fireplace" }, + Freezer: { id: 0x19, label: "Freezer" }, + FrontDoor: { id: 0x1a, label: "Front Door" }, + HighChair: { id: 0x1b, label: "High Chair" }, + KitchenIsland: { id: 0x1c, label: "Kitchen Island" }, + Lamp: { id: 0x1d, label: "Lamp" }, + LitterBox: { id: 0x1e, label: "Litter Box" }, + Mirror: { id: 0x1f, label: "Mirror" }, + Nightstand: { id: 0x20, label: "Nightstand" }, + Oven: { id: 0x21, label: "Oven" }, + PetBed: { id: 0x22, label: "Pet Bed" }, + PetBowl: { id: 0x23, label: "Pet Bowl" }, + PetCrate: { id: 0x24, label: "Pet Crate" }, + Refrigerator: { id: 0x25, label: "Refrigerator" }, + ScratchingPost: { id: 0x26, label: "Scratching Post" }, + ShoeRack: { id: 0x27, label: "Shoe Rack" }, + Shower: { id: 0x28, label: "Shower" }, + SideDoor: { id: 0x29, label: "Side Door" }, + Sink: { id: 0x2a, label: "Sink" }, + Sofa: { id: 0x2b, label: "Sofa" }, + Stove: { id: 0x2c, label: "Stove" }, + Table: { id: 0x2d, label: "Table" }, + Toilet: { id: 0x2e, label: "Toilet" }, + TrashCan: { id: 0x2f, label: "Trash Can" }, + LaundryWasher: { id: 0x30, label: "Laundry Washer" }, + Window: { id: 0x31, label: "Window" }, + WineCooler: { id: 0x32, label: "Wine Cooler" } + } +}); diff --git a/packages/node/src/tags/LaundryTag.ts b/packages/node/src/tags/LaundryTag.ts index ae6406958a..7c5792380d 100644 --- a/packages/node/src/tags/LaundryTag.ts +++ b/packages/node/src/tags/LaundryTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,7 @@ import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; * The tags contained in this namespace are restricted for use in the laundry domain and shall NOT be used in any other * domain or context. * - * @see {@link MatterSpecification.v13.Namespace} § 11 + * @see {@link MatterSpecification.v13.Namespace} § 14 */ export const LaundryTag = SemanticNamespace({ id: 0xe, diff --git a/packages/node/src/tags/LevelTag.ts b/packages/node/src/tags/LevelTag.ts index 1b8454212d..7b9fb081e0 100644 --- a/packages/node/src/tags/LevelTag.ts +++ b/packages/node/src/tags/LevelTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/tags/LocationTag.ts b/packages/node/src/tags/LocationTag.ts index 1013c32726..c9d6b7b176 100644 --- a/packages/node/src/tags/LocationTag.ts +++ b/packages/node/src/tags/LocationTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/tags/NumberTag.ts b/packages/node/src/tags/NumberTag.ts index 2796e84fdb..b108e1b4cf 100644 --- a/packages/node/src/tags/NumberTag.ts +++ b/packages/node/src/tags/NumberTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/tags/PositionTag.ts b/packages/node/src/tags/PositionTag.ts index 103cc8ee9d..ed83452bcd 100644 --- a/packages/node/src/tags/PositionTag.ts +++ b/packages/node/src/tags/PositionTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/node/src/tags/PowerSourceTag.ts b/packages/node/src/tags/PowerSourceTag.ts index 5c81a3f9d0..86c9ad4098 100644 --- a/packages/node/src/tags/PowerSourceTag.ts +++ b/packages/node/src/tags/PowerSourceTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,7 @@ import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; * The tags contained in this namespace are restricted for use in the power source domain and shall NOT be used in any * other domain or context. * - * @see {@link MatterSpecification.v13.Namespace} § 12 + * @see {@link MatterSpecification.v13.Namespace} § 15 */ export const PowerSourceTag = SemanticNamespace({ id: 0xf, @@ -28,7 +28,7 @@ export const PowerSourceTag = SemanticNamespace({ * * Power Source clusters with this tag shall implement the WIRED feature. * - * @see {@link MatterSpecification.v13.Namespace} § 12.1 + * @see {@link MatterSpecification.v13.Namespace} § 15.1 */ Grid: { id: 0x1, label: "Grid" }, @@ -37,7 +37,7 @@ export const PowerSourceTag = SemanticNamespace({ * * Power Source clusters with this tag shall implement the WIRED feature. * - * @see {@link MatterSpecification.v13.Namespace} § 12.2 + * @see {@link MatterSpecification.v13.Namespace} § 15.2 */ Solar: { id: 0x2, label: "Solar" }, @@ -46,7 +46,7 @@ export const PowerSourceTag = SemanticNamespace({ * * Power Source clusters with this tag shall implement the BAT feature. * - * @see {@link MatterSpecification.v13.Namespace} § 12.3 + * @see {@link MatterSpecification.v13.Namespace} § 15.3 */ Battery: { id: 0x3, label: "Battery" }, @@ -55,7 +55,7 @@ export const PowerSourceTag = SemanticNamespace({ * * Power Source clusters with this tag shall implement the BAT feature. * - * @see {@link MatterSpecification.v13.Namespace} § 12.4 + * @see {@link MatterSpecification.v13.Namespace} § 15.4 */ Ev: { id: 0x4, label: "EV" } } diff --git a/packages/node/src/tags/RefrigeratorTag.ts b/packages/node/src/tags/RefrigeratorTag.ts index d52b7206f0..e380d28972 100644 --- a/packages/node/src/tags/RefrigeratorTag.ts +++ b/packages/node/src/tags/RefrigeratorTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,7 @@ import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; * The tags contained in this namespace are restricted for use in the refrigerator domain and shall NOT be used in any * other domain or context. * - * @see {@link MatterSpecification.v13.Namespace} § 13 + * @see {@link MatterSpecification.v13.Namespace} § 16 */ export const RefrigeratorTag = SemanticNamespace({ id: 0x41, diff --git a/packages/node/src/tags/RelativePositionTag.ts b/packages/node/src/tags/RelativePositionTag.ts new file mode 100644 index 0000000000..733db11c5d --- /dev/null +++ b/packages/node/src/tags/RelativePositionTag.ts @@ -0,0 +1,41 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; + +/** + * The tags contained in this namespace may be used in any domain or context, to indicate an association with a + * position relative to some reference, which must be specified by the user of these tags. For example, the position + * may be relative to a household item, such as a dining table, and the user of these tags must indicate that. Note the + * difference with Chapter 9, Common Position Semantic Tag Namespace, which contains tags indicating the position + * relative to the device. + * + * @see {@link MatterSpecification.v13.Namespace} § 11 + */ +export const RelativePositionTag = SemanticNamespace({ + id: 0x12, + + tags: { + Under: { id: 0x0, label: "Under" }, + + /** + * Area in proximity to the point of reference + */ + NextTo: { id: 0x1, label: "Next To" }, + + /** + * The area surrounding the point the reference + */ + Around: { id: 0x2, label: "Around" }, + + On: { id: 0x3, label: "On" }, + Above: { id: 0x4, label: "Above" }, + FrontOf: { id: 0x5, label: "Front Of" }, + Behind: { id: 0x6, label: "Behind" } + } +}); diff --git a/packages/node/src/tags/RoomAirConditionerTag.ts b/packages/node/src/tags/RoomAirConditionerTag.ts index a64ca42617..01d6fa78c5 100644 --- a/packages/node/src/tags/RoomAirConditionerTag.ts +++ b/packages/node/src/tags/RoomAirConditionerTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,7 @@ import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; * The tags contained in this namespace are restricted for use in the room air conditioner domain and shall NOT be used * in any other domain or context. * - * @see {@link MatterSpecification.v13.Namespace} § 14 + * @see {@link MatterSpecification.v13.Namespace} § 17 */ export const RoomAirConditionerTag = SemanticNamespace({ id: 0x42, diff --git a/packages/node/src/tags/SwitchesTag.ts b/packages/node/src/tags/SwitchesTag.ts index 955cd5daf6..fe1dbc92ba 100644 --- a/packages/node/src/tags/SwitchesTag.ts +++ b/packages/node/src/tags/SwitchesTag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -17,7 +17,7 @@ import { SemanticNamespace } from "../endpoint/type/SemanticNamespace.js"; * Please see the rules for applying these and other tags for switch devices, e.g. from the Common Position Namespace * and the Common Number Namespace in the Generic Switch device type section in the Device Library. * - * @see {@link MatterSpecification.v13.Namespace} § 15 + * @see {@link MatterSpecification.v13.Namespace} § 18 */ export const SwitchesTag = SemanticNamespace({ id: 0x43, @@ -56,7 +56,7 @@ export const SwitchesTag = SemanticNamespace({ * description of the function indicated on the button, such as a label or icon printed on the button, e.g. * "dining". * - * @see {@link MatterSpecification.v13.Namespace} § 15.1 + * @see {@link MatterSpecification.v13.Namespace} § 18.1 */ Custom: { id: 0x8, label: "Custom" } } diff --git a/packages/node/src/tags/index.ts b/packages/node/src/tags/index.ts index dd8a06fd78..a5f783d150 100644 --- a/packages/node/src/tags/index.ts +++ b/packages/node/src/tags/index.ts @@ -1,16 +1,18 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ +export * from "./AreaNamespaceTag.js"; export * from "./ClosureTag.js"; export * from "./CompassDirectionTag.js"; export * from "./CompassLocationTag.js"; export * from "./DirectionTag.js"; export * from "./ElectricalMeasurementTag.js"; +export * from "./LandmarkNamespaceTag.js"; export * from "./LaundryTag.js"; export * from "./LevelTag.js"; export * from "./LocationTag.js"; @@ -18,5 +20,6 @@ export * from "./NumberTag.js"; export * from "./PositionTag.js"; export * from "./PowerSourceTag.js"; export * from "./RefrigeratorTag.js"; +export * from "./RelativePositionTag.js"; export * from "./RoomAirConditionerTag.js"; export * from "./SwitchesTag.js"; diff --git a/packages/node/src/tsconfig.json b/packages/node/src/tsconfig.json index 6b68909f38..dd6cabd880 100644 --- a/packages/node/src/tsconfig.json +++ b/packages/node/src/tsconfig.json @@ -20,6 +20,9 @@ { "path": "../../testing/src" }, + { + "path": "../../tools/src" + }, { "path": "../../types/src" } diff --git a/packages/node/test/behavior/state/validation/conformanceTest.ts b/packages/node/test/behavior/state/validation/conformanceTest.ts index 759a527039..e77794014b 100644 --- a/packages/node/test/behavior/state/validation/conformanceTest.ts +++ b/packages/node/test/behavior/state/validation/conformanceTest.ts @@ -520,6 +520,35 @@ const AllTests = Tests({ }, }, ), + + "hairy real-world": Tests( + Features({ + PIR: "PIR", + US: "US", + PHY: "PHY", + }), + Fields( + { + name: "HoldTime", + type: "uint16", + }, + { + name: "PirUnoccupiedToOccupiedThreshold", + type: "uint8", + }, + { + name: "PirUnoccupiedToOccupiedDelay", + type: "uint8", + conformance: + "HoldTime & (PIR | !PIR & !US & !PHY) & PirUnoccupiedToOccupiedThreshold, [HoldTime & (PIR | !PIR & !US & !PHY)], D", + }, + ), + { + "OccupancySensing.PirUnoccupiedToOccupiedDelay": { + record: { pirUnoccupiedToOccupiedDelay: 4 }, + }, + }, + ), }), }); diff --git a/packages/node/test/behavior/state/validation/validation-test-utils.ts b/packages/node/test/behavior/state/validation/validation-test-utils.ts index d7a6ddc9f3..7521f0e882 100644 --- a/packages/node/test/behavior/state/validation/validation-test-utils.ts +++ b/packages/node/test/behavior/state/validation/validation-test-utils.ts @@ -81,7 +81,7 @@ function validate({ fields, features }: ClusterStructure, { supports, record, er // Perform validation try { manager.validate?.(record ?? {}, OfflineContext.ReadOnly, { path: DataModelPath(cluster.path) }); - expect(error).undefined; + expect(error, `Expected ${error?.constructor.name} but none thrown`); } catch (e) { if (!error || (e as any).constructor.name === "AssertionError") { throw e; @@ -92,11 +92,15 @@ function validate({ fields, features }: ClusterStructure, { supports, record, er } export function testValidation(description: string, what: Tests | Test, structure: ClusterStructure = {}) { - if (what.fields) { - structure = { ...structure, fields: what.fields }; + const { only, fields, features } = what; + if (only) { + structure = { ...structure, only }; } - if (what.features) { - structure = { ...structure, features: what.features }; + if (fields) { + structure = { ...structure, fields }; + } + if (features) { + structure = { ...structure, features }; } if (what[NESTING]) { @@ -106,7 +110,11 @@ export function testValidation(description: string, what: Tests | Test, structur } }); } else { - it(description, () => validate(structure, what)); + let generator = it; + if (only) { + generator = generator.only as Mocha.TestFunction; + } + generator(description, () => validate(structure, what)); } } @@ -114,12 +122,14 @@ type Fields = FieldModel[]; type Features = AttributeModel; type ClusterStructure = { + only?: boolean; fields?: Fields; features?: Features; }; type Test = ClusterStructure & { [NESTING]?: false; + only?: boolean; supports?: FeatureSet.Definition; record?: Properties; error?: { type: new (...args: any[]) => StatusResponseError; message?: string }; diff --git a/packages/node/test/behaviors/descriptor/DescriptorServerTest.ts b/packages/node/test/behaviors/descriptor/DescriptorServerTest.ts index a146ffd48f..1acee7936d 100644 --- a/packages/node/test/behaviors/descriptor/DescriptorServerTest.ts +++ b/packages/node/test/behaviors/descriptor/DescriptorServerTest.ts @@ -122,8 +122,9 @@ describe("DescriptorServer", () => { it("fully populates device types", async () => { const light = await MockEndpoint.create(ColorTemperatureLightDevice, { colorControl: { - coupleColorTempToLevelMinMireds: 0, - startUpColorTemperatureMireds: 0, + colorMode: 0, + coupleColorTempToLevelMinMireds: 1, + startUpColorTemperatureMireds: null, }, }); diff --git a/packages/node/test/behaviors/switch/SwitchServerTest.ts b/packages/node/test/behaviors/switch/SwitchServerTest.ts index 3c0ba755b0..ea9141e019 100644 --- a/packages/node/test/behaviors/switch/SwitchServerTest.ts +++ b/packages/node/test/behaviors/switch/SwitchServerTest.ts @@ -111,7 +111,7 @@ describe("SwitchServer", () => { it("Reject invalid currentPosition", async () => { const device = await createLatchingSwitch(); await expect(device.set({ switch: { currentPosition: 2 } })).to.be.rejectedWith( - "Error in reactor: (135) Position 2 invalid", + 'Validating node0.part0.switch.state: Constraint "max numberOfPositions - 1": Value 2 is not within bounds defined by constraint (135)', ); }); diff --git a/packages/node/test/behaviors/time-format-localization/TimeFormatLocalizationServerTest.ts b/packages/node/test/behaviors/time-format-localization/TimeFormatLocalizationServerTest.ts index 046c8dcc8a..b154de6bf4 100644 --- a/packages/node/test/behaviors/time-format-localization/TimeFormatLocalizationServerTest.ts +++ b/packages/node/test/behaviors/time-format-localization/TimeFormatLocalizationServerTest.ts @@ -42,7 +42,7 @@ describe("TimeFormatLocalizationServer", () => { }), ).throws( ConstraintError, - 'Validating node0.timeFormatLocalization.state: Constraint "in supportedCalendarTypes": Value 4 is not one of the values allowed by "in" constraint (135)', + 'Validating node0.timeFormatLocalization.state: Constraint "in SupportedCalendarTypes": Value 4 is not one of the values allowed by "in" constraint (135)', ); }); }); diff --git a/packages/node/test/node/ServerNodeTest.ts b/packages/node/test/node/ServerNodeTest.ts index 231379ccf2..17eb5e5649 100644 --- a/packages/node/test/node/ServerNodeTest.ts +++ b/packages/node/test/node/ServerNodeTest.ts @@ -4,11 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { CommissioningServer } from "#behavior/system/commissioning/CommissioningServer.js"; -import { BasicInformationBehavior } from "#behaviors/basic-information"; import { DescriptorBehavior } from "#behaviors/descriptor"; import { PumpConfigurationAndControlServer } from "#behaviors/pump-configuration-and-control"; -import { GeneralCommissioning } from "#clusters/general-commissioning"; import { PumpConfigurationAndControl } from "#clusters/pump-configuration-and-control"; import { ColorTemperatureLightDevice } from "#devices/color-temperature-light"; import { ExtendedColorLightDevice } from "#devices/extended-color-light"; @@ -21,38 +18,23 @@ import { AggregatorEndpoint } from "#endpoints/aggregator"; import { Bytes, CrashedDependenciesError, - Crypto, DnsCodec, DnsMessage, DnsRecordType, Environment, - Key, MockUdpChannel, NetworkSimulator, - PrivateKey, StorageBackendMemory, StorageManager, StorageService, } from "#general"; import { ServerNode } from "#node/ServerNode.js"; -import { AttestationCertificateManager, CertificationDeclarationManager, FabricManager } from "#protocol"; -import { NodeId, VendorId } from "#types"; +import { AttestationCertificateManager, CertificationDeclarationManager } from "#protocol"; +import { VendorId } from "#types"; import { MockServerNode } from "./mock-server-node.js"; +import { CommissioningHelper, testFactoryReset } from "./node-helpers.js"; -let commissionForFabricNumber: number | undefined = undefined; - -Crypto.get().createKeyPair = () => { - const DEFAULT_SEC1_KEY = Bytes.fromHex( - "30770201010420aef3484116e9481ec57be0472df41bf499064e5024ad869eca5e889802d48075a00a06082a8648ce3d030107a144034200043c398922452b55caf389c25bd1bca4656952ccb90e8869249ad8474653014cbf95d687965e036b521c51037e6b8cedefca1eb44046694fa08882eed6519decba", - ); - - const sec1Key = - commissionForFabricNumber !== undefined - ? Fixtures.fabrics[commissionForFabricNumber]?.sec1Key - : DEFAULT_SEC1_KEY; - - return Key({ sec1: sec1Key }) as PrivateKey; -}; +const commissioning = CommissioningHelper(); describe("ServerNode", () => { before(() => { @@ -60,7 +42,7 @@ describe("ServerNode", () => { }); beforeEach(() => { - commissionForFabricNumber = undefined; + commissioning.fabricNumber = undefined; }); describe("emits correct lifecycle changes", () => { @@ -226,7 +208,7 @@ describe("ServerNode", () => { }); it("commissions", async () => { - const { node } = await commission(); + const { node } = await commissioning.commission(); await MockTime.resolve(node.cancel()); @@ -234,7 +216,7 @@ describe("ServerNode", () => { }); it("times out commissioning", async () => { - const { node } = await almostCommission(); + const { node } = await commissioning.almostCommission(); const opcreds = node.state.operationalCredentials; @@ -306,7 +288,7 @@ describe("ServerNode", () => { }); it("decommissions and recommissions", async () => { - const { node, contextOptions } = await commission(); + const { node, contextOptions } = await commissioning.commission(); const fabricIndex = await node.online( contextOptions, @@ -333,39 +315,11 @@ describe("ServerNode", () => { if (!node.lifecycle.isOnline) { await MockTime.resolve(node.lifecycle.online); } - await commission(node); + await commissioning.commission(node); await node.close(); }); - async function testFactoryReset(mode: "online" | "offline-after-commission" | "offline") { - let node: MockServerNode; - if (mode !== "offline") { - ({ node } = await commission()); - } else { - node = await MockServerNode.createOnline({ online: false }); - } - - if (mode === "offline-after-commission") { - await node.cancel(); - } - - await MockTime.resolve(node.erase()); - - // Confirm previous online state is resumed - expect(node.lifecycle.isOnline).equals(mode === "online"); - - // Confirm basic state information is present - expect(node.stateOf(BasicInformationBehavior).vendorName).equals("Matter.js Test Vendor"); - - // Confirm pairing codes are available - const pairingCodes = node.stateOf(CommissioningServer).pairingCodes; - expect(typeof pairingCodes).equals("object"); - expect(typeof pairingCodes.manualPairingCode).equals("string"); - - await node.close(); - } - it("factory resets when offline after commission", async () => { await testFactoryReset("offline-after-commission"); }); @@ -379,7 +333,7 @@ describe("ServerNode", () => { }); it("commissions twice", async () => { - const { node } = await commission(); + const { node } = await commissioning.commission(); let lastCommissionedFabricCount; node.events.operationalCredentials.commissionedFabrics$Changed.on(commissionedFabrics => { @@ -396,7 +350,7 @@ describe("ServerNode", () => { lastFabricsCount = fabrics.length; }); - await commission(node, 1); + await commissioning.commission(node, 1); expect(node.state.operationalCredentials.nocs.length).equals(2); expect(Object.keys(node.state.commissioning.fabrics).length).equals(2); @@ -426,7 +380,7 @@ describe("ServerNode", () => { const node = await MockServerNode.createOnline({ device: aggregator }); - await commission(node); + await commissioning.commission(node); expect(node.stateOf(DescriptorBehavior).partsList).deep.equals([aggregator.number, light.number, pump.number]); expect(aggregator.stateOf(DescriptorBehavior).partsList).deep.equals([light.number, pump.number]); @@ -518,8 +472,9 @@ describe("ServerNode", () => { id: "foo", number: 1, colorControl: { - startUpColorTemperatureMireds: 0, - coupleColorTempToLevelMinMireds: 0, + colorMode: 0, + startUpColorTemperatureMireds: 1, + coupleColorTempToLevelMinMireds: 1, }, }); @@ -538,8 +493,8 @@ describe("ServerNode", () => { id: "foo", number: 1, colorControl: { - startUpColorTemperatureMireds: 0, - coupleColorTempToLevelMinMireds: 0, + startUpColorTemperatureMireds: 1, + coupleColorTempToLevelMinMireds: 1, }, }); @@ -548,91 +503,7 @@ describe("ServerNode", () => { }); }); -async function almostCommission(node?: MockServerNode, number = 0) { - if (!node) { - node = await MockServerNode.createOnline(); - } - - const params = Fixtures.fabrics[number]; - commissionForFabricNumber = number; - - const exchange = await node.createExchange(); - - const context = { exchange, command: true }; - - await node.online(context, async agent => { - await agent.generalCommissioning.armFailSafe({ expiryLengthSeconds: Fixtures.failsafeLengthS, breadcrumb: 4 }); - }); - - await node.online(context, async agent => { - await agent.generalCommissioning.setRegulatoryConfig({ - newRegulatoryConfig: 2, - countryCode: "XX", - breadcrumb: 5, - }); - }); - - await node.online(context, async agent => { - await agent.operationalCredentials.certificateChainRequest({ certificateType: 2 }); - }); - - await node.online(context, async agent => { - await agent.operationalCredentials.certificateChainRequest({ certificateType: 1 }); - }); - - await node.online(context, async agent => { - await agent.operationalCredentials.attestationRequest({ attestationNonce: params.attestationNonce }); - }); - - await node.online(context, async agent => { - await agent.operationalCredentials.csrRequest({ csrNonce: params.csrNonce }); - }); - - await node.online(context, async agent => { - agent.operationalCredentials.addTrustedRootCertificate({ rootCaCertificate: params.caCert }); - }); - - await node.online(context, async agent => { - const result = await agent.operationalCredentials.addNoc({ - nocValue: params.nocValue, - icacValue: params.icacValue, - ipkValue: params.ipkValue, - caseAdminSubject: NodeId((number + 1) * 100), - adminVendorId: VendorId(65521), - }); - expect(result.statusCode).deep.equals(0); - }); - - return { node, context }; -} - -async function commission(existingNode?: MockServerNode, number = 0) { - const { node } = await almostCommission(existingNode, number); - - // Do not reuse session from initial commissioning because we must now move from CASE to PASE - const fabric = node.env.get(FabricManager).fabrics[number]; - const contextOptions = { - exchange: await node.createExchange({ - fabric, - peerNodeId: NodeId(number + 1), - }), - command: true, - }; - - await node.online(contextOptions, async agent => { - // Use MockTime.resolve to wait for broadcaster cleanup - const result = await MockTime.resolve(agent.generalCommissioning.commissioningComplete()); - expect(result).deep.equals({ errorCode: GeneralCommissioning.CommissioningError.Ok, debugText: "" }); - }); - - if (!node.lifecycle.isCommissioned) { - await node.lifecycle.commissioned; - } - - return { node, contextOptions }; -} - -namespace Fixtures { +export namespace Fixtures { function u(hex: string) { return Bytes.fromHex(hex); } diff --git a/packages/node/test/node/node-helpers.ts b/packages/node/test/node/node-helpers.ts new file mode 100644 index 0000000000..cf911f2232 --- /dev/null +++ b/packages/node/test/node/node-helpers.ts @@ -0,0 +1,175 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { BasicInformationBehavior } from "#behaviors/basic-information"; +import { GeneralCommissioning } from "#clusters/general-commissioning"; +import { Bytes, Crypto, Key, PrivateKey } from "#general"; +import { CommissioningServer } from "#index.js"; +import { FabricManager } from "#protocol"; +import { NodeId, VendorId } from "#types"; +import { MockServerNode } from "./mock-server-node.js"; +import { Fixtures } from "./ServerNodeTest.js"; + +let activeCommissioning: undefined | ReturnType; + +Crypto.get().createKeyPair = () => { + const DEFAULT_SEC1_KEY = Bytes.fromHex( + "30770201010420aef3484116e9481ec57be0472df41bf499064e5024ad869eca5e889802d48075a00a06082a8648ce3d030107a144034200043c398922452b55caf389c25bd1bca4656952ccb90e8869249ad8474653014cbf95d687965e036b521c51037e6b8cedefca1eb44046694fa08882eed6519decba", + ); + + const sec1Key = + activeCommissioning?.fabricNumber !== undefined + ? Fixtures.fabrics[activeCommissioning.fabricNumber]?.sec1Key + : DEFAULT_SEC1_KEY; + + return Key({ sec1: sec1Key }) as PrivateKey; +}; + +export async function testFactoryReset(mode: "online" | "offline-after-commission" | "offline") { + let node: MockServerNode; + if (mode !== "offline") { + ({ node } = await CommissioningHelper().commission()); + } else { + node = await MockServerNode.createOnline({ online: false }); + } + + if (mode === "offline-after-commission") { + await node.cancel(); + } + + // We want to confirm unique ID is reset but the ID is not random in testing. So set to something known we can + // compare after reset + const oldUniqueId = "asdf"; + await node.set({ basicInformation: { uniqueId: oldUniqueId } }); + + await MockTime.resolve(node.erase()); + + // Confirm previous online state is resumed + expect(node.lifecycle.isOnline).equals(mode === "online"); + + // Confirm basic state information is present + expect(node.stateOf(BasicInformationBehavior).vendorName).equals("Matter.js Test Vendor"); + + // Confirm unique ID did not persist + expect(node.state.basicInformation.uniqueId).not.equals(oldUniqueId); + + // Confirm pairing codes are available + const pairingCodes = node.stateOf(CommissioningServer).pairingCodes; + expect(typeof pairingCodes).equals("object"); + expect(typeof pairingCodes.manualPairingCode).equals("string"); + + await node.close(); +} + +export function CommissioningHelper() { + return { + fabricNumber: undefined as number | undefined, + + async almostCommission(node?: MockServerNode, number = 0) { + activeCommissioning = this; + + try { + if (!node) { + node = await MockServerNode.createOnline(); + } + + const params = Fixtures.fabrics[number]; + this.fabricNumber = number; + + const exchange = await node.createExchange(); + + const context = { exchange, command: true }; + + await node.online(context, async agent => { + await agent.generalCommissioning.armFailSafe({ + expiryLengthSeconds: Fixtures.failsafeLengthS, + breadcrumb: 4, + }); + }); + + await node.online(context, async agent => { + await agent.generalCommissioning.setRegulatoryConfig({ + newRegulatoryConfig: 2, + countryCode: "XX", + breadcrumb: 5, + }); + }); + + await node.online(context, async agent => { + await agent.operationalCredentials.certificateChainRequest({ certificateType: 2 }); + }); + + await node.online(context, async agent => { + await agent.operationalCredentials.certificateChainRequest({ certificateType: 1 }); + }); + + await node.online(context, async agent => { + await agent.operationalCredentials.attestationRequest({ + attestationNonce: params.attestationNonce, + }); + }); + + await node.online(context, async agent => { + await agent.operationalCredentials.csrRequest({ csrNonce: params.csrNonce }); + }); + + await node.online(context, async agent => { + agent.operationalCredentials.addTrustedRootCertificate({ rootCaCertificate: params.caCert }); + }); + + await node.online(context, async agent => { + const result = await agent.operationalCredentials.addNoc({ + nocValue: params.nocValue, + icacValue: params.icacValue, + ipkValue: params.ipkValue, + caseAdminSubject: NodeId((number + 1) * 100), + adminVendorId: VendorId(65521), + }); + expect(result.statusCode).deep.equals(0); + }); + + return { node, context }; + } finally { + activeCommissioning = undefined; + } + }, + + async commission(existingNode?: MockServerNode, number = 0) { + try { + activeCommissioning = this; + + const { node } = await this.almostCommission(existingNode, number); + + // Do not reuse session from initial commissioning because we must now move from CASE to PASE + const fabric = node.env.get(FabricManager).fabrics[number]; + const contextOptions = { + exchange: await node.createExchange({ + fabric, + peerNodeId: NodeId(number + 1), + }), + command: true, + }; + + await node.online(contextOptions, async agent => { + // Use MockTime.resolve to wait for broadcaster cleanup + const result = await MockTime.resolve(agent.generalCommissioning.commissioningComplete()); + expect(result).deep.equals({ + errorCode: GeneralCommissioning.CommissioningError.Ok, + debugText: "", + }); + }); + + if (!node.lifecycle.isCommissioned) { + await node.lifecycle.commissioned; + } + + return { node, contextOptions }; + } finally { + activeCommissioning = undefined; + } + }, + }; +} diff --git a/packages/nodejs-ble/src/tsconfig.json b/packages/nodejs-ble/src/tsconfig.json index e51060e93d..9397725292 100644 --- a/packages/nodejs-ble/src/tsconfig.json +++ b/packages/nodejs-ble/src/tsconfig.json @@ -12,6 +12,9 @@ { "path": "../../protocol/src" }, + { + "path": "../../tools/src" + }, { "path": "../../types/src" } diff --git a/packages/nodejs-shell/src/tsconfig.json b/packages/nodejs-shell/src/tsconfig.json index 7acf535bb7..6725d45709 100644 --- a/packages/nodejs-shell/src/tsconfig.json +++ b/packages/nodejs-shell/src/tsconfig.json @@ -17,6 +17,9 @@ }, { "path": "../../nodejs/src" + }, + { + "path": "../../tools/src" } ] } \ No newline at end of file diff --git a/packages/nodejs/src/tsconfig.json b/packages/nodejs/src/tsconfig.json index d2d6fbcf01..99e2abe9d2 100644 --- a/packages/nodejs/src/tsconfig.json +++ b/packages/nodejs/src/tsconfig.json @@ -24,6 +24,9 @@ { "path": "../../testing/src" }, + { + "path": "../../tools/src" + }, { "path": "../../types/src" } diff --git a/packages/nodejs/test/IntegrationTest.ts b/packages/nodejs/test/IntegrationTest.ts index d66bcc829d..d997b12574 100644 --- a/packages/nodejs/test/IntegrationTest.ts +++ b/packages/nodejs/test/IntegrationTest.ts @@ -165,6 +165,7 @@ describe("Integration Test", () => { productName, productId, partNumber: "123456", + uniqueId: "supdog", nodeLabel: "", location: "US", reachable: true, @@ -540,7 +541,7 @@ describe("Integration Test", () => { ], }); - assert.equal(response.length, 42); + assert.equal(response.length, 43); assert.equal( response.filter( ({ path: { endpointId, clusterId } }) => endpointId === 0 && clusterId === Descriptor.Cluster.id, @@ -583,7 +584,7 @@ describe("Integration Test", () => { ({ path: { endpointId, clusterId } }) => endpointId === 0 && clusterId === BasicInformation.Cluster.id, ).length, - 23, + 24, ); const softwareVersionStringData = response.find( ({ path: { endpointId, clusterId, attributeId } }) => @@ -1252,6 +1253,7 @@ describe("Integration Test", () => { softwareVersion: 1, softwareVersionString: "v1", specificationVersion: Specification.SPECIFICATION_VERSION, + uniqueId: "supdog", vendorId: 65521, vendorName: "matter-node.js", }, @@ -1314,6 +1316,7 @@ describe("Integration Test", () => { productName, productId, partNumber: "123456", + uniqueId: "snotupdog", nodeLabel: "", location: "US", reachable: true, @@ -1459,6 +1462,7 @@ describe("Integration Test", () => { softwareVersion: 1, softwareVersionString: "v1", specificationVersion: Specification.SPECIFICATION_VERSION, + uniqueId: "supdog", vendorId: 65521, vendorName: "matter-node.js", }, @@ -1525,6 +1529,7 @@ describe("Integration Test", () => { softwareVersion: 1, softwareVersionString: "v1", specificationVersion: Specification.SPECIFICATION_VERSION, + uniqueId: "snotupdog", vendorId: 65521, vendorName: "matter-node.js", }, @@ -1776,6 +1781,7 @@ describe("Integration Test", () => { softwareVersion: 1, softwareVersionString: "v1", specificationVersion: Specification.SPECIFICATION_VERSION, + uniqueId: "supdog", vendorId: 65521, vendorName: "matter-node.js", }, @@ -1831,6 +1837,7 @@ describe("Integration Test", () => { softwareVersion: 1, softwareVersionString: "v1", specificationVersion: Specification.SPECIFICATION_VERSION, + uniqueId: "snotupdog", vendorId: 65521, vendorName: "matter-node.js", }, @@ -1904,6 +1911,7 @@ describe("Integration Test", () => { softwareVersion: 1, softwareVersionString: "v1", specificationVersion: Specification.SPECIFICATION_VERSION, + uniqueId: "supdog", vendorId: 65521, vendorName: "matter-node.js", }, diff --git a/packages/nodejs/test/cluster/GeneralCommissioningServerTest.ts b/packages/nodejs/test/cluster/GeneralCommissioningServerTest.ts index 80c33fc5f1..6b4f8a5dfb 100644 --- a/packages/nodejs/test/cluster/GeneralCommissioningServerTest.ts +++ b/packages/nodejs/test/cluster/GeneralCommissioningServerTest.ts @@ -55,6 +55,7 @@ describe("GeneralCommissioning Server test", () => { productId: 1, productName: "test", nodeLabel: "", + uniqueId: "", hardwareVersion: 0, hardwareVersionString: "0", location, diff --git a/packages/nodejs/test/interaction/InteractionProtocolTest.ts b/packages/nodejs/test/interaction/InteractionProtocolTest.ts index 618607c875..c5ffdd4300 100644 --- a/packages/nodejs/test/interaction/InteractionProtocolTest.ts +++ b/packages/nodejs/test/interaction/InteractionProtocolTest.ts @@ -867,25 +867,25 @@ const wildcardTestCases: { wildcardPathFilter?: TypeFromPartialBitSchema; count: number; }[] = [ - { testCase: "no", clusterId: ClusterId(0x28), wildcardPathFilter: undefined, count: 20 }, + { testCase: "no", clusterId: ClusterId(0x28), wildcardPathFilter: undefined, count: 21 }, { testCase: "skipRootNode", clusterId: ClusterId(0x28), wildcardPathFilter: { skipRootNode: true }, count: 0 }, // all sorted out { testCase: "skipGlobalAttributes", clusterId: ClusterId(0x28), wildcardPathFilter: { skipGlobalAttributes: true }, - count: 17, + count: 18, }, // 4 less { testCase: "skipAttributeList", clusterId: ClusterId(0x28), wildcardPathFilter: { skipAttributeList: true }, - count: 19, + count: 20, }, // 1 less { testCase: "skipCommandLists", clusterId: ClusterId(0x28), wildcardPathFilter: { skipCommandLists: true }, - count: 18, + count: 19, }, // 2 less { testCase: "skipFixedAttributes", @@ -897,7 +897,7 @@ const wildcardTestCases: { testCase: "skipChangesOmittedAttributes", clusterId: ClusterId(0x28), wildcardPathFilter: { skipChangesOmittedAttributes: true }, - count: 20, + count: 21, }, // nothing filtered { testCase: "no for WiFiDiag", @@ -993,6 +993,7 @@ describe("InteractionProtocol", () => { productName: "product", productId: 2, nodeLabel: "", + uniqueId: "", hardwareVersion: 0, hardwareVersionString: "0", location: "US", @@ -1164,7 +1165,6 @@ describe("InteractionProtocol", () => { AccessControlCluster, { acl: [], - extension: [], subjectsPerAccessControlEntry: 4, targetsPerAccessControlEntry: 4, accessControlEntriesPerFabric: 4, @@ -1172,7 +1172,6 @@ describe("InteractionProtocol", () => { {}, { accessControlEntryChanged: true, - accessControlExtensionChanged: true, }, ); @@ -1289,6 +1288,7 @@ describe("InteractionProtocol", () => { productName: "product", productId: 2, nodeLabel: "", + uniqueId: "", hardwareVersion: 0, hardwareVersionString: "0", location: "US", @@ -1334,6 +1334,7 @@ describe("InteractionProtocol", () => { productName: "product", productId: 2, nodeLabel: "", + uniqueId: "", hardwareVersion: 0, hardwareVersionString: "0", location: "US", diff --git a/packages/protocol/src/tsconfig.json b/packages/protocol/src/tsconfig.json index 454de9957d..29cca1065f 100644 --- a/packages/protocol/src/tsconfig.json +++ b/packages/protocol/src/tsconfig.json @@ -16,6 +16,9 @@ { "path": "../../testing/src" }, + { + "path": "../../tools/src" + }, { "path": "../../types/src" } diff --git a/packages/react-native/src/tsconfig.json b/packages/react-native/src/tsconfig.json index 38f8252871..bdda116065 100644 --- a/packages/react-native/src/tsconfig.json +++ b/packages/react-native/src/tsconfig.json @@ -12,6 +12,9 @@ }, { "path": "../../protocol/src" + }, + { + "path": "../../tools/src" } ] } \ No newline at end of file diff --git a/packages/testing/package.json b/packages/testing/package.json index 21be1ae37b..3e3bd015a2 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -41,7 +41,8 @@ }, "homepage": "https://github.com/project-chip/matter.js#readme", "imports": { - "#tools": "@matter/tools" + "#tools": "@matter/tools", + "#tools/ansi-text": "@matter/tools/ansi-text" }, "dependencies": { "@matter/tools": "0.0.0-git", diff --git a/packages/testing/src/chip/matter-js-pics.properties b/packages/testing/src/chip/matter-js-pics.properties index a5e9342bc9..f77c150135 100644 --- a/packages/testing/src/chip/matter-js-pics.properties +++ b/packages/testing/src/chip/matter-js-pics.properties @@ -85,4 +85,7 @@ TMP.M.ManuallyControlled=0 OO.C=0 # We do not support Color Control client cluster -CC.C=0 \ No newline at end of file +CC.C=0 + +# FLW 2.2 requires user input to change flow; the test skips the user prompt so subsequent command fails. This disables +FLW.M.FlowChange=0 \ No newline at end of file diff --git a/packages/testing/src/cli.ts b/packages/testing/src/cli.ts index 1d7c69184c..bf6d826089 100644 --- a/packages/testing/src/cli.ts +++ b/packages/testing/src/cli.ts @@ -9,7 +9,7 @@ import "./util/node-shims.js"; import "./global-definitions.js"; -import { Builder, Graph, Package, Project } from "#tools"; +import { Graph, Package, Project, ProjectBuilder } from "#tools"; import { clear } from "console"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; @@ -80,7 +80,7 @@ export async function main(argv = process.argv) { packageLocation = firstSpec; } - const builder = new Builder(); + const builder = new ProjectBuilder(); const pkg = new Package({ path: packageLocation }); // If the location is a workspace, test all packages with test diff --git a/packages/testing/src/failure-detail.ts b/packages/testing/src/failure-detail.ts index 23375d658a..e86bfdb041 100644 --- a/packages/testing/src/failure-detail.ts +++ b/packages/testing/src/failure-detail.ts @@ -4,35 +4,24 @@ * SPDX-License-Identifier: Apache-2.0 */ -import colors from "ansi-colors"; - export interface FailureDetail { message: string; stack?: string; - diff?: string; + stackLines?: string[]; + actual?: string; + expected?: string; logs?: string; cause?: FailureDetail; errors?: FailureDetail[]; } -export function FailureDetail(error: any, logs?: string[]) { - let diff: string | undefined; - - const { message, stack, cause, errors } = parseError(error); - - if (error.expected && error.actual) { - if (FailureDetail.diff === undefined) { - diff = "(no diff implementation installed)"; - } else { - diff = FailureDetail.diff(error.actual.toString(), error.expected.toString()); - diff = diff.trim().replace(/^ {6}/gms, ""); - } - } - +/** + * Captures all pertinent information about a failed test. + */ +export function FailureDetail(error: any, logs?: string[], parentStack?: string[]) { + const { message, stack, stackLines, cause, errors } = parseError(error, parentStack); const result = { message } as FailureDetail; - if (diff) { - result.diff = diff; - } + if (stack) { result.stack = stack; } @@ -45,46 +34,32 @@ export function FailureDetail(error: any, logs?: string[]) { if (errors) { result.errors = errors; } + if (stackLines) { + result.stackLines = stackLines; + } - return result; -} - -export namespace FailureDetail { - export function dump(failure: FailureDetail, prefix: string = "") { - process.stdout.write(colors.redBright(`${prefix}${failure.message}\n\n`)); - - if (failure.diff) { - process.stdout.write(`${prefix} ${failure.diff.replace(/\n/gm, "\n ")}\n\n`); - } - - if (failure.stack) { - process.stdout.write(`${prefix}${colors.dim(failure.stack.replace(/\n/gm, `\n${prefix}`))}\n\n`); - } - - if (failure.cause) { - process.stdout.write(`${prefix}Caused by:\n\n`); - dump(failure.cause, prefix); - } - - if (failure.errors?.length) { - let num = 0; - for (const cause of failure.errors) { - process.stdout.write(`${prefix}Cause #${++num}:\n\n`); - dump(cause, `${prefix} `); - } - } - - if (failure.logs) { - process.stdout.write(` ${failure.logs.replace(/\n/gm, "\n ")}\n\n`); - } + const { actual, expected } = error; + if (actual) { + result.actual = actual; + } + if (expected) { + result.expected = expected; } - export let diff: undefined | ((actual: string, expected: string) => string); + return result; } -function parseError(error: Error) { - let message, stack, cause: FailureDetail | undefined, errors: FailureDetail[] | undefined; +function messageAndStackFor( + error: Error, + parentStack?: string[], +): { message: string; stack?: string; stackLines?: string[] } { + // If an error formatting hook is installed, use that + if (MatterHooks?.messageAndStackFor) { + return MatterHooks.messageAndStackFor(error, parentStack); + } + // Fallback message formatting + let message, stack; if (error === undefined || error === null) { message = `(error is ${error})`; } else { @@ -100,27 +75,29 @@ function parseError(error: Error) { if (lines.length) { stack = lines.map(line => line.trim()).join("\n"); } - } else if (error.message) { - message = error.message; - } else { + } + + if (!message) { message = error.toString(); } - message = message.trim().replace(/Error: /, ""); + return { message, stack }; +} + +function parseError(error: Error, parentStack?: string[]) { + const { message, stack, stackLines } = messageAndStackFor(error, parentStack); - if (message.endsWith(":")) { - message = message.slice(0, message.length - 1); - } + let cause: FailureDetail | undefined, errors: FailureDetail[] | undefined; const errorCause = error.cause; if (errorCause) { - cause = FailureDetail(errorCause); + cause = FailureDetail(errorCause, undefined, stackLines); } const errorErrors = (error as AggregateError).errors; if (Array.isArray(errorErrors)) { - errors = errorErrors.map(e => FailureDetail(e)); + errors = errorErrors.map(e => FailureDetail(e, undefined, stackLines)); } - return { message, stack, cause, errors }; + return { message, stack, stackLines, cause, errors }; } diff --git a/packages/testing/src/failure-reporter.ts b/packages/testing/src/failure-reporter.ts new file mode 100644 index 0000000000..574923aef7 --- /dev/null +++ b/packages/testing/src/failure-reporter.ts @@ -0,0 +1,65 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ansi, Printer, screen } from "#tools"; +import { FailureDetail } from "./failure-detail.js"; +import { TextDiff } from "./text-diff.js"; + +const OUTER_PREFIX = `${ansi.red}▌ ${ansi.not.red}`; +const INNER_PREFIX = `${ansi.dim}┆ ${ansi.not.dim}`; + +export namespace FailureReporter { + export function report(out: Printer, failure: FailureDetail, title: string) { + out.state({ style: ansi.reset.white.bg.red }, () => { + out(screen.erase.toEol, "\n ", title, screen.erase.toEol, "\n", screen.erase.toEol, "\n"); + }); + + out(screen.erase.toEol); + + out.state({ linePrefix: OUTER_PREFIX }, () => { + dumpDetails(out, failure); + }); + } +} + +function dumpCause(out: Printer, failure: FailureDetail) { + out.state({ linePrefix: INNER_PREFIX }, () => { + dumpDetails(out, failure); + }); +} + +function dumpDetails(out: Printer, { message, actual, expected, stack, cause, errors, logs }: FailureDetail) { + out("\n", ansi.bright.red(message), "\n"); + + if (actual !== undefined && expected !== undefined) { + out("\n"); + out.state({ linePrefix: " " }, () => out(TextDiff(actual, expected))); + out("\n"); + } + + if (stack) { + out("\n"); + out.state({ linePrefix: " " }, () => out(stack)); + out("\n"); + } + + if (cause) { + out("\n", ansi.bold("Caused by:"), "\n"); + dumpCause(out, cause); + } + + if (errors?.length) { + let num = 0; + for (const cause of errors) { + out("\n", ansi.bold(`Cause #${++num}:`), "\n"); + dumpCause(out, cause); + } + } + + if (logs) { + out("\n", logs, "\n"); + } +} diff --git a/packages/testing/src/global-declarations.ts b/packages/testing/src/global-declarations.ts index f6f0e02c98..d36d116f77 100644 --- a/packages/testing/src/global-declarations.ts +++ b/packages/testing/src/global-declarations.ts @@ -52,6 +52,14 @@ declare global { * Receive intercepted log messages. */ loggerSink?: (level: number, message: string) => void; + + /** + * Extract error details. + */ + messageAndStackFor?: ( + error: unknown, + parentStack?: string[], + ) => { message: string; stack?: string; stackLines?: string[] }; }; namespace Mocha { diff --git a/packages/testing/src/mocha.ts b/packages/testing/src/mocha.ts index d1acab79b0..060b15c10c 100644 --- a/packages/testing/src/mocha.ts +++ b/packages/testing/src/mocha.ts @@ -11,9 +11,11 @@ import { FailureDetail } from "./failure-detail.js"; import { Boot } from "./mocks/boot.js"; import { LoggerHooks } from "./mocks/logging.js"; import { TestOptions } from "./options.js"; -import { ConsoleProxyReporter, Reporter } from "./reporter.js"; +import { Reporter } from "./reporter.js"; import type { TestDescriptor } from "./test-descriptor.js"; +import { TextDiff } from "./text-diff.js"; import { wtf } from "./util/wtf.js"; +import { WebReporter } from "./web-reporter.js"; // We allow fixed 60s. timeout for our extended "before/after each test" hooks. To make this configurable we'd need // to perform timeout handling ourselves so avoiding for now @@ -92,7 +94,7 @@ export function generalSetup(mocha: Mocha) { return (this.currentTest as HookableTest)[afterOneHook]?.call(this, done); }); - FailureDetail.diff = Base.generateDiff.bind(Base); + TextDiff.generator = Base.generateDiff.bind(Base); } export function extendApi(Mocha: typeof MochaType) { @@ -262,7 +264,7 @@ export function browserSetup(mocha: BrowserMocha) { // Start Mocha, proxying reporting through console to Playwright and completing once Mocha has finished auto: async function (options: TestOptions) { TestOptions.apply(mocha, options); - mocha.reporter(adaptReporter(Mocha, "Web", new ConsoleProxyReporter())); + mocha.reporter(adaptReporter(Mocha, "Web", new WebReporter())); return new Promise(accept => { const runner = this.start(); runner.on("end", accept); diff --git a/packages/testing/src/mocks/logging.ts b/packages/testing/src/mocks/logging.ts index 210b0e2c76..55b779c115 100644 --- a/packages/testing/src/mocks/logging.ts +++ b/packages/testing/src/mocks/logging.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import colors from "ansi-colors"; +import { ansi, Wrapper } from "#tools/ansi-text"; interface LoggerLike { format: string; @@ -22,7 +22,7 @@ export const TheMockLogger: MockLogger = { }; function formatExternalMessage(source: string, text: string) { - return `${colors.bgCyan.black.bold(` ${source} `)} ${colors.dim(text)}`; + return `${Wrapper.prefixStart}${ansi.black.bg.cyan.bold(` ${source} `)} ${Wrapper.prefixStop}${ansi.dim(text)}`; } /** diff --git a/packages/testing/src/nodejs-reporter.ts b/packages/testing/src/nodejs-reporter.ts new file mode 100644 index 0000000000..64d5c4bf75 --- /dev/null +++ b/packages/testing/src/nodejs-reporter.ts @@ -0,0 +1,123 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Progress, ansi, std } from "#tools"; +import { FailureDetail } from "./failure-detail.js"; +import { FailureReporter } from "./failure-reporter.js"; +import { Failure, Reporter, Stats } from "./reporter.js"; + +/** + * Test UI for Node.js. + */ +export abstract class NodejsReporter implements Reporter { + #run = ""; + #suite = Array(); + #test?: string; + #step?: string; + #stats?: Stats; + #failures = Array(); + #lastTitle?: string; + + constructor(private progress: Progress) {} + + beginRun(name: string, stats: Stats | undefined, supportsSuites = true): void { + this.#run = name; + this.#suite = []; + this.#failures = []; + if (!supportsSuites) { + this.progress.update(this.#summarize(stats)); + } + } + + beginSuite(name: string[]): void { + this.#suite = name; + } + + beginTest(name: string, stats?: Stats): void { + this.#test = name; + this.#stats = stats; + this.#step = undefined; + + // If not a TTY, only update once per suite to keep the line count down for e.g. GH action logs + const title = process.stdout.isTTY ? this.#formatName(this.#suite, name) : this.#suite[0]; + this.#updateTitle(title); + } + + beginStep(name: string): void { + this.#step = name; + + if (process.stdout.isTTY && this.#test) { + const title = this.#formatName(this.#suite, this.#test, name); + this.#updateTitle(title); + } + } + + #updateTitle(title: string) { + if (title === this.#lastTitle) { + return; + } + this.#lastTitle = title; + this.progress.update(this.#summarize(this.#stats), title); + } + + failTest(name: string, detail: FailureDetail) { + this.#failures.push({ + suite: this.#suite, + test: name, + step: this.#step, + detail, + }); + } + + abstract failRun(detail: FailureDetail): void; + + endRun(stats?: Stats): void { + if (this.#failures.length) { + this.progress.failure(this.#summarize(stats)); + this.#dumpFailures(); + } else if (stats && !stats.complete) { + this.progress.failure("No tests found"); + } else { + this.progress.success(this.#summarize(stats)); + } + } + + #summarize(stats?: Stats) { + let statStr; + if (stats) { + const complete = ansi.dim(`${stats.complete}/${stats.total}`); + const failures = stats.failures ? ansi.bright.red(` ${stats.failures.toString()} failed`) : ""; + statStr = ` ${complete}${failures}`; + } else { + statStr = ""; + } + + return `${ansi.bold(this.#run)}${statStr}`; + } + + #dumpFailures() { + for (let i = 0; i < this.#failures.length; i++) { + if (i !== 0) { + std.out("\n"); + } + + const failure = this.#failures[i]; + const index = `Failure ${ansi.bold((i + 1).toString())} of ${this.#failures.length}`; + const title = `${index} ${this.#formatName(failure.suite, failure.test, failure.step)}`; + + FailureReporter.report(std.out, failure.detail, title); + } + } + + #formatName(suite: string[], test: string, step?: string) { + const breadcrumb = [...suite, test]; + if (step) { + breadcrumb.push(step); + } + breadcrumb[breadcrumb.length - 1] = ansi.bold(breadcrumb[breadcrumb.length - 1]).toString(); + return breadcrumb.join(" ➡ "); + } +} diff --git a/packages/testing/src/reporter.ts b/packages/testing/src/reporter.ts index 9e76350589..8a2852d4e7 100644 --- a/packages/testing/src/reporter.ts +++ b/packages/testing/src/reporter.ts @@ -4,8 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Progress } from "#tools"; -import colors from "ansi-colors"; import { FailureDetail } from "./failure-detail.js"; export type Stats = { @@ -30,148 +28,3 @@ export interface Failure { step?: string; detail: FailureDetail; } - -export abstract class ProgressReporter implements Reporter { - #run = ""; - #suite = Array(); - #test?: string; - #step?: string; - #stats?: Stats; - #failures = Array(); - #lastTitle?: string; - - constructor(private progress: Progress) {} - - beginRun(name: string, stats: Stats | undefined, supportsSuites = true): void { - this.#run = name; - this.#suite = []; - this.#failures = []; - if (!supportsSuites) { - this.progress.update(this.#summarize(stats)); - } - } - - beginSuite(name: string[]): void { - this.#suite = name; - } - - beginTest(name: string, stats?: Stats): void { - this.#test = name; - this.#stats = stats; - this.#step = undefined; - - // If not a TTY, only update once per suite to keep the line count down for e.g. GH action logs - const title = process.stdout.isTTY ? this.#formatName(this.#suite, name) : this.#suite[0]; - this.#updateTitle(title); - } - - beginStep(name: string): void { - this.#step = name; - - if (process.stdout.isTTY && this.#test) { - const title = this.#formatName(this.#suite, this.#test, name); - this.#updateTitle(title); - } - } - - #updateTitle(title: string) { - if (title === this.#lastTitle) { - return; - } - this.#lastTitle = title; - this.progress.update(this.#summarize(this.#stats), title); - } - - failTest(name: string, detail: FailureDetail) { - this.#failures.push({ - suite: this.#suite, - test: name, - step: this.#step, - detail, - }); - } - - abstract failRun(detail: FailureDetail): void; - - endRun(stats?: Stats): void { - if (this.#failures.length) { - this.progress.failure(this.#summarize(stats)); - this.#dumpFailures(); - } else if (stats && !stats.complete) { - this.progress.failure("No tests found"); - } else { - this.progress.success(this.#summarize(stats)); - } - } - - #summarize(stats?: Stats) { - let statStr; - if (stats) { - const complete = colors.dim(`${stats.complete}/${stats.total}`); - const failures = stats.failures ? colors.redBright(` ${stats.failures.toString()} failed`) : ""; - statStr = ` ${complete}${failures}`; - } else { - statStr = ""; - } - - return `${colors.bold(this.#run)}${statStr}`; - } - - #dumpFailures() { - for (let i = 0; i < this.#failures.length; i++) { - const failure = this.#failures[i]; - const index = `Failure ${colors.bold((i + 1).toString())} of ${this.#failures.length}`; - process.stdout.write(`\n${index} ${this.#formatName(failure.suite, failure.test, failure.step)}\n\n`); - - FailureDetail.dump(failure.detail, " "); - } - } - - #formatName(suite: string[], test: string, step?: string) { - const breadcrumb = [...suite, test]; - if (step) { - breadcrumb.push(step); - } - breadcrumb[breadcrumb.length - 1] = colors.bold(breadcrumb[breadcrumb.length - 1]); - return breadcrumb.join(" ➡ "); - } -} - -const actualConsole = console; -const actualLog = actualConsole.log; - -function proxy(...args: any[]) { - actualLog.call(actualConsole, `${ConsoleProxyReporter.FLAG}${JSON.stringify(args)}`); -} - -export class ConsoleProxyReporter implements Reporter { - static FLAG = "<> "; - - beginRun(name: string, stats?: Stats) { - proxy("beginRun", name, stats); - } - - beginSuite(name: string[], stats?: Stats) { - proxy("beginSuite", name, stats); - } - - beginTest(name: string, stats?: Stats) { - proxy("beginTest", name, stats); - } - - beginStep(name: string) { - proxy("beginStep", name); - } - - endRun(stats?: Stats) { - proxy("endRun", stats); - } - - failTest(name: string, detail: FailureDetail) { - proxy("failTest", name, detail); - } - - failRun(detail: FailureDetail) { - proxy("failRun", detail); - } -} diff --git a/packages/testing/src/runner.ts b/packages/testing/src/runner.ts index 34f644b756..baf0c20c8d 100644 --- a/packages/testing/src/runner.ts +++ b/packages/testing/src/runner.ts @@ -4,15 +4,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { Package, Progress } from "#tools"; -import colors from "ansi-colors"; +import { ansi, Package, Progress, std } from "#tools"; import debug from "debug"; import { relative } from "path"; import { chip } from "./chip/chip.js"; import { FailureDetail } from "./failure-detail.js"; +import { FailureReporter } from "./failure-reporter.js"; +import { NodejsReporter } from "./nodejs-reporter.js"; import { testNodejs } from "./nodejs.js"; import { TestOptions } from "./options.js"; -import { ProgressReporter, Reporter } from "./reporter.js"; +import { Reporter } from "./reporter.js"; import { listSupportFiles } from "./util/files.js"; import { testWeb } from "./web.js"; @@ -27,13 +28,15 @@ export class TestRunner { ) { chip.runner = this; - this.reporter = new (class extends ProgressReporter { + this.reporter = new (class extends NodejsReporter { constructor() { super(progress); } + override failRun(detail: FailureDetail) { - process.stdout.write("\n"); - FailureDetail.dump(detail); + std.err.write("\n"); + FailureReporter.report(std.err, detail, "Test suite crash"); + std.err.write("\n"); process.exit(1); } })(); @@ -87,6 +90,6 @@ export class TestRunner { } function fatal(message: string) { - process.stderr.write(colors.redBright(`\n${message}\n\n`)); + std.err.write(ansi.bright.red(`\n${message}\n\n`)); process.exit(1); } diff --git a/packages/testing/src/text-diff.ts b/packages/testing/src/text-diff.ts new file mode 100644 index 0000000000..1457887592 --- /dev/null +++ b/packages/testing/src/text-diff.ts @@ -0,0 +1,16 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +export function TextDiff(actual: string, expected: string) { + if (TextDiff.generator) { + return TextDiff.generator(actual, expected); + } + return "(no diff generator installed)"; +} + +export namespace TextDiff { + export let generator: undefined | ((actual: string, expected: string) => string); +} diff --git a/packages/testing/src/tsconfig.json b/packages/testing/src/tsconfig.json index c93a1a6c53..3c18fbb416 100644 --- a/packages/testing/src/tsconfig.json +++ b/packages/testing/src/tsconfig.json @@ -8,5 +8,9 @@ "include": [ "**/*.ts" ], - "references": [] + "references": [ + { + "path": "../../tools/src" + } + ] } \ No newline at end of file diff --git a/packages/testing/src/web-reporter.ts b/packages/testing/src/web-reporter.ts new file mode 100644 index 0000000000..86ddfdd1af --- /dev/null +++ b/packages/testing/src/web-reporter.ts @@ -0,0 +1,51 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { FailureDetail } from "./failure-detail.js"; +import { Reporter, Stats } from "./reporter.js"; + +// Save these so we can avoid any trapping logic and write directly to the console +const actualConsole = console; +const actualLog = actualConsole.log; +function proxy(...args: any[]) { + actualLog.call(actualConsole, `${WebReporter.FLAG}${JSON.stringify(args)}`); +} + +/** + * Test UI for web browsers. Encodes each reporting method to the console. This is a simple way to convey messages + * from the browser to the test harness. + */ +export class WebReporter implements Reporter { + static FLAG = "<> "; + + beginRun(name: string, stats?: Stats) { + proxy("beginRun", name, stats); + } + + beginSuite(name: string[], stats?: Stats) { + proxy("beginSuite", name, stats); + } + + beginTest(name: string, stats?: Stats) { + proxy("beginTest", name, stats); + } + + beginStep(name: string) { + proxy("beginStep", name); + } + + endRun(stats?: Stats) { + proxy("endRun", stats); + } + + failTest(name: string, detail: FailureDetail) { + proxy("failTest", name, detail); + } + + failRun(detail: FailureDetail) { + proxy("failRun", detail); + } +} diff --git a/packages/testing/src/web.ts b/packages/testing/src/web.ts index a5d01c4937..c1fcefe7a9 100644 --- a/packages/testing/src/web.ts +++ b/packages/testing/src/web.ts @@ -13,8 +13,9 @@ import { AddressInfo } from "net"; import { relative } from "path"; import { Browser, chromium, ConsoleMessage, Page } from "playwright"; import { TestOptions } from "./options.js"; -import { ConsoleProxyReporter, Reporter } from "./reporter.js"; +import { Reporter } from "./reporter.js"; import type { TestRunner } from "./runner.js"; +import { WebReporter } from "./web-reporter.js"; export async function testWeb(runner: TestRunner, manual: boolean) { const files = await runner.loadFiles("esm"); @@ -105,13 +106,13 @@ function consoleHandler(reporter: Reporter) { const text = message.text(); // If it's not an encoded reporter update, write to normal console - if (type !== "log" || !text.startsWith(ConsoleProxyReporter.FLAG)) { + if (type !== "log" || !text.startsWith(WebReporter.FLAG)) { console[type](text); return; } // Invoke reporter - const args: string[] = JSON.parse(text.slice(ConsoleProxyReporter.FLAG.length)); + const args: string[] = JSON.parse(text.slice(WebReporter.FLAG.length)); const method = (reporter as any)[args[0]]; if (typeof method !== "function") { throw new Error(`Invalid encoded reporter update method ${args[0]}`); diff --git a/packages/tools/package.json b/packages/tools/package.json index 9693a3c3f1..d356fff76e 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -25,6 +25,16 @@ "default": "./dist/cjs/index.js" } }, + "./ansi-text": { + "import": { + "types": "./dist/esm/ansi-text/index.d.ts", + "default": "./dist/esm/ansi-text/index.js" + }, + "require": { + "types": "./dist/cjs/ansi-text/index.d.ts", + "default": "./dist/cjs/ansi-text/index.js" + } + }, "./bootstrap": { "import": { "default": "./src/util/bootstrap.mjs" diff --git a/packages/tools/src/ansi-text/chars.ts b/packages/tools/src/ansi-text/chars.ts new file mode 100644 index 0000000000..c41bac3b54 --- /dev/null +++ b/packages/tools/src/ansi-text/chars.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +export namespace Chars { + export const breakingSpace = new Set([ + " ", // Space + "\u1680", // Ask the Irish + "\u200b", // Zero-width space + "\u2000", + "\u2001", + "\u2002", + "\u2003", + "\u2004", + "\u2005", + "\u2006", + "\u2007", + "\u2008", + "\u2009", + "\u200a", + "\u205f", // Math space + "\u3000", // Ideographic space + ]); + + // eslint-disable-next-line no-misleading-character-class + export const zeroWidth = /[\u200b\u200c\u200d\u2060\p{Mn}\p{Me}]/u; + + export const nonbreakingText = /[\u00a0\u202f\p{Letter}\p{Mark}\p{Sm}\p{Sc}\p{Sk}\p{So}\p{Number}\p{Punctuation}]/u; +} diff --git a/packages/tools/src/ansi-text/consumer.ts b/packages/tools/src/ansi-text/consumer.ts new file mode 100644 index 0000000000..8ee96a8db4 --- /dev/null +++ b/packages/tools/src/ansi-text/consumer.ts @@ -0,0 +1,53 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Producer } from "./producer.js"; +import { Style } from "./style.js"; + +export interface Consumer { + /** + * Add text. + * + * If tokenized, the tokens must be in the form returned by {@link tokenize} for correct processing. + */ + write(...text: Producer.Sequence): void; + + /** + * Current state of the destination. + */ + readonly state: Consumer.State; + + /** + * Settle output state after generating all output. + */ + close(): void; +} + +export namespace Consumer { + export interface Options { + linePrefix?: string; + style?: Style; + terminalWidth?: number; + styleEnabled?: boolean; + buffer?: boolean; + } + + export interface State extends Options { + (options?: Options): Context; + (options?: Options, executor?: () => void): void; + + readonly availableWidth: number | undefined; + readonly remainingWidth: number | undefined; + + onRevert(fn: () => void): void; + offRevert(fn: () => void): void; + } + + export interface Context { + close(): void; + [Symbol.dispose](): void; + } +} diff --git a/packages/tools/src/ansi-text/contiguous-output-segment.ts b/packages/tools/src/ansi-text/contiguous-output-segment.ts new file mode 100644 index 0000000000..d4df2d5732 --- /dev/null +++ b/packages/tools/src/ansi-text/contiguous-output-segment.ts @@ -0,0 +1,181 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Producer } from "./producer.js"; +import { BreakingToken, NonbreakingToken, Token } from "./token.js"; + +/** + * A single output segment that should be presented contiguously if space allows. + */ +export class ContiguousOutputSegment implements Producer { + width = 0; + tokens: Token[]; + + constructor(...text: Producer.Sequence) { + this.tokens = [...Producer.of(text)]; + this.#addWidth(this.tokens); + } + + [Symbol.iterator]() { + return this.tokens[Symbol.iterator](); + } + + push(...text: Producer.Sequence) { + const tokens = [...Producer.of(text)]; + this.tokens.push(...tokens); + this.#addWidth(tokens); + } + + #addWidth(tokens: Token[]) { + for (const token of tokens) { + if ("width" in token) { + this.width += token.width; + } + } + } + + /** + * Create a scanner that can be used to move through the segment in chunks of visible characters. This is only + * necessary when wrapping segments that are too long to fit on a single line. + */ + scan(): ContiguousOutputSegment.Scanner { + let done = false; + const iterator = this.tokens[Symbol.iterator](); + let current: BreakingToken | NonbreakingToken | undefined; + let pos = 0; + return { + [Symbol.iterator]() { + return iterator; + }, + + get done() { + return done; + }, + + next() { + const next = iterator.next(); + if (next.done) { + done = true; + } + return next; + }, + + take(width: number) { + let widthSoFar = 0; + const result = Array(); + while (true) { + if (current !== undefined) { + const splitStart = pos; + let splitWidth = 0; + for (let i = splitStart; i < current.str.length; i++) { + const charCode = current.str.charCodeAt(0); + + // Zero-width characters + switch (charCode) { + case 0x200b: + case 0x200c: + case 0x200d: + case 0x2060: + case 0xfeff: + continue; + } + + // If we've hit the target width, split the current token if any portion of it fits and + // we are done + if (widthSoFar === width) { + pos = i; + if (splitStart !== pos) { + result.push({ + kind: current.kind, + str: current.str.slice(splitStart, pos), + width: splitWidth, + }); + } + return result; + } + + // Increase width + widthSoFar++; + splitWidth++; + + // Skip properly formed surrogate pair + if (charCode >= 0xd800 && charCode < 0xdc00) { + const charCode2 = current.str.charCodeAt(i + 1); + if (charCode2 !== undefined && charCode2 >= 0xdc00 && charCode2 < 0xe000) { + i++; + } + } + } + + // The remainder of the current token fits so we are done with it + if (splitStart === 0) { + // Entire token + result.push(current); + } else { + // Tailing portion of token + result.push({ + kind: current.kind, + str: current.str.slice(splitStart), + width: splitWidth, + }); + } + + current = undefined; + } + + // Process next token + const n = this.next(); + if (n.done) { + return result; + } + + // Control sequences do not contribute space + if (n.value.kind !== "breaking" && n.value.kind !== "nonbreaking") { + result.push(n.value); + continue; + } + + // Space and visible tokens require code unit scan + current = n.value; + } + }, + }; + } + + toString() { + return this.tokens + .map(token => { + switch (token.kind) { + case "style": + return token.style.toString(); + + case "ansi": + return token.sequence; + + case "breaking": + case "nonbreaking": + return token.str; + + case "tab": + return "\t"; + + case "carriage-return": + return "\r"; + + case "newline": + return "\n"; + } + }) + .join(""); + } +} + +export namespace ContiguousOutputSegment { + export interface Scanner extends IterableIterator { + done: boolean; + take(width: number): Token[]; + } +} diff --git a/packages/tools/src/ansi-text/index.ts b/packages/tools/src/ansi-text/index.ts new file mode 100644 index 0000000000..fd7a340e1b --- /dev/null +++ b/packages/tools/src/ansi-text/index.ts @@ -0,0 +1,14 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +// Note -- don't put ./std.js here because it's not cross platform + +export * from "./printer.js"; +export * from "./screen.js"; +export * from "./style.js"; +export * from "./text-builder.js"; +export * from "./text-writer.js"; +export * from "./wrapper.js"; diff --git a/packages/tools/src/ansi-text/printer.ts b/packages/tools/src/ansi-text/printer.ts new file mode 100644 index 0000000000..c6da508350 --- /dev/null +++ b/packages/tools/src/ansi-text/printer.ts @@ -0,0 +1,86 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Consumer } from "./consumer.js"; +import { Producer } from "./producer.js"; +import { Truncator } from "./truncator.js"; +import { Wrapper } from "./wrapper.js"; + +/** + * Text output with high-level formatting functionality. + */ +export interface Printer extends Consumer { + (...text: Producer.Sequence): void; + + target: Consumer; + + writeTruncated(...text: Producer.Sequence): void; + writeTruncatedLine(...text: Producer.Sequence): void; +} + +export function Printer(target: Consumer, options?: Printer.Options) { + target = options?.wrap ? new Wrapper(target, options.wrap) : target; + let truncator: undefined | Truncator; + + const printer = function Printer(...text: Producer.Sequence) { + printer.write(...text); + } as Printer; + + Object.defineProperties(printer, { + target: { + get() { + return target; + }, + }, + + state: { + get() { + return target.state; + }, + }, + + write: { + value(...text: Producer.Sequence) { + target.write(...text); + }, + }, + + close: { + value() { + target.close(); + }, + }, + + writeTruncated: { + value(...text: string[]) { + if (!truncator) { + truncator = new Truncator(target, { addNewline: false }); + } + truncator.write(...text); + }, + }, + + writeTruncatedLine: { + value(...text: string[]) { + const tokens = [...Producer.of(text)].filter( + token => token.kind !== "newline" && token.kind !== "carriage-return", + ); + if (!truncator) { + truncator = new Truncator(target); + } + truncator.write(...tokens); + }, + }, + }); + + return printer; +} + +export namespace Printer { + export interface Options extends Consumer.Options { + wrap?: Wrapper.Options; + } +} diff --git a/packages/tools/src/ansi-text/producer.ts b/packages/tools/src/ansi-text/producer.ts new file mode 100644 index 0000000000..49300b8779 --- /dev/null +++ b/packages/tools/src/ansi-text/producer.ts @@ -0,0 +1,29 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Token } from "./token.js"; +import { tokenize } from "./tokenize.js"; + +/** + * A source of ANSI tokens. + */ +export interface Producer extends Iterable {} + +export namespace Producer { + export interface Sequence extends Array {} + + export function* of(sequence: Sequence): Producer { + for (const item of sequence) { + if (typeof item === "string") { + yield* tokenize(item); + } else if (Symbol.iterator in item) { + yield* item; + } else { + yield item; + } + } + } +} diff --git a/packages/tools/src/ansi-text/screen.ts b/packages/tools/src/ansi-text/screen.ts new file mode 100644 index 0000000000..4267658198 --- /dev/null +++ b/packages/tools/src/ansi-text/screen.ts @@ -0,0 +1,18 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +export namespace screen { + export namespace erase { + // Erase to end of line + export const toEol = "\x1b[K"; + + // Move to start of line and erase + export const line = `\r${toEol}`; + } + + // Clear all lines + export const clear = "\x1b[K"; +} diff --git a/packages/tools/src/ansi-text/sgr.ts b/packages/tools/src/ansi-text/sgr.ts new file mode 100644 index 0000000000..cba635f34f --- /dev/null +++ b/packages/tools/src/ansi-text/sgr.ts @@ -0,0 +1,154 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * SGR (select graphics rendition) opcodes. + * + * SGR is a CSI (ANSI "control sequence introducer", or ESC-[) sequence terminated by "m". + */ +export enum SgrOpcode { + reset = 0, + bold = 1, + dim = 2, + italic = 3, + underline = 4, + slowBlink = 5, + fastBlink = 6, + invert = 7, + conceal = 8, + strike = 9, + normalFont = 10, + gothic = 20, + doubleUnderline = 21, + normalIntensity = 22, + notItalic = 23, + notUnderline = 24, + notBlink = 25, + notInvert = 27, + notConceal = 28, + notStrike = 29, + normalFg = 39, + normalBg = 49, +} + +/** + * SGR categories. + * + * Each of these is cleared via a single opcode. Except for intensity (dim/bold) only one value may be in effect. + */ +export enum SgrCategory { + reset, + intensity, + italic, + underline, + blink, + invert, + conceal, + strike, + font, + fg, + bg, +} + +/** + * Masks for meaningful groups of CSI codes. + */ +export enum SgrOpcodeBlock { + font = 10, + fg = 30, + bg = 40, + fgBright = 90, + bgBright = 100, +} + +/** + * Color selectors. + */ +export enum Color { + black = 0, + red = 1, + green = 2, + yellow = 3, + blue = 4, + magenta = 5, + cyan = 6, + white = 7, + extended = 8, +} + +/** + * Extended color subselectors. + */ +export enum ExtendedColor { + rgb = 2, + eightBit = 5, +} + +/** + * Mapping of opcodes to categories. + */ +export const SgrOpcodeToCategory = Array(110); + +/** + * Mapping of opcodes to opcodes that disable the attribute. + */ +export const SgrOpcodeToUndoOpcode = Array(110); + +{ + function setCat(code: keyof typeof SgrOpcode, category: keyof typeof SgrCategory, undo?: keyof typeof SgrOpcode) { + const opcode = SgrOpcode[code]; + SgrOpcodeToCategory[opcode] = SgrCategory[category]; + if (undo !== undefined) { + SgrOpcodeToUndoOpcode[opcode] = SgrOpcode[undo]; + } + } + + function setBlockCat( + block: keyof typeof SgrOpcodeBlock, + category: keyof typeof SgrCategory, + undo: keyof typeof SgrOpcode, + ) { + const start = SgrOpcodeBlock[block]; + for (let i = SgrOpcodeBlock[block]; i < start + 10; i++) { + SgrOpcodeToCategory[i] = SgrCategory[category]; + SgrOpcodeToUndoOpcode[i] = SgrOpcode[undo]; + } + } + + setCat("reset", "reset"); + setCat("dim", "intensity", "normalIntensity"); + setCat("bold", "intensity", "normalIntensity"); + setCat("normalIntensity", "intensity"); + setCat("italic", "italic", "notItalic"); + setCat("notItalic", "italic"); + setCat("underline", "underline", "notUnderline"); + setCat("doubleUnderline", "underline", "notUnderline"); + setCat("notUnderline", "underline"); + setCat("fastBlink", "blink", "notBlink"); + setCat("slowBlink", "blink", "notBlink"); + setCat("notBlink", "blink"); + setCat("invert", "invert", "notInvert"); + setCat("notInvert", "invert"); + setCat("conceal", "conceal", "notConceal"); + setCat("notConceal", "conceal"); + setCat("strike", "strike", "notStrike"); + setCat("notStrike", "strike"); + setBlockCat("font", "font", "normalFont"); + setBlockCat("fg", "fg", "normalFg"); + setBlockCat("fgBright", "fg", "normalFg"); + setBlockCat("bg", "bg", "normalBg"); + setBlockCat("bgBright", "bg", "normalBg"); +} + +export interface EightBitColor { + color: number; +} + +export interface RgbColor { + r?: number; + g?: number; + b?: number; +} diff --git a/packages/tools/src/ansi-text/std.ts b/packages/tools/src/ansi-text/std.ts new file mode 100644 index 0000000000..c9370254f0 --- /dev/null +++ b/packages/tools/src/ansi-text/std.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { stderr, stdout } from "process"; +import { Printer } from "./printer.js"; +import { ansi } from "./text-builder.js"; +import { TextWriter } from "./text-writer.js"; + +const DEFAULT_WRAP_PREFIX = ` ${ansi.dim}⤷${ansi.not.dim} `; + +export namespace std { + /** + * Writer that writes to Node's stdout. + */ + export const out = Printer(new TextWriter(text => stdout.write(text), { terminalWidth: stdout.columns }), { + wrap: { wrapPrefix: DEFAULT_WRAP_PREFIX }, + }); + + /** + * Writer that writes to Node's stdout. + */ + export const err = Printer(new TextWriter(text => stderr.write(text), { terminalWidth: stderr.columns }), { + wrap: { wrapPrefix: DEFAULT_WRAP_PREFIX }, + }); +} diff --git a/packages/tools/src/ansi-text/style.ts b/packages/tools/src/ansi-text/style.ts new file mode 100644 index 0000000000..738bead1ae --- /dev/null +++ b/packages/tools/src/ansi-text/style.ts @@ -0,0 +1,366 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Producer } from "./producer.js"; +import { + Color, + ExtendedColor, + SgrCategory, + SgrOpcode, + SgrOpcodeBlock, + SgrOpcodeToCategory, + SgrOpcodeToUndoOpcode, +} from "./sgr.js"; +import { Token } from "./token.js"; + +/** + * An immutable representation of an ANSI CSI SGR sequence, also known as the "American National Standards Institute + * Control Sequence Introducer Select Graphic Rendition". + * + * Implemented largely from https://en.wikipedia.org/wiki/ANSI_escape_code + * + * Provides high level logic for parsing and manipulating styling. + */ +export interface Style extends Producer { + /** + * The current definition, either {@link codes} or {@link text}. + */ + get styleDefinition(): Style.Definition; + + set styleDefinition(definition: Style.InputDefinition | Style | undefined); + + /** + * The list of codes in this style. + */ + styleCodes: (string | number)[]; + + /** + * The style as a style token. + */ + styleToken: Token; + + /** + * A style that disables this style. + */ + undoStyle: Style; + + /** + * Create the ANSI escape sequence for this style. + */ + toString(): string; + + /** + * Create a new style by adding additional style information. + */ + addStyle(this: T, style: Style.InputDefinition | Style): T; + + /** + * Create a style that transitions from this style to another. + */ + diffStyle(this: T, other: Style): T; + + /** + * Execute a function against each code in this style's sequence. + */ + evaluateStyle(processor: (category: SgrCategory, code: number | string) => void): void; + + /** + * The factory used to create this style. + */ + factory: Style.Factory; +} + +const codes = Symbol("codes"); +const text = Symbol("text"); + +interface InternalStyle extends Style { + [codes]?: (string | number)[]; + [text]?: string; +} + +export function Style(definition?: Style.InputDefinition): Style { + if (definition instanceof Style) { + return definition; + } + + const style = Object.create(Style.prototype) as Style; + + style.styleDefinition = Style.definitionOf(definition); + + return style; +} + +Style.prototype = { + get styleDefinition(): Style.Definition { + if (this[codes] !== undefined) { + return this[codes]; + } + if (this[text] !== undefined) { + return this[text]; + } + }, + + set styleDefinition(definition: Style.InputDefinition) { + if (typeof definition === "function" || (typeof definition === "object" && !Array.isArray(definition))) { + this.styleDefinition = definition.styleDefinition; + } else if (typeof definition === "string") { + this[text] = Style.textOf(definition); + this[codes] = undefined; + } else { + this[codes] = definition; + this[text] = undefined; + } + }, + + get styleCodes() { + if (this[codes] === undefined) { + this[codes] = Style.codesOf(this[text]); + } + return this[codes] ?? []; + }, + + get styleToken(): Token { + return { + kind: "style", + + // Do not use this because extension toString() may not do the correct thing + style: Style(this.styleDefinition), + }; + }, + + get undoStyle() { + const codes = Array(); + for (const code of this.styleCodes) { + const opcode = Style.opcodeOf(code); + if (opcode === undefined) { + continue; + } + + const undo = SgrOpcodeToUndoOpcode[opcode]; + if (undo === undefined) { + continue; + } + + codes.push(undo); + } + return Style(codes); + }, + + toString() { + const codes = Array(); + for (const code of this.styleCodes) { + const opcode = Style.opcodeOf(code); + if (opcode === undefined) { + continue; + } + + codes.push(code); + } + return `\x1b[${codes.join(";")}m`; + }, + + addStyle(this: T, codes: Style.InputDefinition): T { + let categories = Array(); + + function processor(category: SgrCategory, code: number | string) { + if (category === SgrCategory.reset) { + categories = [SgrOpcode.reset]; + } else { + categories[category] = code; + } + } + + // Add my codes + this.evaluateStyle(processor); + + // Overwrite with new codes + codes = Style.definitionOf(codes); + if (codes !== undefined) { + Style(codes).evaluateStyle(processor); + } + + return this.factory( + categories.filter(entry => entry !== undefined), + this, + ) as T; + }, + + diffStyle(this: T, other: Style): T { + let current = Array(); + + // Collect current styles by category. Reset clears state + this.evaluateStyle((category: SgrCategory, code: number | string) => { + if (category === SgrCategory.reset) { + current = []; + } else { + current[category] = code; + } + }); + + // Collect target style by category. Reset clears current (because its no longer relevant) and adds the + // reset which always serializes first + let target = [...current]; + other.evaluateStyle((category, code) => { + if (category === SgrCategory.reset) { + current = []; + target = [SgrCategory.reset]; + } else if (current[category] === code) { + target[category] = undefined; + } else { + target[category] = code; + } + }); + + // Target now contains only those codes required to perform transition + return this.factory( + target.filter(entry => entry !== undefined), + this, + ) as T; + }, + + evaluateStyle(processor: (category: SgrCategory, code: number | string) => void) { + for (const code of this.styleCodes) { + const opcode = Style.opcodeOf(code); + if (opcode !== undefined) { + const category = SgrOpcodeToCategory[opcode]; + if (category !== undefined) { + processor(category, code); + } + } + } + }, + + get factory() { + return Style; + }, + + [Symbol.iterator]() { + return [{ kind: "style", style: this as Style } satisfies Token][Symbol.iterator](); + }, +} satisfies Pick; + +export namespace Style { + export type Factory = (definition?: Definition | Style, derivesFrom?: Style) => Style; + export type Definition = undefined | string | (string | number)[]; + export type InputDefinition = Definition | { styleDefinition: Definition }; + + export function opcodeOf(code: number | string) { + if (typeof code === "number") { + return code; + } + + if (code === "") { + return 0; + } + + // Note we must use parseInt so trailing parameters are stripped + const opcode = Number.parseInt(code); + if (Number.isNaN(opcode)) { + return undefined; + } + + return opcode; + } + + export function codesOf(definition?: string): (number | string)[] { + definition = textOf(definition); + if (definition === undefined) { + return []; + } + if (definition === "") { + return [0]; + } + + const parts = definition.split(";"); + const codes = Array(); + let pos = 0; + while (pos < parts.length) { + const part = parts[pos]; + const opcode = opcodeOf(parts[pos]); + pos++; + + // Determine how many arguments the code has. We encode these as a single unit + let expectedParts; + switch (opcode) { + case SgrOpcodeBlock.fg + Color.extended: + case SgrOpcodeBlock.bg + Color.extended: + switch (opcodeOf(parts[pos])) { + case ExtendedColor.eightBit: + expectedParts = 3; + break; + + case ExtendedColor.rgb: + expectedParts = 5; + break; + + default: + // Not sure what to make of this; just grab the two prefix codes + expectedParts = 1; + break; + } + break; + + case undefined: + // Ignore + continue; + + default: + expectedParts = 0; + break; + } + + // Store the original code as a number if it is encoded as an integer without arguments + let baseCode: number | string; + if (opcode.toString() === part) { + baseCode = opcode; + } else { + baseCode = part; + } + + // Arguments may be encoded in a single code with ":" as separator, or as separate codes if ";" is + // the separator. Unsure where which is supported so we just handle both + if (expectedParts) { + const codeCount = part.split(":").length; + if (codeCount < expectedParts) { + // At least some args are in subsequent codes; join these together using original separator so + // they serialize in original form + const argParts = expectedParts - codeCount; + codes.push([baseCode, ...parts.slice(pos, pos + argParts)].join(";")); + pos += argParts; + continue; + } + } + + // No args or all args encoded using ":" separator + codes.push(baseCode); + } + return codes; + } + + export function textOf(definition?: string) { + if (definition === undefined || definition === "") { + return definition; + } + definition = definition.trim(); + if (definition[0] === "\x1b" && definition[1] === "[") { + definition = definition.slice(2); + } + if (definition[definition.length - 1] === "m") { + definition = definition.slice(0, definition.length - 1); + } + return definition; + } + + export function definitionOf(definition: InputDefinition): Definition { + if (definition !== undefined && typeof definition !== "string" && !Array.isArray(definition)) { + return definition.styleDefinition; + } + return definition; + } + + export const Inherit = Style(); + export const None = Style([0]); +} diff --git a/packages/tools/src/ansi-text/text-builder.ts b/packages/tools/src/ansi-text/text-builder.ts new file mode 100644 index 0000000000..3807e55d82 --- /dev/null +++ b/packages/tools/src/ansi-text/text-builder.ts @@ -0,0 +1,261 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Producer } from "./producer.js"; +import { + Color, + EightBitColor, + ExtendedColor, + RgbColor, + SgrOpcode, + SgrOpcodeBlock, + SgrOpcodeToUndoOpcode, +} from "./sgr.js"; +import { Style } from "./style.js"; +import { TextWriter } from "./text-writer.js"; + +/** + * Convenience API for building ANSI text. + * + * Allows you to create ANSI escape sequences using e.g. `ansi.bright.yellow.bg.blue.blink`. + */ +export interface TextBuilder extends Style { + (...text: Producer.Sequence): TextBuilder; + + readonly state: TextBuilder.State; + readonly bg: TextBuilder; + readonly not: TextBuilder; + readonly reset: TextBuilder; + readonly bold: TextBuilder; + readonly dim: TextBuilder; + readonly bright: TextBuilder; + readonly italic: TextBuilder; + readonly underline: TextBuilder; + readonly doubleUnderline: TextBuilder; + readonly blink: TextBuilder; + readonly fastBlink: TextBuilder; + readonly invert: TextBuilder; + readonly conceal: TextBuilder; + readonly strike: TextBuilder; + readonly black: TextBuilder; + readonly red: TextBuilder; + readonly green: TextBuilder; + readonly yellow: TextBuilder; + readonly blue: TextBuilder; + readonly magenta: TextBuilder; + readonly cyan: TextBuilder; + readonly white: TextBuilder; + color(color: Color | EightBitColor | RgbColor): TextBuilder; + + factory: TextBuilder.Factory; +} + +export function TextBuilder( + definition?: Style.InputDefinition | Style, + derivesFrom?: Style, + state?: TextBuilder.State, +) { + if (derivesFrom instanceof TextBuilder) { + state = { ...(derivesFrom as TextBuilder).state, ...state }; + } else if (state === undefined) { + state = {}; + } + + definition = Style.definitionOf(definition); + + const self = function TextBuilderInstance(...text: Producer.Sequence) { + const sequence = self.state.sequence ? [...self.state.sequence] : []; + if (self.styleDefinition?.length) { + sequence.push(self.styleToken); + } + sequence.push(...text); + return TextBuilder(self, self, { sequence, revert: true }); + } as TextBuilder; + + Object.setPrototypeOf(self, TextBuilder.prototype); + + (self as any).state = state; + + if (definition !== undefined) { + self.styleDefinition = definition; + } + + return self; +} + +TextBuilder.prototype = Object.create(Style.prototype, { + bg: chmode({ bg: true }), + not: chmode({ not: true }), + bold: toggle("bold"), + dim: toggle("dim"), + bright: chmode({ bright: true }), + italic: toggle("italic"), + underline: toggle("underline"), + doubleUnderline: toggle("doubleUnderline"), + slowBlink: toggle("slowBlink"), + fastBlink: toggle("fastBlink"), + invert: toggle("invert"), + conceal: toggle("conceal"), + strike: toggle("strike"), + black: color("black"), + red: color("red"), + green: color("green"), + yellow: color("yellow"), + blue: color("blue"), + magenta: color("magenta"), + cyan: color("cyan"), + white: color("white"), + + reset: { + get() { + return (this as TextBuilder).addStyle([0]); + }, + }, + + color: { + value(this: TextBuilder, color: Color | EightBitColor | RgbColor) { + if (this.state.not) { + return this.addStyle([this.state.bg ? SgrOpcode.normalBg : SgrOpcode.normalFg]); + } + + if (typeof color === "object") { + if ("color" in color) { + return this.addStyle([Color.extended, ExtendedColor.eightBit, color.color]); + } + return this.addStyle([Color.extended, ExtendedColor.rgb, color.r ?? 0, color.g ?? 0, color.b ?? 0]); + } + + const block = this.state.bg + ? this.state.bright + ? SgrOpcodeBlock.bgBright + : SgrOpcodeBlock.bg + : this.state.bright + ? SgrOpcodeBlock.fgBright + : SgrOpcodeBlock.fg; + + return this.addStyle([block + color]); + }, + }, + + toString: { + value(this: TextBuilder) { + let { sequence } = this.state; + if (!sequence) { + sequence = [this.styleToken]; + } + + if (this.state.revert) { + sequence = [...sequence, this.undoStyle.styleToken]; + } + + const parts = Array(); + + const writer = new TextWriter(part => parts.push(part)); + writer.write(...sequence); + writer.close(); + + return parts.join(""); + }, + }, + + [Symbol.iterator]: { + get(this: TextBuilder) { + if (this.state.sequence === undefined) { + return { + next() { + return undefined; + }, + + done: true, + }; + } + let sequence = this.state.sequence; + if (this.state.revert) { + sequence = [...sequence, this.undoStyle.styleToken]; + } + const iterable = Producer.of(sequence); + return iterable[Symbol.iterator].bind(iterable); + }, + }, + + factory: { + value: TextBuilder, + }, +}); + +function chmode(state?: TextBuilder.State) { + return { + get(this: TextBuilder) { + return TextBuilder(this, this, state); + }, + }; +} + +function toggle(name: keyof typeof SgrOpcode) { + const on = SgrOpcode[name]; + const off = SgrOpcodeToUndoOpcode[on]; + if (off === undefined) { + throw new Error(`Can't toggle opcode ${on}`); + } + + return { + get(this: TextBuilder) { + return this.addStyle([this.state.not ? off : on]); + }, + }; +} + +function color(color: keyof typeof Color) { + const opcode = Color[color]; + return { + get(this: TextBuilder) { + return this.color(opcode); + }, + }; +} + +export namespace TextBuilder { + export interface State { + /** + * If next build affects a color it will modify bg rather than fg. + */ + readonly bg?: boolean; + + /** + * If next build affects 8-bit color the color will render as bright. + */ + readonly bright?: boolean; + + /** + * If next build modifies ANSI styling its meaning is inverted. + */ + readonly not?: boolean; + + /** + * Serialization will include style reversion as the final token. + * + * Set after invoking builder as function, cleared when modifying style. This means that ansi.red("foo") is + * terminated but ansi.red("foo").green will render as a red "foo" and leave text styled green. + */ + readonly revert?: boolean; + + /** + * The serialization sequence. Populated by invoking builder as function. + */ + readonly sequence?: Producer.Sequence; + } + + export type Factory = ( + definition?: Style.Definition | Style, + derivesFrom?: Style, + state?: TextBuilder.State, + ) => TextBuilder; +} + +/** + * Initial builder. + */ +export const ansi = TextBuilder(); diff --git a/packages/tools/src/ansi-text/text-writer.ts b/packages/tools/src/ansi-text/text-writer.ts new file mode 100644 index 0000000000..cb6d897bf8 --- /dev/null +++ b/packages/tools/src/ansi-text/text-writer.ts @@ -0,0 +1,363 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Consumer } from "./consumer.js"; +import { ContiguousOutputSegment } from "./contiguous-output-segment.js"; +import { Producer } from "./producer.js"; +import { SgrOpcode } from "./sgr.js"; +import { Style } from "./style.js"; +import { Token } from "./token.js"; +import { tokenize } from "./tokenize.js"; + +const DEFAULT_TAB_WIDTH = 4; + +/** + * Low-level text output with ANSI escape sequences, maintaining state regarding style and width of current line. + */ +export class TextWriter implements Consumer { + tabWidth: number; + + #terminalWidth?: number; + #currentLineWidth = 0; + #out: (text: string) => void; + #activeStyle = Style.Inherit; + #styleDirty = true; + #currentStyle = Style.Inherit; + #linePrefix?: ContiguousOutputSegment; + #state: Consumer.State; + #styleEnabled = true; + #isNewLine = true; + #buffer?: string[]; + #revertHandlers?: Set<() => void>; + + constructor(out: (text: string) => void, options?: Writer.Options) { + const { tabWidth, terminalWidth, linePrefix } = options ?? {}; + this.#out = out; + this.tabWidth = tabWidth ?? DEFAULT_TAB_WIDTH; + this.#terminalWidth = terminalWidth; + if (linePrefix) { + this.#linePrefix = new ContiguousOutputSegment(...tokenize(linePrefix)); + } + + const self = this; + + this.#state = function state(options?: Consumer.Options, executor?: () => void): Consumer.Context | undefined { + options = { ...options }; + + const revertTo = { ...self.state, options } as Consumer.Options; + + const { linePrefix, style, buffer } = options; + if (linePrefix) { + if (self.#linePrefix) { + self.#linePrefix.push(linePrefix); + } else { + self.#linePrefix = new ContiguousOutputSegment(linePrefix); + } + } + + if (style) { + if (self.#currentStyle) { + self.#currentStyle = self.#currentStyle.addStyle(style); + } else { + self.#currentStyle = style; + } + self.#styleDirty = true; + } + + if (!!buffer !== !!self.#buffer) { + if (buffer) { + self.#buffer = []; + } else { + self.#buffer = undefined; + } + } + + const context = { + close() { + if (self.#revertHandlers) { + for (const fn of self.#revertHandlers) { + fn(); + } + } + + if (revertTo.style) { + revertTo.style = self.#currentStyle.undoStyle.addStyle(revertTo.style); + } else { + revertTo.style = Style.None; + } + + for (const key in revertTo) { + (self.state as any)[key] = (revertTo as any)[key]; + } + }, + + [Symbol.dispose]() { + this.close(); + }, + }; + + if (executor) { + try { + executor(); + } finally { + context.close(); + } + } else { + return context; + } + } as Consumer.State; + + Object.defineProperties(this.#state, { + style: { + get(this: never) { + return self.#currentStyle; + }, + + set(this: never, style) { + self.#currentStyle = style ?? Style.Inherit; + self.#styleDirty = true; + }, + + enumerable: true, + }, + + linePrefix: { + get(this: never) { + return self.#linePrefix?.toString(); + }, + + set(this: never, prefix) { + if (prefix) { + self.#linePrefix = new ContiguousOutputSegment(...tokenize(prefix)); + } else { + self.#linePrefix = undefined; + } + }, + + enumerable: true, + }, + + terminalWidth: { + get(this: never) { + return self.#terminalWidth; + }, + + set(this: never, width: number | undefined) { + self.#terminalWidth = width; + }, + + enumerable: true, + }, + + styleEnabled: { + get(this: never) { + return self.#styleEnabled; + }, + + set(this: never, enabled: boolean) { + self.#styleEnabled = enabled; + }, + + enumerable: true, + }, + + availableWidth: { + get(this: never) { + if (self.#terminalWidth === undefined) { + return undefined; + } + + if (self.#linePrefix) { + const width = self.#terminalWidth - self.#linePrefix.width; + if (width > 0) { + return width; + } + return undefined; + } + + return self.#terminalWidth; + }, + }, + + remainingWidth: { + get(this: never) { + if (self.#terminalWidth === undefined) { + return undefined; + } + return self.#terminalWidth - self.#currentLineWidth; + }, + }, + + buffer: { + get(this: never) { + return !!self.#buffer; + }, + + set(this: never, buffering: boolean) { + if (!!self.#buffer === buffering) { + return; + } + if (buffering) { + self.#buffer = []; + return; + } + if (self.#buffer) { + self.#out(self.#buffer.join("")); + self.#buffer = undefined; + } + }, + + enumerable: true, + }, + + onRevert: { + value(fn: () => void) { + if (!self.#revertHandlers) { + self.#revertHandlers = new Set(); + } + self.#revertHandlers.add(fn); + }, + }, + + offRevert: { + value(fn: () => void) { + if (self.#revertHandlers) { + self.#revertHandlers.add(fn); + } + }, + }, + }); + } + + get state() { + return this.#state; + } + + write(...text: Producer.Sequence) { + for (const token of Producer.of(text)) { + this.#addToken(token); + } + } + + close() { + this.#writeStyle(); + } + + /** + * Reset styling. + */ + reset() { + if (this.#currentStyle.styleCodes.find(code => code !== SgrOpcode.reset)) { + this.#currentStyle = Style.None; + this.#styleDirty = true; + } + } + + #addToken(token: Token, forLinePrefix = false) { + if (this.#isNewLine && this.#linePrefix && !forLinePrefix) { + this.#isNewLine = false; + const style = this.#currentStyle; + this.#currentStyle = Style.None; + this.#styleDirty = true; + for (const token of this.#linePrefix.tokens) { + this.#addToken(token, true); + } + this.#currentStyle = style; + this.#styleDirty = true; + } + + switch (token.kind) { + case "newline": + this.#emitLine("\n"); + break; + + case "carriage-return": + this.#emitLine("\r"); + break; + + case "tab": + let width = this.tabWidth - (this.#currentLineWidth % this.tabWidth); + if (width === 0) { + width = this.tabWidth; + } + this.#writeText("".padStart(width)); + this.#currentLineWidth += width; + break; + + case "breaking": + this.#writeText(token.str); + this.#currentLineWidth += token.width; + break; + + case "style": + this.#currentStyle = this.#currentStyle.addStyle(token.style); + this.#styleDirty = true; + break; + + case "ansi": + if (this.#styleEnabled) { + this.#writeText(token.sequence); + } + if (token.newColumn !== undefined) { + // TODO - don't need to support yet but to be correct should adjust sequence to account for indent + if (!this.#currentLineWidth) { + this.#isNewLine = true; + } + this.#currentLineWidth = token.newColumn; + } + break; + + case "nonbreaking": + this.#writeText(token.str); + this.#currentLineWidth += token.width; + break; + } + } + + #writeText(text: string) { + this.#writeStyle(); + this.#emit(text); + } + + #writeStyle() { + if (this.#styleDirty && this.#styleEnabled) { + this.#styleDirty = false; + + this.#emit(this.#activeStyle.diffStyle(this.#currentStyle).toString()); + + this.#activeStyle = this.#currentStyle; + } + } + + #emit(text: string) { + if (this.#buffer) { + this.#buffer.push(text); + } else { + this.#out(text); + } + } + + #emitLine(terminator?: string) { + this.#writeStyle(); + this.#beginLine(); + if (terminator) { + this.#emit(terminator); + } + } + + #beginLine() { + this.#isNewLine = true; + this.#currentLineWidth = 0; + } +} + +export namespace Writer { + export interface Options { + tabWidth?: number; + terminalWidth?: number; + linePrefix?: string; + } +} diff --git a/packages/tools/src/ansi-text/token.ts b/packages/tools/src/ansi-text/token.ts new file mode 100644 index 0000000000..666fe560e5 --- /dev/null +++ b/packages/tools/src/ansi-text/token.ts @@ -0,0 +1,76 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Style } from "./style.js"; + +/** + * An individual lexical token in a Unicode string with ANSI escape codes. + */ +export type Token = + | NonbreakingToken + | BreakingToken + | StyleToken + | NewlineToken + | CarriageReturnToken + | TabToken + | AnsiToken; + +/** + * Text sequence that is not whitespace or a control sequence. + */ +export interface NonbreakingToken { + kind: "nonbreaking"; + str: string; + width: number; +} + +/** + * Non-tab non-newline whitespace sequence. + */ +export interface BreakingToken { + kind: "breaking"; + str: string; + width: number; +} + +/** + * A text styling sequence. + */ +export interface StyleToken { + kind: "style"; + style: Style; +} + +/** + * Newline character. + */ +export interface NewlineToken { + kind: "newline"; +} + +/** + * Carriage return character. + */ +export interface CarriageReturnToken { + kind: "carriage-return"; +} + +/** + * Tab character. + */ +export interface TabToken { + kind: "tab"; +} + +/** + * Misc valid non-CSI (style) ANSI codes. Currently we tokenize because we have to parse them anyway to skip, but + * otherwise we ignore. + */ +export interface AnsiToken { + kind: "ansi"; + sequence: string; + newColumn?: number; +} diff --git a/packages/tools/src/ansi-text/tokenize.ts b/packages/tools/src/ansi-text/tokenize.ts new file mode 100644 index 0000000000..01a59019a1 --- /dev/null +++ b/packages/tools/src/ansi-text/tokenize.ts @@ -0,0 +1,212 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Chars } from "./chars.js"; +import { Producer } from "./producer.js"; +import { Style } from "./style.js"; +import { Token } from "./token.js"; + +/** + * Convert ANSI text into a sequence of tokens. + */ +export function* tokenize(text: string): Producer { + for (let pos = 0; pos < text.length; ) { + const unit = text[pos]; + switch (unit) { + case "\n": + yield { kind: "newline" }; + pos++; + break; + + case "\r": + if (text[pos + 1] === "\n") { + yield { kind: "newline" }; + pos += 2; + } else { + yield { kind: "carriage-return" }; + pos += 1; + } + break; + + case "\t": + yield { kind: "tab" }; + pos++; + break; + + case "\x1b": + let valid = false; + let newColumn: number | undefined; + const escapeStart = pos; + pos++; + switch (text[pos]) { + case "[": + // Fe CSI + pos++; + + // Valid sequence members + while (text[pos] >= "\x30" && text[pos] <= "\x3f") { + pos++; + } + + // Valid sequence termination + if (text[pos] >= "\0x40" && text[pos] <= "\x7e") { + const param = text.slice(escapeStart + 2, pos); + + switch (text[pos]) { + case "m": // SGR (select graphics rendition), the sequence that controls styling + yield { + kind: "style", + style: Style(param), + }; + pos++; + continue; + + case "E": // Move up + case "F": // Move down + newColumn = 0; + break; + + case "G": // Move to column + newColumn = Number.parseInt(param); + break; + + case "H": // Move to row and column + const [, column] = param.split(";"); + newColumn = column ? Number.parseInt(column) : 0; + break; + + case "J": // Clear screen part + switch (param) { + case "2": // Entire screen + case "3": // Entire screen plus scrollback buffer + newColumn = 0; + } + break; + } + + pos++; + valid = true; + } + break; + + case "X": + case "]": + case "^": + case "_": + // Fe sequences that take a single string argument (, , , + // terminated by "\") + pos++; + while (pos < text.length) { + pos++; + if (text[pos] === "\\") { + valid = true; + break; + } + } + break; + + default: + const code = text[pos]; + if ( + (code >= "\x40" && code <= "\x57") || + (code >= "\x59" && code <= "\x5a") || + (code >= "\x5c" && code <= "\x5d") + ) { + // Fe sequence not covered above + pos++; + valid = true; + } else if (code >= "\x30" && code <= "0x3f") { + // Fp sequence + pos++; + valid = true; + } else if (code >= "\x60" && code <= "0x7e") { + // Fs sequence + pos++; + valid = true; + } else if (code >= "\x20" && code <= "0x2f") { + pos++; + const code2 = text[pos]; + if (code2 >= "\x30" && code2 <= "0x73") { + pos++; + valid = true; + } + } + break; + } + + if (valid) { + const token: Token = { + kind: "ansi", + sequence: text.slice(escapeStart, pos), + }; + if (newColumn !== undefined && !Number.isNaN(newColumn)) { + token.newColumn = newColumn; + } + yield token; + } + + break; + + default: + const start = pos; + + // Whitespace - no surrogates, zero-width space does not contribute to width + if (Chars.breakingSpace.has(unit)) { + let width = 1; + pos++; + while (Chars.breakingSpace.has(text[pos])) { + pos++; + // No width for zero-width space + if (unit !== "\u200b") { + width++; + } + } + yield { + kind: "breaking", + str: text.slice(start, pos), + width, + }; + break; + } + + // Scan characters + let width = 0; + while (pos < text.length) { + let cp = text[pos]; + + // Combine proper surrogate pairs + if (cp >= "\ud800" && cp < "\udc00") { + const nextUnit = text[pos + 1]; + if (nextUnit !== undefined && nextUnit >= "\udc00" && nextUnit < "\ue000") { + cp += nextUnit; + } + } + + if (!cp.match(Chars.nonbreakingText)) { + break; + } + + pos += cp.length; + if (!cp.match(Chars.zeroWidth)) { + width++; + } + } + + // If we detected no characters, the code unit is garbage and we skip it entirely + if (start === pos) { + pos++; + break; + } + + // Yield the token and skip forward to the last character + yield { + kind: "nonbreaking", + str: text.slice(start, pos), + width, + }; + } + } +} diff --git a/packages/tools/src/ansi-text/truncator.ts b/packages/tools/src/ansi-text/truncator.ts new file mode 100644 index 0000000000..7efa8d12d5 --- /dev/null +++ b/packages/tools/src/ansi-text/truncator.ts @@ -0,0 +1,63 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Consumer } from "./consumer.js"; +import { ContiguousOutputSegment } from "./contiguous-output-segment.js"; +import { Producer } from "./producer.js"; + +/** + * Writes lines truncated to a specific width. + */ +export class Truncator implements Consumer { + #target: Consumer; + #addNewline: boolean; + + constructor(target: Consumer, options: { addNewline?: boolean } = {}) { + const { addNewline } = options; + this.#target = target; + this.#addNewline = addNewline === undefined ? true : false; + } + + get state() { + return this.#target.state; + } + + write(...text: Producer.Sequence) { + const width = this.#target.state.remainingWidth; + + if (width === undefined) { + this.#write(...text); + return; + } + + const segment = new ContiguousOutputSegment(...text); + if (segment.width <= width) { + this.#write(...segment.tokens); + } else { + const scanner = segment.scan(); + + this.#write(...scanner.take(width - 1), { kind: "nonbreaking", str: "…", width: 1 }); + for (const token of scanner) { + if (token.kind === "breaking" || token.kind === "nonbreaking") { + continue; + } + this.#write(token); + } + } + } + + close() { + this.#target.close(); + } + + #write(...text: Producer.Sequence) { + if (this.#addNewline) { + this.#target.write(...text, { kind: "newline" }); + } else { + this.#target.write(...text); + } + } +} diff --git a/packages/tools/src/ansi-text/visible-width-of.ts b/packages/tools/src/ansi-text/visible-width-of.ts new file mode 100644 index 0000000000..423ff819df --- /dev/null +++ b/packages/tools/src/ansi-text/visible-width-of.ts @@ -0,0 +1,39 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * Returns visible width of a space or visible text segment. + */ +export function visibleWidthOf(str: string) { + let width = 0; + + for (let i = 0; i < str.length; i++) { + const charCode = str.charCodeAt(i); + + // Skip zero width characters + switch (charCode) { + case 0x200b: // zwsp + case 0x200c: // zero width non-joiner + case 0x200d: // zero width joiner + case 0x2060: // word joiner + case 0xfeff: // bom + continue; + } + + // Extend width + width++; + + // Skip low surrogate if it properly follows a high surrogate + if (charCode >= 0xd800 && charCode < 0xdc00) { + const charCode2 = str.charCodeAt(i + 1); + if (charCode2 !== undefined && charCode2 >= 0xdc00 && charCode2 < 0xe000) { + i++; + } + } + } + + return width; +} diff --git a/packages/tools/src/ansi-text/wrapper.ts b/packages/tools/src/ansi-text/wrapper.ts new file mode 100644 index 0000000000..0c53c07d36 --- /dev/null +++ b/packages/tools/src/ansi-text/wrapper.ts @@ -0,0 +1,244 @@ +/** + * @license + * Copyright 2022-2024 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Consumer } from "./consumer.js"; +import { ContiguousOutputSegment } from "./contiguous-output-segment.js"; +import { Producer } from "./producer.js"; +import { Style } from "./style.js"; +import { TextWriter } from "./text-writer.js"; +import { Token } from "./token.js"; +import { tokenize } from "./tokenize.js"; + +const NEWLINE: Token = { kind: "newline" }; +const SPACE: Token = { kind: "nonbreaking", str: " ", width: 1 }; + +/** + * Writes to a {@link TextWriter} with support for smart wrapping of text. + */ +export class Wrapper implements Consumer { + #target: Consumer; + #wrapPrefix?: ContiguousOutputSegment; + #preserveIndent: boolean; + #splitStyling: boolean; + #inputState: "newline" | "prefix" | "indent" | "word" | "space" = "newline"; + #outputState: "newline" | "newwrap" | "inline" = "newline"; + #indent?: ContiguousOutputSegment; + #output?: ContiguousOutputSegment; + #onRevert = () => { + // When state reverts we may have buffered output we have yet to emit. Do so now to ensure it receives proper + // styling + this.#emit(); + }; + + constructor(target: Consumer, options: Wrapper.Options) { + const { wrapPrefix, preserveIndent, splitStyling } = options; + + this.#target = target; + if (wrapPrefix !== undefined) { + this.#wrapPrefix = new ContiguousOutputSegment(...tokenize(wrapPrefix)); + } + this.#preserveIndent = preserveIndent ?? true; + this.#splitStyling = + splitStyling ?? !!(this.#preserveIndent || this.#wrapPrefix || !this.#target.state.linePrefix); + + this.#target.state.onRevert(this.#onRevert); + } + + get state() { + return this.#target.state; + } + + write(...text: Producer.Sequence) { + if (this.#target.state.terminalWidth === undefined) { + this.#target.write(...text); + return; + } + + for (const token of Producer.of(text)) { + this.#addToken(token); + } + } + + close() { + this.#emit(); + this.#target.state.offRevert(this.#onRevert); + this.#target.close(); + } + + [Symbol.dispose]() { + this.close(); + } + + #addToken(token: Token) { + switch (token.kind) { + case "newline": + case "carriage-return": + this.#emit(); + this.#target.write(token); + this.#indent = undefined; + this.#outputState = this.#inputState = "newline"; + break; + + case "ansi": + this.#enqueue(token); + + switch (token.sequence) { + case Wrapper.prefixStart: + this.#inputState = "prefix"; + break; + + case Wrapper.prefixStop: + this.#inputState = "indent"; + break; + } + break; + + case "style": + this.#enqueue(token); + break; + + case "nonbreaking": + if (this.#inputState === "prefix") { + this.#enqueue(token); + break; + } + if (this.#inputState === "indent") { + this.#indent = this.#output; + this.#output = undefined; + } + this.#inputState = "word"; + this.#enqueue(token); + break; + + case "tab": + case "breaking": + switch (this.#inputState) { + case "newline": + if (this.#preserveIndent) { + this.#enqueue(token); + } + this.#inputState = "indent"; + break; + + case "prefix": + case "indent": + this.#enqueue(token); + break; + + case "word": + this.#emit(); + this.#inputState = "space"; + break; + } + break; + } + } + + #emit() { + if (this.#output === undefined) { + return; + } + + const outputState = this.#outputState; + if (outputState === "newline") { + this.#emitPrefix(); + } + this.#outputState = "inline"; + + const output = this.#output; + this.#output = undefined; + + let remainingWidth = this.#target.state.remainingWidth!; + + // Leave room for a space except at the beginning of the line + if (remainingWidth !== undefined && outputState === "inline") { + remainingWidth--; + } + + // Ideal case - not wrapping or segment fits on current line + if (remainingWidth === undefined || output.width <= remainingWidth) { + if (outputState === "inline") { + this.#target.write(SPACE); + } + this.#target.write(...output.tokens); + return; + } + + // Least ideal case - the first- or tertiary- prefix fills up the line by itself. Give up on wrapping + const wrapPrefixWidth = (this.#wrapPrefix?.width ?? 0) + (this.#indent?.width ?? 0); + const availableWrappedWidth = this.#target.state.availableWidth! - wrapPrefixWidth; + if ((outputState === "newline" && remainingWidth <= 0) || availableWrappedWidth < 0) { + this.#target.write(...output.tokens); + return; + } + + // Second best case - the segment fits on a new line + if (output.width < availableWrappedWidth) { + this.#wrap(); + this.#target.write(...output.tokens); + return; + } + + // Third best case - we need to wrap the segment itself + const scanner = output.scan(); + if (outputState === "inline") { + this.#target.write(SPACE); + } + this.#target.write(...scanner.take(remainingWidth)); + while (!scanner.done) { + this.#wrap(); + this.#target.write(...scanner.take(availableWrappedWidth)); + } + } + + #emitPrefix(extra?: ContiguousOutputSegment) { + if (this.#indent !== undefined) { + this.#target.write(...this.#indent.tokens); + } + if (extra !== undefined) { + this.#target.write(...extra.tokens); + } + } + + #wrap() { + let style: Style | undefined; + if (this.#splitStyling) { + style = this.#target.state.style; + this.#target.write({ kind: "style", style: Style.None }); + } + this.#target.write(NEWLINE); + this.#emitPrefix(this.#wrapPrefix); + if (style) { + this.#target.write({ kind: "style", style }); + } + } + + #enqueue(token: Token) { + if (this.#output) { + this.#output.push(token); + } else { + this.#output = new ContiguousOutputSegment(token); + } + } +} + +export namespace Wrapper { + export interface Options { + wrapPrefix?: string; + preserveIndent?: boolean; + splitStyling?: boolean; + } + + /** + * Private - begin demarcation of line prefix. + */ + export const prefixStart = "\x1b[<<~"; + + /** + * Private - end demarcation of line prefix. + */ + export const prefixStop = "\x1b[>>~"; +} diff --git a/packages/tools/src/building/cli.ts b/packages/tools/src/building/cli.ts index a0c32c6304..2d8c478fc4 100644 --- a/packages/tools/src/building/cli.ts +++ b/packages/tools/src/building/cli.ts @@ -6,9 +6,9 @@ import { commander } from "../util/commander.js"; import { Package } from "../util/package.js"; -import { Builder, Target } from "./builder.js"; import { buildDocs, mergeDocs } from "./docs.js"; import { Graph } from "./graph.js"; +import { ProjectBuilder, Target } from "./project-builder.js"; import { Project } from "./project.js"; import { syncAllTsconfigs } from "./tsconfig.js"; @@ -105,7 +105,7 @@ export async function main(argv = process.argv) { } function builder(graph?: Graph) { - return new Builder({ ...args, targets: [...targets], graph }); + return new ProjectBuilder({ ...args, targets: [...targets], graph }); } switch (mode as Mode) { diff --git a/packages/tools/src/building/graph.ts b/packages/tools/src/building/graph.ts index 48735a8870..da7a153ec9 100644 --- a/packages/tools/src/building/graph.ts +++ b/packages/tools/src/building/graph.ts @@ -7,8 +7,8 @@ import colors from "ansi-colors"; import { JsonNotFoundError, Package } from "../util/package.js"; import { Progress } from "../util/progress.js"; -import { Builder } from "./builder.js"; import { InternalBuildError } from "./error.js"; +import { ProjectBuilder } from "./project-builder.js"; import { BUILD_INFO_LOCATION, BuildInformation, Project } from "./project.js"; /** @@ -72,7 +72,7 @@ export class Graph { // TODO - parallelization will be trivial except need to update Progress to support display of multiple simultaneous // tasks - async build(builder: Builder, showSkipped = true) { + async build(builder: ProjectBuilder, showSkipped = true) { const toBuild = new Set(this.nodes); const needsConfig = this.nodes.find(node => node.pkg.hasConfig); diff --git a/packages/tools/src/building/builder.ts b/packages/tools/src/building/project-builder.ts similarity index 99% rename from packages/tools/src/building/builder.ts rename to packages/tools/src/building/project-builder.ts index c94f311c4c..992adde37a 100644 --- a/packages/tools/src/building/builder.ts +++ b/packages/tools/src/building/project-builder.ts @@ -30,7 +30,7 @@ export interface Options { * * Warning: This class is intended for command line use and will process.exit if things go wrong. */ -export class Builder { +export class ProjectBuilder { unconditional: boolean; tsContext?: TypescriptContext; graph?: Graph; diff --git a/packages/tools/src/building/tsconfig.ts b/packages/tools/src/building/tsconfig.ts index e769c463eb..ac0e5fc30e 100644 --- a/packages/tools/src/building/tsconfig.ts +++ b/packages/tools/src/building/tsconfig.ts @@ -56,10 +56,8 @@ async function syncSubproject(node: Graph.Node, path: string, ...extraRefs: stri refs = []; } - const deps = node.dependencies - .filter(dep => dep.pkg.isLibrary) - .map(dep => dep.pkg.resolve("src")) - .filter(p => !p.match(/packages[\\/]tools/)); + const deps = node.dependencies.filter(dep => dep.pkg.isLibrary).map(dep => dep.pkg.resolve("src")); + //.filter(p => !p.match(/packages[\\/]tools/)); const desired = [...new Set([...deps, ...extraRefs])]; diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts index ccd3c2c9f7..0a76537e7d 100644 --- a/packages/tools/src/index.ts +++ b/packages/tools/src/index.ts @@ -4,12 +4,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -export * from "./building/builder.js"; +export * from "./ansi-text/index.js"; +export * from "./ansi-text/std.js"; export * from "./building/graph.js"; +export * from "./building/project-builder.js"; export * from "./building/project.js"; export * from "./running/ensure-compiled.js"; -export * from "./util/commander.js"; -export * from "./util/file.js"; -export * from "./util/glob.js"; -export * from "./util/package.js"; -export * from "./util/progress.js"; +export * from "./util/index.js"; diff --git a/packages/tools/src/running/ensure-compiled.ts b/packages/tools/src/running/ensure-compiled.ts index b3183cd8d8..2e2ea83ac1 100644 --- a/packages/tools/src/running/ensure-compiled.ts +++ b/packages/tools/src/running/ensure-compiled.ts @@ -6,8 +6,8 @@ import { exit } from "process"; import { fileURLToPath } from "url"; -import { Builder } from "../building/builder.js"; import { Graph } from "../building/graph.js"; +import { ProjectBuilder } from "../building/project-builder.js"; import { Project } from "../building/project.js"; import { Package } from "../util/package.js"; @@ -39,7 +39,7 @@ export async function ensureCompiled(path: string) { // In development we currently build package and dependencies unconditionally before running const isDevelopment = !path.match(/[\\/]node_modules[\\/]/); if (isDevelopment && format !== "none") { - const builder = new Builder(); + const builder = new ProjectBuilder(); const dependencies = await Graph.forProject(path); if (dependencies) { // Project is in a workspace; build along with dependencies from the same workspace diff --git a/packages/tools/src/util/commander.ts b/packages/tools/src/util/commander.ts index 228f9b998a..76c9b8b404 100644 --- a/packages/tools/src/util/commander.ts +++ b/packages/tools/src/util/commander.ts @@ -4,11 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import colors from "ansi-colors"; import { Command } from "commander"; import process from "process"; - -colors.enabled = process.stdout.isTTY; +import { ansi } from "../ansi-text/text-builder.js"; export function commander(name: string, description: string) { return new Command(name) @@ -16,7 +14,7 @@ export function commander(name: string, description: string) { .allowExcessArguments(false) .configureOutput({ writeOut: str => process.stdout.write(`\n${formatHelp(str)}\n`), - writeErr: str => process.stderr.write(`\n${colors.red(str)}\n`), + writeErr: str => process.stderr.write(`\n${ansi.red(str)}\n`), }); } function formatHelp(help: string) { @@ -24,11 +22,11 @@ function formatHelp(help: string) { return help; } - help = help.replace(/^Usage: (\S+)/, (_match, name) => `Usage: ${colors.bold(name)}`); + help = help.replace(/^Usage: (\S+)/, (_match, name) => `Usage: ${ansi.bold(name)}`); help = help.replace(/^( {2}.+ {2})/gm, (_match, input: string) => input .split(",") - .map(item => item.replace(/(-*\w+)/, (_match, word) => colors.blue(word))) + .map(item => item.replace(/(-*\w+)/, (_match, word) => ansi.blue(word).toString())) .join(","), ); return help; diff --git a/packages/tools/src/util/index.ts b/packages/tools/src/util/index.ts index 57a19583d6..254650a3eb 100644 --- a/packages/tools/src/util/index.ts +++ b/packages/tools/src/util/index.ts @@ -9,3 +9,4 @@ export * from "./errors.js"; export * from "./file.js"; export * from "./glob.js"; export * from "./package.js"; +export * from "./progress.js"; diff --git a/packages/tools/src/util/progress.ts b/packages/tools/src/util/progress.ts index ba8e6094a9..571ea54af2 100644 --- a/packages/tools/src/util/progress.ts +++ b/packages/tools/src/util/progress.ts @@ -4,16 +4,17 @@ * SPDX-License-Identifier: Apache-2.0 */ -import colors from "ansi-colors"; import { stderr, stdout } from "process"; +import { screen } from "../ansi-text/screen.js"; +import { std } from "../ansi-text/std.js"; +import { ansi } from "../ansi-text/text-builder.js"; import { Package } from "./package.js"; -const CLEAR = "\x1b[K"; const SPINNER = "◐◓◑◒"; //"⡜⠔⠢⢣"; //["⚫︎", "⚪︎"]; "⡈⠔⠢⢁"; const SPINNER_INTERVAL = 100; function packageIdentity(pkg: Package) { - let identity = colors.bold(pkg.json.name); + let identity = ansi.bold(pkg.json.name).toString(); if (pkg.json.version) { identity = `${identity}@${pkg.json.version}`; } @@ -50,24 +51,20 @@ const writeStatus = (() => { intercept(stderr); return function writeStatus(text: string, willOverwrite = false) { - const columns = process.stdout.columns; - if (willOverwrite && columns !== undefined && text.length > columns - 2) { - text = filterAnsi(text, columns - 2) + "…"; - } - - text += willOverwrite ? "\r" : "\n"; + text += willOverwrite ? `${screen.erase.toEol}\r` : `${screen.erase.toEol}\n`; if (text === lastStatus) { return; } - if (lastStatus) { - lastStatus = undefined; - stdout.write(CLEAR); - } else if (needNewline && !text.startsWith("\n")) { - stdout.write("\n"); - } + std.out.state({ buffer: true }, () => { + if (lastStatus) { + lastStatus = undefined; + } else if (needNewline && !text.startsWith("\n")) { + std.out("\n"); + } - stdout.write(text); + std.out.writeTruncated(text); + }); lastStatus = text; }; @@ -86,15 +83,15 @@ export class Progress { constructor() {} emphasize(text: unknown) { - return colors.bold(`${text}`); + return ansi.bold(`${text}`); } deemphasize(text: unknown) { - return colors.dim(`${text}`); + return ansi.dim(`${text}`); } skip(why: string, pkg: Package) { - stdout.write(colors.dim(`Skip ${packageIdentity(pkg)}: ${why}\n\n`)); + std.out.write(ansi.dim(`Skip ${packageIdentity(pkg)}: ${why}\n\n`)); } startup(what: string, pkgOrOverwrite?: Package | boolean) { @@ -130,34 +127,32 @@ export class Progress { return; } - const subtask = this.#subtasks.length - ? colors.dim(` (${colors.dim(this.#subtasks[this.#subtasks.length - 1])})`) - : ""; + const subtask = this.#subtasks.length ? ansi.dim(` (${this.#subtasks[this.#subtasks.length - 1]})`) : ""; - writeStatus(` ${colors.yellow(this.#spinner)} ${this.#ongoingText}${subtask}`, true); + writeStatus(` ${ansi.yellow(this.#spinner)} ${this.#ongoingText}${subtask}`, true); } success(text: string) { this.status = Progress.Status.Success; - writeStatus(` ${colors.green("✓")} ${text} ${this.#duration}`); + writeStatus(` ${ansi.green("✓")} ${text} ${this.#duration}`); this.#start = this.#ongoingText = undefined; } failure(text: string) { this.status = Progress.Status.Failure; - writeStatus(` ${colors.redBright("✗")} ${text} ${this.#duration}`); + writeStatus(` ${ansi.bright.red("✗")} ${text} ${this.#duration}`); this.#start = this.#ongoingText = undefined; } info(label: string, value?: any) { if (value) { - label = `${colors.dim(label)} ${value}`; + label = `${ansi.dim(label)} ${value}`; } - writeStatus(` ${colors.dim("‣")} ${label}`); + writeStatus(` ${ansi.dim("‣")} ${label}`); } warn(text: string) { - stdout.write(` ${colors.yellow("Warning:")} ${text}\n`); + std.out.write(` ${ansi.yellow("Warning:")} ${text}\n`); } shutdown() { @@ -223,7 +218,7 @@ export class Progress { } else { ms = Math.trunc(ms / 1000); } - return colors.dim.yellow(`(${ms}s)`); + return `${ansi.dim.yellow}(${ms}s)${ansi.not.dim.not.yellow}`; } } @@ -235,35 +230,3 @@ export namespace Progress { Failure = "failure", } } - -// See https://stackoverflow.com/questions/26238553/how-can-i-truncate-a-string-to-a-maximum-length-without-breaking-ansi-escape-cod -// TODO - this function doesn't seem entirely correct, still seems to truncate too much -// Crop the length of lines, ANSI escape code aware -// Always outputs every escape char, regardless of length (so we always end up with a sane state) -// Visible characters are filtered out once length is exceeded -function filterAnsi(str: string, len: number) { - if (!len || len < 10) return str; // probably not a valid console -- send back the whole line - let count = 0, // number of visible chars on line so far - esc = false, // in an escape sequence - longesc = false; // in a multi-character escape sequence - let outp = true; // should output this character - return str - .split("") - .filter(function (c) { - // filter characters... - if (esc && !longesc && c == "[") longesc = true; // have seen an escape, now '[', start multi-char escape - if (c == "\x1b") esc = true; // start of escape sequence - - outp = count < len || esc; // if length exceeded, don't output non-escape chars - if (!esc && !longesc) count++; // if not in escape, count visible char - - if (esc && !longesc && c != "\x1b") esc = false; // out of single char escape - if (longesc && c != "[" && c >= "@" && c <= "~") { - esc = false; - longesc = false; - } // end of multi-char escape - - return outp; // result for filter - }) - .join(""); // glue chars back into string -} diff --git a/packages/tools/src/versioning/versioner.ts b/packages/tools/src/versioning/versioner.ts index 17ad4522ff..dafb91be94 100644 --- a/packages/tools/src/versioning/versioner.ts +++ b/packages/tools/src/versioning/versioner.ts @@ -4,9 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import colors from "ansi-colors"; import { existsSync, readFileSync } from "fs"; import { cp, writeFile } from "fs/promises"; +import { ansi } from "../ansi-text/text-builder.js"; import { Graph } from "../building/graph.js"; import { execute } from "../running/execute.js"; import { Package } from "../util/package.js"; @@ -54,7 +54,7 @@ export class Versioner { this.#members = new Set(graph.nodes.map(node => node.pkg.name)); for (const node of graph.nodes) { - const what = `Apply ${colors.bold(this.#definiteVersion)} to ${colors.bold(node.pkg.name)}`; + const what = `Apply ${ansi.bold(this.#definiteVersion)} to ${ansi.bold(node.pkg.name)}`; progress?.update(what); if (this.#applyOne(node.pkg)) { progress?.success(what); diff --git a/packages/types/src/clusters/access-control.ts b/packages/types/src/clusters/access-control.ts index 08fc677691..e51670764f 100644 --- a/packages/types/src/clusters/access-control.ts +++ b/packages/types/src/clusters/access-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -9,34 +9,629 @@ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; import { WritableFabricScopedAttribute, - OptionalWritableFabricScopedAttribute, - FixedAttribute, Event, - EventPriority + EventPriority, + FixedAttribute, + FabricScopedAttribute, + Command } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; -import { TlvField, TlvObject } from "../tlv/TlvObject.js"; -import { TlvEnum, TlvUInt16 } from "../tlv/TlvNumber.js"; -import { TlvSubjectId } from "../datatype/SubjectId.js"; -import { TlvNullable } from "../tlv/TlvNullable.js"; -import { TlvClusterId } from "../datatype/ClusterId.js"; -import { TlvEndpointNumber } from "../datatype/EndpointNumber.js"; -import { TlvDeviceTypeId } from "../datatype/DeviceTypeId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js"; +import { TlvByteString, TlvString } from "../tlv/TlvString.js"; import { TlvFabricIndex } from "../datatype/FabricIndex.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { AccessLevel } from "#model"; -import { TlvByteString } from "../tlv/TlvString.js"; import { TlvNodeId } from "../datatype/NodeId.js"; +import { TlvNullable } from "../tlv/TlvNullable.js"; +import { TlvUInt16, TlvEnum, TlvUInt32, TlvUInt64 } from "../tlv/TlvNumber.js"; +import { TlvEndpointNumber } from "../datatype/EndpointNumber.js"; +import { TlvClusterId } from "../datatype/ClusterId.js"; +import { BitFlag } from "../schema/BitmapSchema.js"; +import { TlvSubjectId } from "../datatype/SubjectId.js"; +import { TlvDeviceTypeId } from "../datatype/DeviceTypeId.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; -export namespace AccessControl { +export namespace AccessControl { + /** + * These are optional features supported by AccessControlCluster. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.4 + */ + export enum Feature { + /** + * Extension (EXTS) + * + * This feature indicates the device supports ACL Extension attribute. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.4.1 + */ + Extension = "Extension", + + /** + * ManagedDevice (MNGD) + * + * This feature is for a device that is managed by a service associated with the device vendor and which + * imposes default access restrictions upon each new fabric added to it. This could arise, for example, if the + * device is managed by a service provider under contract to an end-user, in such a way that the manager of the + * device does not unconditionally grant universal access to all of a device’s functionality, even for fabric + * administrators. For example, many Home Routers are managed by an Internet Service Provider (a service), and + * these services often have a policy that requires them to obtain user consent before certain administrative + * functions can be delegated to a third party (e.g., a fabric Administrator). These restrictions are expressed + * using an Access Restriction List (ARL). + * + * The purpose of this feature on the Access Control cluster is to indicate to a fabric Administrator that + * access by it to specific attributes, commands and/or events for specific clusters is currently prohibited. + * Attempts to access these restricted data model elements shall result in an error of ACCESS_RESTRICTED. + * + * A device that implements this feature shall have a mechanism to honor the ReviewFabricRestrictions command, + * such as user interfaces or service interactions associated with a service provider or the device + * manufacturer, which allows the owner (or subscriber) to manage access restrictions for each fabric. The user + * interface design, which includes the way restrictions are organized and presented to the user, is not + * specified, but SHOULD be usable by non-expert end-users from common mobile devices, personal computers, or + * an on-device user interface. + * + * Controllers and clients SHOULD incorporate generic handling of the ACCESS_RESTRICTED error code, when it + * appears in allowed contexts, in order to gracefully handle situations where this feature is encountered. + * Device vendors that adopt this feature SHOULD be judicious in its use given the risk of unexpected behavior + * in controllers and clients. + * + * For certification testing, a device that implements this feature shall provide a way for all restrictions to + * be removed. + * + * The ARL attribute provides the set of restrictions currently applied to this fabric. + * + * The ReviewFabricRestrictions command provides a way for the fabric Administrator to request that the server + * triggers a review of the current fabric restrictions, by involving external entities such as end-users, or + * other services associated with the manager of the device hosting the server. This review process may involve + * communication between external services and the user, and may take an unpredictable amount of time to + * complete since an end-user may need to visit some resources, such as a mobile application or web site. A + * FabricRestrictionReviewUpdate event will be generated by the device within a predictable time period of the + * ReviewFabricRestrictionsResponse (see ReviewFabricRestrictions for specification of this time period), and + * this event can be correlated with the ReviewFabricRestrictionsResponse using a token provided in both. The + * device may provide instructions or a Redirect URL in the FabricRestrictionReviewUpdate event in order to + * help the user access the features required for managing per-fabric restrictions. + * + * See Section 6.6.2, “Model” for a description of how access control is impacted by the ARL attribute. + * + * ### Managed Device Feature Usage Restrictions + * + * Use of this feature shall be limited to the mandatory clusters of endpoints having a device type that + * explicitly permits its use in the Device Library Specification. As a reminder, the device types associated + * with an endpoint are listed in the Descriptor cluster of the endpoint. + * + * In addition, use of this feature shall NOT restrict the following clusters on any endpoint: + * + * 1. the Descriptor Cluster (0x001D) + * + * 2. the Binding Cluster (0x001E) + * + * 3. the Network Commissioning Cluster (0x0031) + * + * 4. the Identify Cluster (0x0003) + * + * 5. the Groups Cluster (0x0004) + * + * In addition, use of this feature shall NOT restrict the global attributes of any cluster. + * + * Because ARLs cannot be used to restrict root node access or access to any clusters required for + * commissioning, administrators may determine the current restrictions of the ARL at any point, including + * during commissioning after joining the fabric. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.4.2 + */ + ManagedDevice = "ManagedDevice" + } + + /** + * @see {@link MatterSpecification.v13.Core} § 9.10.5.7 + */ + export const TlvAccessControlExtension = TlvObject({ + /** + * This field may be used by manufacturers to store arbitrary TLV-encoded data related to a fabric’s + * + * Access Control Entries. + * + * The contents shall consist of a top-level anonymous list; each list element shall include a profile-specific + * tag encoded in fully-qualified form. + * + * Administrators may iterate over this list of elements, and interpret selected elements at their discretion. + * The content of each element is not specified, but may be coordinated among manufacturers at their discretion. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.7.1 + */ + data: TlvField(1, TlvByteString.bound({ maxLength: 128 })), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 9.10.5.7 + */ + export interface AccessControlExtension extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 9.10.5.1 + */ + export enum ChangeType { + /** + * Entry or extension was changed + */ + Changed = 0, + + /** + * Entry or extension was added + */ + Added = 1, + + /** + * Entry or extension was removed + */ + Removed = 2 + } + + /** + * Body of the AccessControl accessControlExtensionChanged event + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.2 + */ + export const TlvAccessControlExtensionChangedEvent = TlvObject({ + /** + * The Node ID of the Administrator that made the change, if the change occurred via a CASE session. + * + * Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change occurred via a + * CASE or PASE session; the other shall be null. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.2.1 + */ + adminNodeId: TlvField(1, TlvNullable(TlvNodeId)), + + /** + * The Passcode ID of the Administrator that made the change, if the change occurred via a PASE session. + * Non-zero values are reserved for future use (see PasscodeId generation in PBKDFParamRequest). + * + * Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change occurred via a + * CASE or PASE session; the other shall be null. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.2.2 + */ + adminPasscodeId: TlvField(2, TlvNullable(TlvUInt16)), + + /** + * The type of change as appropriate. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.2.3 + */ + changeType: TlvField(3, TlvEnum()), + + /** + * The latest value of the changed extension. + * + * This field SHOULD be set if resources are adequate for it; otherwise it shall be set to NULL if resources + * are scarce. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.2.4 + */ + latestValue: TlvField(4, TlvNullable(TlvAccessControlExtension)), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * Body of the AccessControl accessControlExtensionChanged event + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.2 + */ + export interface AccessControlExtensionChangedEvent extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 9.10.5.3 + */ + export enum AccessRestrictionType { + /** + * Clients on this fabric are currently forbidden from reading and writing an attribute + */ + AttributeAccessForbidden = 0, + + /** + * Clients on this fabric are currently forbidden from writing an attribute + */ + AttributeWriteForbidden = 1, + + /** + * Clients on this fabric are currently forbidden from invoking a command + */ + CommandForbidden = 2, + + /** + * Clients on this fabric are currently forbidden from reading an event + */ + EventForbidden = 3 + } + + /** + * This structure describes an access restriction that would be applied to a specific data model element on a given + * endpoint/cluster pair (see AccessRestrictionEntryStruct). + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.8 + */ + export const TlvAccessRestriction = TlvObject({ + /** + * This field shall indicate the type of restriction, for example, AttributeAccessForbidden. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.8.1 + */ + type: TlvField(0, TlvEnum()), + + /** + * This field shall indicate the element Manufacturer Extensible Identifier (MEI) associated with the element + * type subject to the access restriction, based upon the AccessRestrictionTypeEnum. When the Type is + * AttributeAccessForbidden or AttributeWriteForbidden, this value shall be considered of type attrib-id (i.e. + * an attribute identifier). When the Type is CommandForbidden, this value shall be considered of type + * command-id (i.e. an attribute identifier). When the Type is EventForbidden, this value shall be considered + * of type event-id (i.e. an event identifier). + * + * A null value shall indicate the wildcard value for the given value of Type (i.e. all elements associated + * with the Type under the associated endpoint and cluster for the containing AccessRestrictionEntryStruct). + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.8.2 + */ + id: TlvField(1, TlvNullable(TlvUInt32)) + }); + + /** + * This structure describes an access restriction that would be applied to a specific data model element on a given + * endpoint/cluster pair (see AccessRestrictionEntryStruct). + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.8 + */ + export interface AccessRestriction extends TypeFromSchema {} + + /** + * This structure describes a current access restriction when there is no accessing fabric. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.10 + */ + export const TlvCommissioningAccessRestrictionEntry = TlvObject({ + /** + * This field shall indicate the endpoint having associated access restrictions scoped to the associated fabric + * of the list containing the entry. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.10.1 + */ + endpoint: TlvField(0, TlvEndpointNumber), + + /** + * This field shall indicate the cluster having associated access restrictions under the entry’s Endpoint, + * scoped to the associated fabric of the list containing the entry. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.10.2 + */ + cluster: TlvField(1, TlvClusterId), + + /** + * This field shall indicate the set of restrictions applying to the Cluster under the given Endpoint, scoped + * to the associated fabric of the list containing the entry. + * + * This list shall NOT be empty. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.10.3 + */ + restrictions: TlvField(2, TlvArray(TlvAccessRestriction, { minLength: 1 })) + }); + + /** + * This structure describes a current access restriction when there is no accessing fabric. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.10 + */ + export interface CommissioningAccessRestrictionEntry extends TypeFromSchema {} + + /** + * This structure describes a current access restriction on the fabric. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.9 + */ + export const TlvAccessRestrictionEntry = TlvObject({ + /** + * This field shall indicate the endpoint having associated access restrictions scoped to the associated fabric + * of the list containing the entry. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.9.1 + */ + endpoint: TlvField(0, TlvEndpointNumber), + + /** + * This field shall indicate the cluster having associated access restrictions under the entry’s Endpoint, + * scoped to the associated fabric of the list containing the entry. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.9.2 + */ + cluster: TlvField(1, TlvClusterId), + + /** + * This field shall indicate the set of restrictions applying to the Cluster under the given Endpoint, scoped + * to the associated fabric of the list containing the entry. + * + * This list shall NOT be empty. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.9.3 + */ + restrictions: TlvField(2, TlvArray(TlvAccessRestriction, { minLength: 1 })), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * This structure describes a current access restriction on the fabric. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.5.9 + */ + export interface AccessRestrictionEntry extends TypeFromSchema {} + + /** + * Input to the AccessControl reviewFabricRestrictions command + * + * @see {@link MatterSpecification.v13.Core} § 9.10.8.1 + */ + export const TlvReviewFabricRestrictionsRequest = TlvObject({ + /** + * When the ARL field is provided, it indicates the specific restrictions that are requested for review. An + * empty list represents a generic request for review of all restrictions. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.8.1.1 + */ + arl: TlvField(0, TlvArray(TlvCommissioningAccessRestrictionEntry)) + }); + + /** + * Input to the AccessControl reviewFabricRestrictions command + * + * @see {@link MatterSpecification.v13.Core} § 9.10.8.1 + */ + export interface ReviewFabricRestrictionsRequest extends TypeFromSchema {} + + /** + * Returns the review token for the request, which can be used to correlate with a FabricRestrictionReviewUpdate + * event. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.8.2 + */ + export const TlvReviewFabricRestrictionsResponse = TlvObject({ + /** + * This field shall specify a Token that can be used to correlate a ReviewFabricRestrictionsResponse with a + * FabricRestrictionReviewUpdate event. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.8.2.1 + */ + token: TlvField(0, TlvUInt64) + }); + + /** + * Returns the review token for the request, which can be used to correlate with a FabricRestrictionReviewUpdate + * event. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.8.2 + */ + export interface ReviewFabricRestrictionsResponse extends TypeFromSchema {} + + /** + * Body of the AccessControl fabricRestrictionReviewUpdate event + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.3 + */ + export const TlvFabricRestrictionReviewUpdateEvent = TlvObject({ + /** + * This field shall indicate the Token that can be used to correlate a ReviewFabricRestrictionsResponse with a + * FabricRestrictionReviewUpdate event. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.3.1 + */ + token: TlvField(0, TlvUInt64), + + /** + * This field shall provide human readable text that may be displayed to the user to help them locate the user + * interface for managing access restrictions for each fabric. + * + * A device SHOULD implement the Localization Configuration Cluster when it has no other means to determine the + * locale to use for this text. + * + * Examples include "Please try again and immediately access device display for further instructions." or + * "Please check email associated with your Acme account." + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.3.2 + */ + instruction: TlvOptionalField(1, TlvString.bound({ maxLength: 512 })), + + /** + * This field shall indicate the URL for the service associated with the device maker which the user can visit + * to manage fabric limitations. The syntax of this field shall follow the syntax as specified in RFC 1738 and + * shall use the https scheme for internet-hosted URLs. + * + * • The URL may embed the token, fabric index, fabric vendor, or other information transparently in order to + * pass context about the originating ReviewFabricRestrictions command to the service associated with the + * URL. The service associated with the device vendor may perform vendor ID verification on the fabric from + * which the ReviewFabricRestrictions command originated. + * + * • If the device grants the request, the ARL attribute in the Access Control Cluster shall be updated to + * reflect the new access rights and a successful response shall be returned to the device making the + * request using the MTaer field of the callbackUrl. If the request is denied, the ARL attribute shall + * remain unchanged and a failure response shall be returned to the device making the request using the + * MTaer field of the callbackUrl. + * + * • The device using this mechanism shall provide a service at the URL that can accept requests for + * additional access and return responses indicating whether the requests were granted or denied. + * + * • This URL will typically lead to a server which (e.g. by looking at the User-Agent) redirects the user to + * allow viewing, downloading, installing or using a manufacturer-provided means for guiding the user + * through the process to review and approve or deny the request. The device manufacturer may choose to use + * a constructed URL which is valid in a HTTP GET request (i.e. dedicated for the product) such as, for + * example, https://domain.example/arl-app?vid=FFF1& pid=1234. If a client follows or launches the + * ARLRequestFlowUrl, it shall expand it as described in Section 9.10.9.3.4, “ARLRequestFlowUrl format”. + * + * • A manufacturer contemplating using this flow should realize that + * + * ◦ This flow typically requires internet access to access the URL, and access extension may fail when + * internet connectivity is not available. + * + * ◦ If the flow prefers to redirect the user to an app which is available on popular platforms, it SHOULD + * also provide a fallback option such as a web browser interface to ensure users can complete access + * extension. + * + * ### ARLRequestFlowUrl format + * + * The ARLRequestFlowUrl shall contain a query component (see RFC 3986 section 3.4) composed of one or more + * key-value pairs: + * + * • The query shall use the & delimiter between key/value pairs. + * + * • The key-value pairs shall in the format name= where name is the key name, and + * + * is the contents of the value encoded with proper URL-encoded escaping. + * + * • If key MTcu is present, it shall have a value of "_" (i.e. MTcu=_). This is the "callback URL + * + * backUrl) placeholder". + * + * • Any key whose name begins with MT not mentioned in the previous bullets shall be reserved for future use + * by this specification. Manufacturers shall NOT include query keys starting with MT in the + * ARLRequestFlowUrl unless they are referenced by a version of this specification. + * + * Any other element in the ARLRequestFlowUrl query field not covered by the above rules, as well as the + * fragment field (if present), shall remain including the order of query key/value pairs present. + * + * Expansion of ARLRequestFlowUrl by client + * + * Once the URL is obtained, it shall be expanded to form a final URL (ExpandedARLRequestFlowUrl) by proceeding + * with the following substitution algorithm on the original ARLRequestFlowUrl: + * + * 1. If key MTcu is present, compute the CallbackUrl desired (see Section 9.10.9.3.5, “CallbackUrl format + * for ARL Request Flow response”), and substitute the placeholder value "_" (i.e. in MTcu=_) in the + * ARLRequestFlowUrl with the desired contents, encoded with proper URL-encoded escaping (see RFC 3986 + * section 2). + * + * The final URL after expansion (ExpandedARLRequestFlowUrl) shall be the one to follow, rather than the + * original value obtained from the FabricRestrictionReviewUpdate event. + * + * ### CallbackUrl format for ARL Request Flow response + * + * If a CallbackUrl field (i.e. MTcu=) query field placeholder is present in the ARLRequestFlowUrl, the client + * may replace the placeholder value "_" in the ExpandedARLRequestFlowUrl with a URL that the manufacturer flow + * can use to make a smooth return to the client when the ARL flow has terminated. + * + * This URL field may contain a query component (see RFC 3986 section 3.4). If a query is present, it shall be + * composed of one or more key-value pairs: + * + * • The query shall use the & delimiter between key/value pairs. + * + * • The key-value pairs shall follow the format name= where name is the key name, and + * + * is the contents of the value encoded with proper URL-encoded escaping. + * + * • If key MTaer is present, it shall have a value of "_" (i.e. MTaer=_). This is the placeholder for a + * "access extension response" provided by the manufacturer flow to the client. The manufacturer flow shall + * replace this placeholder with the final status of the access extension request, which shall be formatted + * following Expansion of CallbackUrl by the manufacturer custom flow and encoded with proper URL-encoded + * escaping. + * + * • Any key whose name begins with MT not mentioned in the previous bullets shall be reserved for future use + * by this specification. + * + * Any other element in the CallbackUrl query field not covered by the above rules, as well as the frag + * + * ment field (if present), shall remain as provided by the client through embedding within the + * + * ExpandedARLRequestFlowUrl, including the order of query key/value pairs present. + * + * ### Expansion of CallbackUrl by the manufacturer custom flow + * + * Once the CallbackUrl is obtained by the manufacturer flow, it may be expanded to form a final + * ExpandedARLRequestCallbackUrl URL to be used by proceeding with the following substitution algorithm on the + * provided CallbackUrl: + * + * • If key MTaer is present, the manufacturer custom flow having received the initial query containing the + * CallbackUrl shall substitute the placeholder value "_" (i.e. in MTaer=_) in the CallbackUrl with the + * final status of the access extension request flow which shall be one of the following. Any value + * returned in the MTaer field not listed above shall be considered an error and shall be treated as + * GeneralFailure. + * + * ◦ Success - The flow completed successfully and the ARL attribute was updated. The client may now read + * the ARL attribute to determine the new access restrictions. + * + * ◦ NoChange - The ARL attribute was already listing minimum restrictions for the requesting fabric. + * + * ◦ GeneralFailure - The flow failed for an unspecified reason. + * + * ◦ FlowAuthFailure - The user failed to authenticate to the flow. + * + * ◦ NotFound - Access extension failed because the target fabric was not found. + * + * A manufacturer custom flow having received an ExpandedARLRequestFlowUrl SHOULD attempt to open the + * ExpandedARLRequestCallbackUrl, on completion of the request, if an ExpandedARLRequestCallbackUrl was + * computed from the CallbackUrl and opening such a URL is supported. + * + * Examples of ARLRequestFlowUrl URLs + * + * Below are some examples of valid ExpandedARLRequestFlowUrl for several valid values of ARLRequestFlowUrl, as + * well as some examples of invalid values of ARLRequestFlowUrl: + * + * • Invalid URL with no query string: http scheme is not allowed: + * + * ◦ http://company.domain.example/matter/arl/vFFF1p1234 + * + * • Valid URL : + * + * ◦ https://company.domain.example/matter/arl/vFFF1p1234 + * + * • Valid URL, CallbackUrl requested: + * + * ◦ Before expansion: + * + * https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTcu=_ + * + * ◦ After expansion: + * + * https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTcu=https%3A%2F%2Fc + * lient.domain.example%2Fcb%3Ftoken%3DmAsJ6_vqbr-vjDiG_w%253D%253D%26MTaer%3D_ + * + * ◦ The ExpandedARLRequestFlowUrl URL contains: + * + * ▪ A CallbackUrl with a client-provided arbitrary token= key/value pair and the MTaer= key/value pair + * place-holder to indicate support for a return access extension completion status: + * https://client.domain.example/cb?token=mAsJ6_vqbr-vjDiG_w%3D%3D&MTaer=_ + * + * ▪ After expansion of the CallbackUrl (MTcu key) into an ExpandedCallbackUrl, with an example return + * access extension completion status of Success, the ExpandedARLRequestCallbackUrl would be: + * + * https://client.domain.example/cb?token=mAsJ6_vqbr- vjDiG_w%3D%3D&MTaer=Success + * + * Note that the MTcu key/value pair was initially provided URL-encoded within the ExpandedARLRequestFlowUrl + * URL and the MTaer=_ key/value pair placeholder now contains a substituted returned completion status. + * + * • Invalid URL, due to MTza=79 key/value pair in reserved MT-prefixed keys reserved for future use: + * + * ◦ https://company.domain.example/matter/arl?vid=FFF1&pid=1234&MTop=_&MTza=79 + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.3.3 + */ + arlRequestFlowUrl: TlvOptionalField(2, TlvString.bound({ maxLength: 256 })), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * Body of the AccessControl fabricRestrictionReviewUpdate event + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.3 + */ + export interface FabricRestrictionReviewUpdateEvent extends TypeFromSchema {} + /** * Proxy View Value * * This value implicitly grants View privileges * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.2 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.2 */ export enum AccessControlEntryPrivilege { /** @@ -54,7 +649,7 @@ export namespace AccessControl { * * This value implicitly grants View privileges * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.2.1 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.2.1 */ Operate = 3, @@ -63,7 +658,7 @@ export namespace AccessControl { * * This value implicitly grants Operate & View privileges * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.2.2 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.2.2 */ Manage = 4, @@ -72,13 +667,13 @@ export namespace AccessControl { * * This value implicitly grants Manage, Operate, Proxy View & View privileges * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.2.3 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.2.3 */ Administer = 5 } /** - * @see {@link MatterSpecification.v13.Core} § 9.10.4.3 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.4 */ export enum AccessControlEntryAuthMode { /** @@ -98,7 +693,7 @@ export namespace AccessControl { } /** - * @see {@link MatterSpecification.v13.Core} § 9.10.4.4 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.5 */ export const TlvAccessControlTarget = TlvObject({ cluster: TlvField(0, TlvNullable(TlvClusterId)), @@ -107,12 +702,12 @@ export namespace AccessControl { }); /** - * @see {@link MatterSpecification.v13.Core} § 9.10.4.4 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.5 */ export interface AccessControlTarget extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Core} § 9.10.4.5 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.6 */ export const TlvAccessControlEntry = TlvObject({ /** @@ -128,7 +723,7 @@ export namespace AccessControl { * levels as well. The following diagram illustrates how the higher privilege levels subsume the lower * privilege levels: * - * Figure 43. Access Control Privilege Levels + * Figure 46. Access Control Privilege Levels * * Individual clusters shall define whether attributes are readable, writable, or both readable and writable. * Clusters also shall define which privilege is minimally required to be able to perform a particular read or @@ -139,14 +734,14 @@ export namespace AccessControl { * Cluster itself. The Administer privilege shall NOT be used on Access Control Entries which use the Group * auth mode. * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.5.1 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.6.1 */ privilege: TlvField(1, TlvEnum()), /** * The AuthMode field shall specify the authentication mode required by this Access Control Entry. * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.5.2 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.6.2 */ authMode: TlvField(2, TlvEnum()), @@ -166,7 +761,7 @@ export namespace AccessControl { * successfully authenticates via AuthMode. The subjects list shall NOT be empty if the entry’s AuthMode is * PASE. * - * The PASE AuthMode is reserved for future use (see Section 6.6.2.8, “Bootstrapping of the Access Control + * The PASE AuthMode is reserved for future use (see Section 6.6.2.9, “Bootstrapping of the Access Control * Cluster”). An attempt to write an entry with AuthMode set to PASE shall fail with a status code of * CONSTRAINT_ERROR. * @@ -183,7 +778,7 @@ export namespace AccessControl { * For Group authentication, the Group ID identifies the required group, as defined in the Group Key Management * Cluster. * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.5.3 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.6.3 */ subjects: TlvField(3, TlvNullable(TlvArray(TlvSubjectId))), @@ -206,7 +801,7 @@ export namespace AccessControl { * An empty targets list indicates a wildcard: that is, this entry shall grant access to all cluster instances * on all endpoints on this Node. * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.5.4 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.6.4 */ targets: TlvField(4, TlvNullable(TlvArray(TlvAccessControlTarget))), @@ -214,60 +809,14 @@ export namespace AccessControl { }); /** - * @see {@link MatterSpecification.v13.Core} § 9.10.4.5 + * @see {@link MatterSpecification.v13.Core} § 9.10.5.6 */ export interface AccessControlEntry extends TypeFromSchema {} - /** - * @see {@link MatterSpecification.v13.Core} § 9.10.4.6 - */ - export const TlvAccessControlExtension = TlvObject({ - /** - * This field may be used by manufacturers to store arbitrary TLV-encoded data related to a fabric’s Access - * Control Entries. - * - * The contents shall consist of a top-level anonymous list; each list element shall include a profile-specific - * tag encoded in fully-qualified form. - * - * Administrators may iterate over this list of elements, and interpret selected elements at their discretion. - * The content of each element is not specified, but may be coordinated among manufacturers at their discretion. - * - * @see {@link MatterSpecification.v13.Core} § 9.10.4.6.1 - */ - data: TlvField(1, TlvByteString.bound({ maxLength: 128 })), - - fabricIndex: TlvField(254, TlvFabricIndex) - }); - - /** - * @see {@link MatterSpecification.v13.Core} § 9.10.4.6 - */ - export interface AccessControlExtension extends TypeFromSchema {} - - /** - * @see {@link MatterSpecification.v13.Core} § 9.10.4.1 - */ - export enum ChangeType { - /** - * Entry or extension was changed - */ - Changed = 0, - - /** - * Entry or extension was added - */ - Added = 1, - - /** - * Entry or extension was removed - */ - Removed = 2 - } - /** * Body of the AccessControl accessControlEntryChanged event * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.1 + * @see {@link MatterSpecification.v13.Core} § 9.10.9.1 */ export const TlvAccessControlEntryChangedEvent = TlvObject({ /** @@ -276,7 +825,7 @@ export namespace AccessControl { * Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change occurred via a * CASE or PASE session; the other shall be null. * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.1.1 + * @see {@link MatterSpecification.v13.Core} § 9.10.9.1.1 */ adminNodeId: TlvField(1, TlvNullable(TlvNodeId)), @@ -287,14 +836,14 @@ export namespace AccessControl { * Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change occurred via a * CASE or PASE session; the other shall be null. * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.1.2 + * @see {@link MatterSpecification.v13.Core} § 9.10.9.1.2 */ adminPasscodeId: TlvField(2, TlvNullable(TlvUInt16)), /** * The type of change as appropriate. * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.1.3 + * @see {@link MatterSpecification.v13.Core} § 9.10.9.1.3 */ changeType: TlvField(3, TlvEnum()), @@ -304,7 +853,7 @@ export namespace AccessControl { * This field SHOULD be set if resources are adequate for it; otherwise it shall be set to NULL if resources * are scarce. * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.1.4 + * @see {@link MatterSpecification.v13.Core} § 9.10.9.1.4 */ latestValue: TlvField(4, TlvNullable(TlvAccessControlEntry)), @@ -314,71 +863,243 @@ export namespace AccessControl { /** * Body of the AccessControl accessControlEntryChanged event * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.1 + * @see {@link MatterSpecification.v13.Core} § 9.10.9.1 */ export interface AccessControlEntryChangedEvent extends TypeFromSchema {} /** - * Body of the AccessControl accessControlExtensionChanged event - * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.2 + * A AccessControlCluster supports these elements if it supports feature Extension. */ - export const TlvAccessControlExtensionChangedEvent = TlvObject({ - /** - * The Node ID of the Administrator that made the change, if the change occurred via a CASE session. - * - * Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change occurred via a - * CASE or PASE session; the other shall be null. - * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.2.1 - */ - adminNodeId: TlvField(1, TlvNullable(TlvNodeId)), - - /** - * The Passcode ID of the Administrator that made the change, if the change occurred via a PASE session. - * Non-zero values are reserved for future use (see PasscodeId generation in PBKDFParamRequest). - * - * Exactly one of AdminNodeID and AdminPasscodeID shall be set, depending on whether the change occurred via a - * CASE or PASE session; the other shall be null. - * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.2.2 - */ - adminPasscodeId: TlvField(2, TlvNullable(TlvUInt16)), - - /** - * The type of change as appropriate. - * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.2.3 - */ - changeType: TlvField(3, TlvEnum()), - - /** - * The latest value of the changed extension. - * - * This field SHOULD be set if resources are adequate for it; otherwise it shall be set to NULL if resources - * are scarce. - * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.2.4 - */ - latestValue: TlvField(4, TlvNullable(TlvAccessControlExtension)), + export const ExtensionComponent = MutableCluster.Component({ + attributes: { + /** + * If present, the Access Control Extensions may be used by Administrators to store arbitrary data related + * to fabric’s Access Control Entries. + * + * The Access Control Extension list shall support a single extension entry per supported fabric. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.6.4 + */ + extension: WritableFabricScopedAttribute( + 0x1, + TlvArray(TlvAccessControlExtension), + { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ) + }, - fabricIndex: TlvField(254, TlvFabricIndex) + events: { + /** + * The cluster shall generate AccessControlExtensionChanged events whenever its extension attribute data is + * changed by an Administrator. + * + * • Each added extension shall generate an event with ChangeType Added. + * + * • Each changed extension shall generate an event with ChangeType Changed. + * + * • Each removed extension shall generate an event with ChangeType Removed. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.2 + */ + accessControlExtensionChanged: Event( + 0x1, + EventPriority.Info, + TlvAccessControlExtensionChangedEvent, + { readAcl: AccessLevel.Administer } + ) + } }); /** - * Body of the AccessControl accessControlExtensionChanged event - * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.2 + * A AccessControlCluster supports these elements if it supports feature ManagedDevice. */ - export interface AccessControlExtensionChangedEvent extends TypeFromSchema {} + export const ManagedDeviceComponent = MutableCluster.Component({ + attributes: { + /** + * This attribute shall provide the set of CommissioningAccessRestrictionEntryStruct applied during + * commissioning on a managed device. + * + * When present, the CommissioningARL attribute shall indicate the access restrictions applying during + * commissioning. + * + * Attempts to access data model elements described by an entry in the CommissioningARL attribute during + * commissioning shall result in an error of ACCESS_RESTRICTED. See Access Control Model for more + * information about the features related to controlling access to a Node’s Endpoint Clusters ("Targets" + * hereafter) from other Nodes. + * + * See Section 9.10.4.2.1, “Managed Device Feature Usage Restrictions” for limitations on the use of access + * restrictions. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.6.8 + */ + commissioningArL: FixedAttribute(0x5, TlvArray(TlvCommissioningAccessRestrictionEntry), { default: [] }), + + /** + * This attribute shall provide the set of AccessRestrictionEntryStruct applied to the associated fabric on + * a managed device. + * + * When present, the ARL attribute shall indicate the access restrictions applying to the accessing fabric. + * In contrast, the CommissioningARL attribute indicates the accessing restrictions that apply when there + * is no accessing fabric, such as during commissioning. + * + * The access restrictions are externally added/removed based on the particular relationship the device + * hosting this server has with external entities such as its owner, external service provider, or end-user. + * + * Attempts to access data model elements described by an entry in the ARL attribute for the accessing + * fabric shall result in an error of ACCESS_RESTRICTED. See Access Control Model for more information + * about the features related to controlling access to a Node’s Endpoint Clusters ("Targets" hereafter) + * from other Nodes. + * + * See Section 9.10.4.2.1, “Managed Device Feature Usage Restrictions” for limitations on the use of access + * restrictions. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.6.9 + */ + arl: FabricScopedAttribute(0x6, TlvArray(TlvAccessRestrictionEntry), { default: [] }) + }, + + commands: { + /** + * This command signals to the service associated with the device vendor that the fabric administrator + * would like a review of the current restrictions on the accessing fabric. This command includes an + * optional list of ARL entries that the fabric administrator would like removed. + * + * In response, a ReviewFabricRestrictionsResponse is sent which contains a token that can be used to + * correlate a review request with a FabricRestrictionReviewUpdate event. + * + * Within 1 hour of the ReviewFabricRestrictionsResponse, the FabricRestrictionReviewUpdate event shall be + * generated, in order to indicate completion of the review and any additional steps required by the user + * for the review. + * + * A review may include obtaining consent from the user, which can take time. For example, the user may + * need to respond to an email or a push notification. + * + * The ARL attribute may change at any time due to actions taken by the user, or the service associated + * with the device vendor. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.8.1 + */ + reviewFabricRestrictions: Command( + 0x0, + TlvReviewFabricRestrictionsRequest, + 0x1, + TlvReviewFabricRestrictionsResponse, + { invokeAcl: AccessLevel.Administer } + ) + }, + + events: { + /** + * The cluster shall generate a FabricRestrictionReviewUpdate event to indicate completion of a fabric + * restriction review. Due to the requirement to generate this event within a bound time frame of + * successful receipt of the ReviewFabricRestrictions command, this event may include additional steps that + * the client may present to the user in order to help the user locate the user interface for the Managed + * Device feature. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.9.3 + */ + fabricRestrictionReviewUpdate: Event( + 0x2, + EventPriority.Info, + TlvFabricRestrictionReviewUpdateEvent, + { readAcl: AccessLevel.Administer } + ) + } + }); /** - * @see {@link Cluster} + * These elements and properties are present in all AccessControl clusters. */ - export const ClusterInstance = MutableCluster({ + export const Base = MutableCluster.Component({ id: 0x1f, name: "AccessControl", - revision: 1, + revision: 2, + + features: { + /** + * Extension + * + * This feature indicates the device supports ACL Extension attribute. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.4.1 + */ + extension: BitFlag(0), + + /** + * ManagedDevice + * + * This feature is for a device that is managed by a service associated with the device vendor and which + * imposes default access restrictions upon each new fabric added to it. This could arise, for example, if + * the device is managed by a service provider under contract to an end-user, in such a way that the + * manager of the device does not unconditionally grant universal access to all of a device’s + * functionality, even for fabric administrators. For example, many Home Routers are managed by an Internet + * Service Provider (a service), and these services often have a policy that requires them to obtain user + * consent before certain administrative functions can be delegated to a third party (e.g., a fabric + * Administrator). These restrictions are expressed using an Access Restriction List (ARL). + * + * The purpose of this feature on the Access Control cluster is to indicate to a fabric Administrator that + * access by it to specific attributes, commands and/or events for specific clusters is currently + * prohibited. Attempts to access these restricted data model elements shall result in an error of + * ACCESS_RESTRICTED. + * + * A device that implements this feature shall have a mechanism to honor the ReviewFabricRestrictions + * command, such as user interfaces or service interactions associated with a service provider or the + * device manufacturer, which allows the owner (or subscriber) to manage access restrictions for each + * fabric. The user interface design, which includes the way restrictions are organized and presented to + * the user, is not specified, but SHOULD be usable by non-expert end-users from common mobile devices, + * personal computers, or an on-device user interface. + * + * Controllers and clients SHOULD incorporate generic handling of the ACCESS_RESTRICTED error code, when it + * appears in allowed contexts, in order to gracefully handle situations where this feature is encountered. + * Device vendors that adopt this feature SHOULD be judicious in its use given the risk of unexpected + * behavior in controllers and clients. + * + * For certification testing, a device that implements this feature shall provide a way for all + * restrictions to be removed. + * + * The ARL attribute provides the set of restrictions currently applied to this fabric. + * + * The ReviewFabricRestrictions command provides a way for the fabric Administrator to request that the + * server triggers a review of the current fabric restrictions, by involving external entities such as + * end-users, or other services associated with the manager of the device hosting the server. This review + * process may involve communication between external services and the user, and may take an unpredictable + * amount of time to complete since an end-user may need to visit some resources, such as a mobile + * application or web site. A FabricRestrictionReviewUpdate event will be generated by the device within a + * predictable time period of the ReviewFabricRestrictionsResponse (see ReviewFabricRestrictions for + * specification of this time period), and this event can be correlated with the + * ReviewFabricRestrictionsResponse using a token provided in both. The device may provide instructions or + * a Redirect URL in the FabricRestrictionReviewUpdate event in order to help the user access the features + * required for managing per-fabric restrictions. + * + * See Section 6.6.2, “Model” for a description of how access control is impacted by the ARL attribute. + * + * ### Managed Device Feature Usage Restrictions + * + * Use of this feature shall be limited to the mandatory clusters of endpoints having a device type that + * explicitly permits its use in the Device Library Specification. As a reminder, the device types + * associated with an endpoint are listed in the Descriptor cluster of the endpoint. + * + * In addition, use of this feature shall NOT restrict the following clusters on any endpoint: + * + * 1. the Descriptor Cluster (0x001D) + * + * 2. the Binding Cluster (0x001E) + * + * 3. the Network Commissioning Cluster (0x0031) + * + * 4. the Identify Cluster (0x0003) + * + * 5. the Groups Cluster (0x0004) + * + * In addition, use of this feature shall NOT restrict the global attributes of any cluster. + * + * Because ARLs cannot be used to restrict root node access or access to any clusters required for + * commissioning, administrators may determine the current restrictions of the ARL at any point, including + * during commissioning after joining the fabric. + * + * @see {@link MatterSpecification.v13.Core} § 9.10.4.2 + */ + managedDevice: BitFlag(1) + }, attributes: { /** @@ -393,7 +1114,7 @@ export namespace AccessControl { * Control Privilege Granting algorithm to determine if a subject has privilege to interact with targets on * the Node. * - * @see {@link MatterSpecification.v13.Core} § 9.10.5.3 + * @see {@link MatterSpecification.v13.Core} § 9.10.6.3 */ acl: WritableFabricScopedAttribute( 0x0, @@ -401,20 +1122,6 @@ export namespace AccessControl { { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } ), - /** - * If present, the Access Control Extensions may be used by Administrators to store arbitrary data related - * to fabric’s Access Control Entries. - * - * The Access Control Extension list shall support a single extension entry per supported fabric. - * - * @see {@link MatterSpecification.v13.Core} § 9.10.5.4 - */ - extension: OptionalWritableFabricScopedAttribute( - 0x1, - TlvArray(TlvAccessControlExtension), - { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } - ), - /** * This attribute shall provide the minimum number of Subjects per entry that are supported by this server. * @@ -423,7 +1130,7 @@ export namespace AccessControl { * given implementation, it is recommended to only use the minimum value required and avoid reporting a * higher value than the required minimum. * - * @see {@link MatterSpecification.v13.Core} § 9.10.5.5 + * @see {@link MatterSpecification.v13.Core} § 9.10.6.5 */ subjectsPerAccessControlEntry: FixedAttribute(0x2, TlvUInt16.bound({ min: 4 }), { default: 4 }), @@ -435,7 +1142,7 @@ export namespace AccessControl { * given implementation, it is recommended to only use the minimum value required and avoid reporting a * higher value than the required minimum. * - * @see {@link MatterSpecification.v13.Core} § 9.10.5.6 + * @see {@link MatterSpecification.v13.Core} § 9.10.6.6 */ targetsPerAccessControlEntry: FixedAttribute(0x3, TlvUInt16.bound({ min: 3 }), { default: 3 }), @@ -448,15 +1155,15 @@ export namespace AccessControl { * given implementation, it is recommended to only use the minimum value required and avoid reporting a * higher value than the required minimum. * - * @see {@link MatterSpecification.v13.Core} § 9.10.5.7 + * @see {@link MatterSpecification.v13.Core} § 9.10.6.7 */ accessControlEntriesPerFabric: FixedAttribute(0x4, TlvUInt16.bound({ min: 4 }), { default: 4 }) }, events: { /** - * The cluster shall send AccessControlEntryChanged events whenever its ACL attribute data is changed by an - * Administrator. + * The cluster shall generate AccessControlEntryChanged events whenever its ACL attribute data is changed + * by an Administrator. * * • Each added entry shall generate an event with ChangeType Added. * @@ -464,36 +1171,31 @@ export namespace AccessControl { * * • Each removed entry shall generate an event with ChangeType Removed. * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.1 + * @see {@link MatterSpecification.v13.Core} § 9.10.9.1 */ accessControlEntryChanged: Event( 0x0, EventPriority.Info, TlvAccessControlEntryChangedEvent, { readAcl: AccessLevel.Administer } - ), - - /** - * The cluster shall send AccessControlExtensionChanged events whenever its extension attribute data is - * changed by an Administrator. - * - * • Each added extension shall generate an event with ChangeType Added. - * - * • Each changed extension shall generate an event with ChangeType Changed. - * - * • Each removed extension shall generate an event with ChangeType Removed. - * - * @see {@link MatterSpecification.v13.Core} § 9.10.7.2 - */ - accessControlExtensionChanged: Event( - 0x1, - EventPriority.Info, - TlvAccessControlExtensionChangedEvent, - { readAcl: AccessLevel.Administer } ) - } + }, + + /** + * This metadata controls which AccessControlCluster elements matter.js activates for specific feature + * combinations. + */ + extensions: MutableCluster.Extensions( + { flags: { extension: true }, component: ExtensionComponent }, + { flags: { managedDevice: true }, component: ManagedDeviceComponent } + ) }); + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster(Base); + /** * The Access Control Cluster exposes a data model view of a Node’s Access Control List (ACL), which codifies the * rules used to manage and enforce Access Control for the Node’s endpoints and their associated cluster instances. @@ -503,12 +1205,65 @@ export namespace AccessControl { * The Access Control Cluster shall be present on the root node endpoint of each Node, and shall NOT be present on * any other Endpoint of any Node. * + * AccessControlCluster supports optional features that you can enable with the AccessControlCluster.with() factory + * method. + * * @see {@link MatterSpecification.v13.Core} § 9.10 */ export interface Cluster extends Identity {} export const Cluster: Cluster = ClusterInstance; - export const Complete = Cluster; + const EXTS = { extension: true }; + const MNGD = { managedDevice: true }; + + /** + * @see {@link Complete} + */ + export const CompleteInstance = MutableCluster({ + id: Cluster.id, + name: Cluster.name, + revision: Cluster.revision, + features: Cluster.features, + + attributes: { + ...Cluster.attributes, + extension: MutableCluster.AsConditional(ExtensionComponent.attributes.extension, { mandatoryIf: [EXTS] }), + commissioningArL: MutableCluster.AsConditional( + ManagedDeviceComponent.attributes.commissioningArL, + { mandatoryIf: [MNGD] } + ), + arl: MutableCluster.AsConditional(ManagedDeviceComponent.attributes.arl, { mandatoryIf: [MNGD] }) + }, + + commands: { + reviewFabricRestrictions: MutableCluster.AsConditional( + ManagedDeviceComponent.commands.reviewFabricRestrictions, + { mandatoryIf: [MNGD] } + ) + }, + + events: { + ...Cluster.events, + accessControlExtensionChanged: MutableCluster.AsConditional( + ExtensionComponent.events.accessControlExtensionChanged, + { mandatoryIf: [EXTS] } + ), + fabricRestrictionReviewUpdate: MutableCluster.AsConditional( + ManagedDeviceComponent.events.fabricRestrictionReviewUpdate, + { mandatoryIf: [MNGD] } + ) + } + }); + + /** + * This cluster supports all AccessControl features. It may support illegal feature combinations. + * + * If you use this cluster you must manually specify which features are active and ensure the set of active + * features is legal per the Matter specification. + */ + export interface Complete extends Identity {} + + export const Complete: Complete = CompleteInstance; } export type AccessControlCluster = AccessControl.Cluster; diff --git a/packages/types/src/clusters/account-login.ts b/packages/types/src/clusters/account-login.ts index c26291bdde..f1f0ef4a0c 100644 --- a/packages/types/src/clusters/account-login.ts +++ b/packages/types/src/clusters/account-login.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/actions.ts b/packages/types/src/clusters/actions.ts index 24060b296d..ab2f0583d1 100644 --- a/packages/types/src/clusters/actions.ts +++ b/packages/types/src/clusters/actions.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -41,8 +41,9 @@ export namespace Actions { * Can be used to set a static state of the associated endpoints (typically using InstantAction or * InstantActionWithTransition), or to bring these endpoints into a more dynamic state (typically using * StartAction), where the endpoints would e.g. gradually cycle through certain colors for a pleasing effect. A - * voice controller could use "set" (to map to InstantAction) or "play" (to map to StartAction) to trigger such - * actions. + * voice controller could use "set" (to map to InstantAction) or "play" (to map to StartAction) to trig + * + * ger such actions. * * Example: see examples 1 and 2. * @@ -223,7 +224,7 @@ export namespace Actions { * * @see {@link MatterSpecification.v13.Core} § 9.14.4.6.2 */ - name: TlvField(1, TlvString.bound({ maxLength: 32 })), + name: TlvField(1, TlvString.bound({ maxLength: 128 })), /** * This field shall indicate the type of action. The value of Type of an action, along with its @@ -300,8 +301,9 @@ export namespace Actions { /** * User-configured group of endpoints where an endpoint can be in any number of zones * - * Is a more general concept where an endpoint can be part of multiple zones, e.g. a light in the living room - * can be part of the "reading corner" zone (subset of the lights in the living room) but also part of the + * Is a more general concept where an endpoint can be part of multiple zones, e.g. a light in the living + * + * room can be part of the "reading corner" zone (subset of the lights in the living room) but also part of the * "downstairs" zone which contains all the lights on a floor, e.g. combining living room, kitchen and hallway. * This indicates that a user has defined this list of endpoints as something they logically would like to * control as a group, so Matter controllers could provide the user with a way to do as such. @@ -332,7 +334,7 @@ export namespace Actions { * * @see {@link MatterSpecification.v13.Core} § 9.14.4.7.2 */ - name: TlvField(1, TlvString.bound({ maxLength: 32 })), + name: TlvField(1, TlvString.bound({ maxLength: 128 })), /** * This field shall indicate the type of endpoint list, see EndpointListTypeEnum. @@ -717,8 +719,8 @@ export namespace Actions { /** * The SetupURL attribute (when provided) shall indicate a URL; its syntax shall follow the syntax as - * specified in RFC 3986, max. 512 ASCII characters. The location referenced by this URL shall provide - * additional information for the actions provided: + * specified in RFC 1738, max. 512 ASCII characters and shall use the https scheme. The location referenced + * by this URL shall provide additional information for the actions provided: * * • When used without suffix, it shall provide information about the various actions which the cluster * provides. @@ -949,9 +951,8 @@ export namespace Actions { * * • Information about logical grouping of endpoints on the Node (example: lights in a room) * - * • Information about named actions that can be performed on such a group of endpoints - * - * ple: recall a scene for a group of lights by its name) + * • Information about named actions that can be performed on such a group of endpoints (example: recall a scene + * for a group of lights by its name) * * • Commands to trigger such actions * diff --git a/packages/types/src/clusters/activated-carbon-filter-monitoring.ts b/packages/types/src/clusters/activated-carbon-filter-monitoring.ts index 4868ac3b00..8a2000e864 100644 --- a/packages/types/src/clusters/activated-carbon-filter-monitoring.ts +++ b/packages/types/src/clusters/activated-carbon-filter-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/administrator-commissioning.ts b/packages/types/src/clusters/administrator-commissioning.ts index 13b1127596..881b6c1325 100644 --- a/packages/types/src/clusters/administrator-commissioning.ts +++ b/packages/types/src/clusters/administrator-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -44,13 +44,12 @@ export namespace AdministratorCommissioning { export const TlvOpenBasicCommissioningWindowRequest = TlvObject({ /** * This field shall specify the time in seconds during which commissioning session establishment is allowed by - * the Node. This is known as Open Basic Commissioning Window (OBCW). This timeout shall follow guidance as - * specified in the initial Announcement Duration. + * the Node. This timeout shall follow guidance as specified in the initial Announcement Duration. * - * When a Node receives the Open Basic Commissioning Window command, it shall begin advertising on DNS-SD as - * described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as described in Section - * 11.19.8.2.1, “CommissioningTimeout Field”. When the command is received by a ICD, it shall enter into active - * mode. The ICD shall remain in Active Mode as long as one of these conditions is met: + * When a Node receives the OpenBasicCommissioningWindow command, it shall begin advertising on DNS-SD as + * described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as described in + * CommissioningTimeout. When the command is received by a ICD, it shall enter into active mode. The ICD shall + * remain in Active Mode as long as one of these conditions is met: * * • A commissioning window is open. * @@ -96,10 +95,10 @@ export namespace AdministratorCommissioning { export const TlvOpenCommissioningWindowRequest = TlvObject({ /** * This field shall specify the time in seconds during which commissioning session establishment is allowed by - * the Node. This is known as Open Commissioning Window (OCW). This timeout value shall follow guidance as - * specified in the initial Announcement Duration. The CommissioningTimeout applies only to cessation of any - * announcements and to accepting of new commissioning sessions; it does not apply to abortion of connections, - * i.e., a commissioning session SHOULD NOT abort prematurely upon expiration of this timeout. + * the Node. This timeout value shall follow guidance as specified in the initial Announcement Duration. The + * CommissioningTimeout applies only to cessation of any announcements and to accepting of new commissioning + * sessions; it does not apply to abortion of connections, i.e., a commissioning session SHOULD NOT abort + * prematurely upon expiration of this timeout. * * @see {@link MatterSpecification.v13.Core} § 11.19.8.1.1 */ @@ -111,7 +110,8 @@ export namespace AdministratorCommissioning { * concatenation of two values (w0 || L) shall be (CRYPTO_GROUP_SIZE_BYTES + * CRYPTO_PUBLIC_KEY_SIZE_BYTES)-octets long as detailed in Crypto_PAKEValues_Responder. It shall be derived * from an ephemeral passcode (See PAKE). It shall be deleted by the Node at the end of commissioning or - * expiration of OCW, and shall be deleted by the existing Administrator after sending it to the Node(s). + * expiration of the OpenCommissioningWindow command, and shall be deleted by the existing Administrator after + * sending it to the Node(s). * * @see {@link MatterSpecification.v13.Core} § 11.19.8.1.2 */ @@ -129,10 +129,9 @@ export namespace AdministratorCommissioning { /** * This field shall be used by the Node as the PAKE iteration count associated with the ephemeral PAKE passcode * verifier to be used for this commissioning, which shall be sent by the Node to the new Administrator’s - * software as response to the PBKDFParamRequest during PASE negotiation. - * - * The permitted range of values shall match the range specified in Section 3.9, “Password-Based Key Derivation - * Function (PBKDF)”, within the definition of the Crypto_PBKDFParameterSet. + * software as response to the PBKDFParamRequest during PASE negotiation. The permitted range of values shall + * match the range specified in Section 3.9, “Password-Based Key Derivation Function (PBKDF)”, within the + * definition of the Crypto_PBKDFParameterSet. * * @see {@link MatterSpecification.v13.Core} § 11.19.8.1.4 */ @@ -146,9 +145,9 @@ export namespace AdministratorCommissioning { * Crypto_PBKDFParameterSet. * * When a Node receives the Open Commissioning Window command, it shall begin advertising on DNS-SD as - * described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as described in Section - * 11.19.8.1.1, “CommissioningTimeout Field”. When the command is received by a ICD, it shall enter into active - * mode. The ICD shall remain in Active Mode as long as one of these conditions is met: + * described in Section 4.3.1, “Commissionable Node Discovery” and for a time period as described in + * CommissioningTimeout. When the command is received by a ICD, it shall enter into active mode. The ICD shall + * remain in Active Mode as long as one of these conditions is met: * * • A commissioning window is open. * @@ -195,7 +194,7 @@ export namespace AdministratorCommissioning { * This command may be used by a current Administrator to instruct a Node to go into commissioning mode, if * the node supports the Basic Commissioning Method. The Basic Commissioning Method specifies a window of * time during which an already commissioned Node accepts PASE sessions. The current Administrator shall - * specify a timeout value for the duration of OBCW. + * specify a timeout value for the duration of the OpenBasicCommissioningWindow command. * * If a commissioning window is already currently open, this command shall fail with a cluster specific * status code of Busy. @@ -241,13 +240,16 @@ export namespace AdministratorCommissioning { attributes: { /** - * Indicates whether a new Commissioning window has been opened by an Administrator, using either the OCW - * command or the OBCW command. + * Indicates whether a new Commissioning window has been opened by an Administrator, using either the + * OpenCommissioningWindow command or the OpenBasicCommissioningWindow command. * * This attribute shall revert to WindowNotOpen upon expiry of a commissioning window. * - * Note that an initial commissioning window is not opened using either the OCW command or the OBCW - * command, and therefore this attribute shall be set to WindowNotOpen on initial commissioning. + * NOTE + * + * An initial commissioning window is not opened using either the OpenCommissioningWindow command or the + * OpenBasicCommissioningWindow command, and therefore this attribute shall be set to WindowNotOpen on + * initial commissioning. * * @see {@link MatterSpecification.v13.Core} § 11.19.7.1 */ @@ -285,13 +287,15 @@ export namespace AdministratorCommissioning { /** * This command is used by a current Administrator to instruct a Node to go into commissioning mode. The * Enhanced Commissioning Method specifies a window of time during which an already commissioned Node - * accepts PASE sessions. The current Administrator MUST specify a timeout value for the duration of OCW. + * accepts PASE sessions. The current Administrator MUST specify a timeout value for the duration of the + * OpenCommissioningWindow command. + * + * When the OpenCommissioningWindow command expires or commissioning completes, the Node shall remove the + * Passcode by deleting the PAKE passcode verifier as well as stop publishing the DNS-SD record + * corresponding to this command as described in Section 4.3.1, “Commissionable * - * When OCW expires or commissioning completes, the Node shall remove the Passcode by deleting the PAKE - * passcode verifier as well as stop publishing the DNS-SD record corresponding to this command as - * described in Section 4.3.1, “Commissionable Node Discovery”. The commissioning into a new Fabric - * completes when the Node successfully receives a CommissioningComplete command, see Section 5.5, - * “Commissioning Flows”. + * Node Discovery”. The commissioning into a new Fabric completes when the Node successfully receives a + * CommissioningComplete command, see Section 5.5, “Commissioning Flows”. * * The parameters for OpenCommissioningWindow command are as follows: * @@ -324,18 +328,19 @@ export namespace AdministratorCommissioning { ), /** - * This command is used by a current Administrator to instruct a Node to revoke any active Open - * Commissioning Window or Open Basic Commissioning Window command. This is an idempotent command and the + * This command is used by a current Administrator to instruct a Node to revoke any active + * OpenCommissioningWindow or OpenBasicCommissioningWindow command. This is an idempotent command and the * Node shall (for ECM) delete the temporary PAKEPasscodeVerifier and associated data, and stop publishing - * the DNS-SD record associated with the Open Commissioning Window or Open Basic Commissioning Window - * command, see Section 4.3.1, “Commissionable Node Discovery”. + * the DNS-SD record associated with the OpenCommissioningWindow or OpenBasicCommissioningWindow command, + * see Section 4.3.1, “Commissionable Node Discovery”. * * If no commissioning window was open at time of receipt, this command shall fail with a cluster specific * status code of WindowNotOpen. * * If the commissioning window was open and the fail-safe was armed when this command is received, the - * device shall immediately expire the fail-safe and perform the cleanup steps outlined in Section - * 11.10.6.2.2, “Behavior on expiry of Fail-Safe timer”. + * device shall immediately expire the fail-safe and perform the cleanup steps outlined + * + * in Section 11.10.7.2.2, “Behavior on expiry of Fail-Safe timer”. * * @see {@link MatterSpecification.v13.Core} § 11.19.8.3 */ @@ -371,6 +376,20 @@ export namespace AdministratorCommissioning { * For the management of Operational Credentials and Trusted Root Certificates, the Node Operational Credentials * cluster is used. * + * If the Administrator Commissioning Cluster server instance is present on an endpoint with the Root Node device + * type in the Descriptor cluster DeviceTypeList, then: + * + * • The Commissioning Window shall be opened or closed on the node that the Root Node endpoint is on. + * + * • The attributes shall indicate the state of the node that the Root Node endpoint is on. + * + * If the Administrator Commissioning Cluster server instance is present on an endpoint with the Bridged Node + * device type in the Descriptor cluster DeviceTypeList, then: + * + * • The Commissioning Window shall be opened or closed on the node represented by the Bridged Node. + * + * • The attributes shall indicate the state of the node that is represented by the Bridged Node. + * * AdministratorCommissioningCluster supports optional features that you can enable with the * AdministratorCommissioningCluster.with() factory method. * diff --git a/packages/types/src/clusters/air-quality.ts b/packages/types/src/clusters/air-quality.ts index 629d0029ee..2cf541d76f 100644 --- a/packages/types/src/clusters/air-quality.ts +++ b/packages/types/src/clusters/air-quality.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/alarm-base.ts b/packages/types/src/clusters/alarm-base.ts index 673272d158..5929de5145 100644 --- a/packages/types/src/clusters/alarm-base.ts +++ b/packages/types/src/clusters/alarm-base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -84,10 +84,9 @@ export namespace AlarmBase { * alarm shall respond with a status code of FAILURE; otherwise the server shall respond with a status code of * SUCCESS. * - * On a SUCCESS case, the server shall also change the value of the Mask attribute to the value of the - * - * Mask field from this command. After that the server shall also update the value of its State attribute to - * reflect the status of the new alarm set as indicated by the new value of the Mask attribute. + * On a SUCCESS case, the server shall also change the value of the Mask attribute to the value of the Mask + * field from this command. After that the server shall also update the value of its State attribute to reflect + * the status of the new alarm set as indicated by the new value of the Mask attribute. * * @see {@link MatterSpecification.v13.Cluster} § 1.15.7.2.1 */ diff --git a/packages/types/src/clusters/application-basic.ts b/packages/types/src/clusters/application-basic.ts index b1b87459e0..9fc29ec47c 100644 --- a/packages/types/src/clusters/application-basic.ts +++ b/packages/types/src/clusters/application-basic.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/application-launcher.ts b/packages/types/src/clusters/application-launcher.ts index 5477bb1524..55ec0ebe96 100644 --- a/packages/types/src/clusters/application-launcher.ts +++ b/packages/types/src/clusters/application-launcher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -131,14 +131,29 @@ export namespace ApplicationLauncher { Success = 0, /** - * Requested app is not available. + * Requested app is not available */ AppNotAvailable = 1, /** - * Video platform unable to honor command. + * Video platform unable to honor command */ - SystemBusy = 2 + SystemBusy = 2, + + /** + * User approval for app download is pending + */ + PendingUserApproval = 3, + + /** + * Downloading the requested app + */ + Downloading = 4, + + /** + * Installing the requested app + */ + Installing = 5 } /** @@ -235,7 +250,7 @@ export namespace ApplicationLauncher { export const Base = MutableCluster.Component({ id: 0x50c, name: "ApplicationLauncher", - revision: 1, + revision: 2, features: { /** @@ -308,10 +323,10 @@ export namespace ApplicationLauncher { * The endpoint may decide to stop the application based on manufacturer specific behavior or resource * constraints if any. The Status attribute shall be updated to ActiveHidden or Stopped, depending on the * action taken, on the Application Basic cluster of the Endpoint corresponding to the application on which - * the action was taken. The Status attribute shall be updated on any other + * the action was taken. The Status attribute shall be updated on any other application whose Status may + * have changed as a result of this command. * - * application whose Status may have changed as a result of this command. This command returns a Launcher - * Response. + * This command returns a Launcher Response. * * @see {@link MatterSpecification.v13.Cluster} § 6.4.7.3 */ diff --git a/packages/types/src/clusters/audio-output.ts b/packages/types/src/clusters/audio-output.ts index 672438c77c..20a2d7a0bf 100644 --- a/packages/types/src/clusters/audio-output.ts +++ b/packages/types/src/clusters/audio-output.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/ballast-configuration.ts b/packages/types/src/clusters/ballast-configuration.ts index 8267bad84a..8749537208 100644 --- a/packages/types/src/clusters/ballast-configuration.ts +++ b/packages/types/src/clusters/ballast-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -110,15 +110,15 @@ export namespace BallastConfiguration { minLevel: WritableAttribute(0x10, TlvUInt8, { writeAcl: AccessLevel.Manage }), /** - * This attribute shall specify the light output of the ballast according to the dimming light curve + * This attribute shall specify the light output of the ballast according to the dimming light curve (see + * Dimming Curve) when the Level Control Cluster’s CurrentLevel attribute equals to 254 (and the On/Off + * Cluster’s OnOff attribute equals to TRUE). * - * (see Dimming Curve) when the Level Control Cluster’s CurrentLevel attribute equals to 254 (and the - * On/Off Cluster’s OnOff attribute equals to TRUE). + * The value of this attribute shall be both less than or equal to PhysicalMaxLevel and greater than * - * The value of this attribute shall be both less than or equal to PhysicalMaxLevel and greater than or - * equal to MinLevel. If an attempt is made to set this attribute to a level where these conditions are not - * met, a response shall be returned with status code set to CONSTRAINT_ERROR, and the level shall NOT be - * set. + * or equal to MinLevel. If an attempt is made to set this attribute to a level where these conditions are + * not met, a response shall be returned with status code set to CONSTRAINT_ERROR, and the level shall NOT + * be set. * * @see {@link MatterSpecification.v13.Cluster} § 3.3.6.5 */ diff --git a/packages/types/src/clusters/basic-information.ts b/packages/types/src/clusters/basic-information.ts index a83745b1aa..a54645483e 100644 --- a/packages/types/src/clusters/basic-information.ts +++ b/packages/types/src/clusters/basic-information.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -315,7 +315,7 @@ export namespace BasicInformation { export const ClusterInstance = MutableCluster({ id: 0x28, name: "BasicInformation", - revision: 3, + revision: 4, attributes: { /** @@ -453,10 +453,10 @@ export namespace BasicInformation { partNumber: OptionalFixedAttribute(0xc, TlvString.bound({ maxLength: 32 })), /** - * This attribute shall specify a link to a product specific web page. The syntax of the ProductURL - * attribute shall follow the syntax as specified in RFC 3986 [https://tools.ietf.org/html/rfc3986]. The - * specified URL SHOULD resolve to a maintained web page available for the lifetime of the product. The - * maximum length of the ProductUrl attribute is 256 ASCII characters. + * This attribute shall specify a link to a product specific web page. The specified URL SHOULD resolve to + * a maintained web page available for the lifetime of the product. The syntax of this attribute shall + * follow the syntax as specified in RFC 1738 and shall use the https scheme. The maximum length of this + * attribute is 256 ASCII characters. * * @see {@link MatterSpecification.v13.Core} § 11.1.5.14 */ @@ -505,24 +505,34 @@ export namespace BasicInformation { reachable: OptionalAttribute(0x11, TlvBoolean, { default: true }), /** - * This attribute (when used) shall indicate a unique identifier for the device, which is constructed in a - * manufacturer specific manner. + * Indicates a unique identifier for the device, which is constructed in a manufacturer specific manner. * * It may be constructed using a permanent device identifier (such as device MAC address) as basis. In * order to prevent tracking, * * • it SHOULD NOT be identical to (or easily derived from) such permanent device identifier * - * • it SHOULD be updated when the device is factory reset + * • it shall be updated when the device is factory reset * - * • it shall not be identical to the SerialNumber attribute + * • it shall NOT be identical to the SerialNumber attribute * - * • it shall not be printed on the product or delivered with the product The value does not need to be - * human readable. + * • it shall NOT be printed on the product or delivered with the product + * + * The value does not need to be human readable, since it is intended for machine to machine (M2M) + * communication. + * + * NOTE + * + * NOTE + * + * The conformance of the UniqueID attribute was optional in cluster revisions prior to revision 4. + * + * This UniqueID attribute shall NOT be the same as the Persistent Unique ID which is used in the Rotating + * Device Identifier mechanism. * * @see {@link MatterSpecification.v13.Core} § 11.1.5.19 */ - uniqueId: OptionalFixedAttribute(0x12, TlvString.bound({ maxLength: 32 })), + uniqueId: FixedAttribute(0x12, TlvString.bound({ maxLength: 32 })), /** * This attribute shall provide the minimum guaranteed value for some system-wide resource capabilities @@ -535,8 +545,9 @@ export namespace BasicInformation { * provided in this attribute. * * Note that since the fixed values within this attribute may change over time, both increasing and - * decreasing, as software versions change for a given Node, clients SHOULD take care not to assume forever - * unchanging values and SHOULD NOT cache this value permanently at Commissioning time. + * decreasing, as software versions change for a given Node, clients SHOULD take care not to assume + * + * forever unchanging values and SHOULD NOT cache this value permanently at Commissioning time. * * @see {@link MatterSpecification.v13.Core} § 11.1.5.20 */ @@ -595,9 +606,8 @@ export namespace BasicInformation { * Indicates the maximum number of elements in a single InvokeRequests list (see Section 8.8.2, “Invoke * Request Action”) that the Node is able to process. Note that since this attribute may change over time, * both increasing and decreasing, as software versions change for a given Node, clients SHOULD take care - * not to assume forever unchanging values and SHOULD NOT - * - * cache this value permanently at Commissioning time. + * not to assume forever unchanging values and SHOULD NOT cache this value permanently at Commissioning + * time. * * If the MaxPathsPerInvoke attribute is absent or zero, such as in Basic Information cluster revisions * prior to Revision 3, clients shall assume a value of 1. @@ -634,10 +644,8 @@ export namespace BasicInformation { * generated, it SHOULD be assumed that the fabric recorded in the event is no longer usable, and * subsequent interactions targeting that fabric will most likely fail. * - * Upon receipt of Leave Event on a subscription, the receiving Node may update other nodes in the - * - * fabric by removing related bindings, access control list entries and other data referencing the leaving - * Node. + * Upon receipt of Leave Event on a subscription, the receiving Node may update other nodes in the fabric + * by removing related bindings, access control list entries and other data referencing the leaving Node. * * @see {@link MatterSpecification.v13.Core} § 11.1.6.3 */ diff --git a/packages/types/src/clusters/binding.ts b/packages/types/src/clusters/binding.ts index 3ea3e9fad2..0dd5238279 100644 --- a/packages/types/src/clusters/binding.ts +++ b/packages/types/src/clusters/binding.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/boolean-state-configuration.ts b/packages/types/src/clusters/boolean-state-configuration.ts index 506f05f325..ff4c20bc1f 100644 --- a/packages/types/src/clusters/boolean-state-configuration.ts +++ b/packages/types/src/clusters/boolean-state-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/boolean-state.ts b/packages/types/src/clusters/boolean-state.ts index f2a0718071..e301066c21 100644 --- a/packages/types/src/clusters/boolean-state.ts +++ b/packages/types/src/clusters/boolean-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/bridged-device-basic-information.ts b/packages/types/src/clusters/bridged-device-basic-information.ts index fda78f6f32..9fc96beb97 100644 --- a/packages/types/src/clusters/bridged-device-basic-information.ts +++ b/packages/types/src/clusters/bridged-device-basic-information.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,30 +8,120 @@ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; import { + Command, + TlvNoResponse, + Event, + EventPriority, OptionalFixedAttribute, OptionalWritableAttribute, Attribute, - OptionalEvent, - EventPriority, - Event + FixedAttribute, + OptionalEvent } from "../cluster/Cluster.js"; +import { TlvField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvUInt32, TlvUInt16 } from "../tlv/TlvNumber.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { BitFlag } from "../schema/BitmapSchema.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvVendorId } from "../datatype/VendorId.js"; import { AccessLevel } from "#model"; -import { TlvUInt16, TlvUInt32 } from "../tlv/TlvNumber.js"; import { TlvBoolean } from "../tlv/TlvBoolean.js"; import { BasicInformation } from "./basic-information.js"; -import { TlvField, TlvObject } from "../tlv/TlvObject.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; export namespace BridgedDeviceBasicInformation { + /** + * These are optional features supported by BridgedDeviceBasicInformationCluster. + * + * @see {@link MatterSpecification.v13.Core} § 9.13.4 + */ + export enum Feature { + /** + * BridgedIcdSupport (BIS) + * + * Support bridged ICDs. + */ + BridgedIcdSupport = "BridgedIcdSupport" + } + + /** + * Input to the BridgedDeviceBasicInformation keepActive command + * + * @see {@link MatterSpecification.v13.Core} § 9.13.6.1 + */ + export const TlvKeepActiveRequest = TlvObject({ + /** + * This field shall indicate the duration, in milliseconds, that the device is requested to remain active, once + * the device becomes active again. + * + * The value of this field may be longer than the value supported by the bridged device and would, typically, + * be used by the client to request the server of the bridged device to stay active and responsive for this + * period to allow a sequence of message exchanges during that period. + * + * The client may slightly overestimate the duration it wants the bridged device to be active for, in order to + * account for network delays. + * + * @see {@link MatterSpecification.v13.Core} § 9.13.6.1.1 + */ + stayActiveDuration: TlvField(0, TlvUInt32), + + /** + * This field shall indicate the period, in milliseconds, that the server will wait before the "pending active" + * state expires. See the KeepActive Command description for details. + * + * NOTE + * + * TimeoutMs is a timeout for the request, NOT the time the device will be awake for. The server will wait for + * up to TimeoutMs for the device. If after TimeoutMs the ICD + * + * device does NOT check-in, the server will not perform any actions. + * + * @see {@link MatterSpecification.v13.Core} § 9.13.6.1.2 + */ + timeoutMs: TlvField(1, TlvUInt32.bound({ min: 30000, max: 3600000 })) + }); + + /** + * Input to the BridgedDeviceBasicInformation keepActive command + * + * @see {@link MatterSpecification.v13.Core} § 9.13.6.1 + */ + export interface KeepActiveRequest extends TypeFromSchema {} + + /** + * Body of the BridgedDeviceBasicInformation activeChanged event + * + * @see {@link MatterSpecification.v13.Core} § 9.13.7.3 + */ + export const TlvActiveChangedEvent = TlvObject({ + /** + * This field shall indicate the minimum duration, in milliseconds, that the bridged device will remain active + * after receiving the initial request from the KeepActive processing steps. + * + * If the bridged device is a Matter Intermittently Connected Device, PromisedActiveDuration shall be set to + * the PromisedActiveDuration value returned in the StayActiveResponse command. + * + * If the bridged device is not a Matter Intermittently Connected Device, the implementation of this is + * best-effort since it may interact with non-native protocol. + * + * @see {@link MatterSpecification.v13.Core} § 9.13.7.3.1 + */ + promisedActiveDuration: TlvField(0, TlvUInt32) + }); + + /** + * Body of the BridgedDeviceBasicInformation activeChanged event + * + * @see {@link MatterSpecification.v13.Core} § 9.13.7.3 + */ + export interface ActiveChangedEvent extends TypeFromSchema {} + /** * Body of the BridgedDeviceBasicInformation startUp event * - * @see {@link MatterSpecification.v13.Core} § 9.13.5 + * @see {@link MatterSpecification.v13.Core} § 9.13.7 */ export const TlvStartUpEvent = TlvObject({ /** @@ -45,14 +135,14 @@ export namespace BridgedDeviceBasicInformation { /** * Body of the BridgedDeviceBasicInformation startUp event * - * @see {@link MatterSpecification.v13.Core} § 9.13.5 + * @see {@link MatterSpecification.v13.Core} § 9.13.7 */ export interface StartUpEvent extends TypeFromSchema {} /** * Body of the BridgedDeviceBasicInformation reachableChanged event * - * @see {@link MatterSpecification.v13.Core} § 9.13.5.2 + * @see {@link MatterSpecification.v13.Core} § 9.13.7.2 */ export const TlvReachableChangedEvent = TlvObject({ /** @@ -66,36 +156,101 @@ export namespace BridgedDeviceBasicInformation { /** * Body of the BridgedDeviceBasicInformation reachableChanged event * - * @see {@link MatterSpecification.v13.Core} § 9.13.5.2 + * @see {@link MatterSpecification.v13.Core} § 9.13.7.2 */ export interface ReachableChangedEvent extends TypeFromSchema {} /** - * @see {@link Cluster} + * A BridgedDeviceBasicInformationCluster supports these elements if it supports feature BridgedIcdSupport. + */ + export const BridgedIcdSupportComponent = MutableCluster.Component({ + commands: { + /** + * Upon receipt, the server shall attempt to keep the bridged device active for the duration specified by + * the command, when the device is next active. + * + * The implementation of this is best-effort since it may interact with non-native protocols. However, + * several specific protocol requirements are: + * + * • If the bridged device is a Matter Intermittently Connected Device, then the server shall send a + * StayActiveRequest command with the StayActiveDuration field set to value of the StayActiveDuration + * field in the received command to the bridged device when the bridged device next sends a checks-in + * message or subscription report. See Intermittently Connected Devices Behavior for details on ICD + * state management. + * + * When the bridge detects that the bridged device goes into an active state, an ActiveChanged event shall + * be generated. + * + * In order to avoid unnecessary power consumption in the bridged device: + * + * • The server shall enter a "pending active" state for the associated device when the KeepActive + * command is received. The server "pending active" state shall expire after the amount of time defined + * by the TimeoutMs field, in milliseconds, if no subsequent KeepActive command is received. When a + * KeepActive command is received, the "pending active" state is set, the StayActiveDuration is updated + * to the greater of the new value and the previously stored value, and the TimeoutMs is updated to the + * greater of the new value and the remaining time until the prior "pending active" state expires. + * + * • The server shall only keep the bridged device active once for a request. (The server shall only + * consider the operation performed if an associated ActiveChanged event was generated.) + * + * @see {@link MatterSpecification.v13.Core} § 9.13.6.1 + */ + keepActive: Command(0x80, TlvKeepActiveRequest, 0x80, TlvNoResponse) + }, + + events: { + /** + * This event (when supported) shall be generated the next time a bridged device becomes active after a + * KeepActive command is received. + * + * See KeepActive for more details. + * + * @see {@link MatterSpecification.v13.Core} § 9.13.7.3 + */ + activeChanged: Event(0x80, EventPriority.Info, TlvActiveChangedEvent) + } + }); + + /** + * These elements and properties are present in all BridgedDeviceBasicInformation clusters. */ - export const ClusterInstance = MutableCluster({ + export const Base = MutableCluster.Component({ id: 0x39, name: "BridgedDeviceBasicInformation", - revision: 3, + revision: 4, + + features: { + /** + * BridgedIcdSupport + * + * Support bridged ICDs. + */ + bridgedIcdSupport: BitFlag(20) + }, attributes: { /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ vendorName: OptionalFixedAttribute(0x1, TlvString.bound({ maxLength: 32 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ vendorId: OptionalFixedAttribute(0x2, TlvVendorId), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ productName: OptionalFixedAttribute(0x3, TlvString.bound({ maxLength: 32 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 + */ + productId: OptionalFixedAttribute(0x4, TlvUInt16), + + /** + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ nodeLabel: OptionalWritableAttribute( 0x5, @@ -104,74 +259,90 @@ export namespace BridgedDeviceBasicInformation { ), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ hardwareVersion: OptionalFixedAttribute(0x7, TlvUInt16), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ hardwareVersionString: OptionalFixedAttribute(0x8, TlvString.bound({ minLength: 1, maxLength: 64 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ softwareVersion: OptionalFixedAttribute(0x9, TlvUInt32), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ softwareVersionString: OptionalFixedAttribute(0xa, TlvString.bound({ minLength: 1, maxLength: 64 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ manufacturingDate: OptionalFixedAttribute(0xb, TlvString.bound({ minLength: 8, maxLength: 16 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ partNumber: OptionalFixedAttribute(0xc, TlvString.bound({ maxLength: 32 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ productUrl: OptionalFixedAttribute(0xd, TlvString.bound({ maxLength: 256 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ productLabel: OptionalFixedAttribute(0xe, TlvString.bound({ maxLength: 64 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ serialNumber: OptionalFixedAttribute(0xf, TlvString.bound({ maxLength: 32 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * This attribute shall be used to indicate whether the bridged device is reachable by the bridge, so a + * Matter Node which wants to communicate with a bridged device can get an indication that this might fail + * (when the attribute is False). Determination of reachability might not be perfect (e.g. depending on + * technology employed), so the Matter Node SHOULD be aware of the risk of false positives and negatives on + * reachability determination. For example, a bridged device may be marked as unreachable while it could + * actually be reached, and vice-versa. Also, detection (and indication) that a bridged device is not + * longer reachable may be delayed due to the technique employed (e.g. detecting that a number of expected + * messages from the bridged device did not arrive). Also see event ReachableChanged below. + * + * @see {@link MatterSpecification.v13.Core} § 9.13.5.1 */ reachable: Attribute(0x11, TlvBoolean), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * This attribute shall, for a Bridged Device, be updated when the Bridge is factory reset. If the bridged + * device does not provide some unique id (e.g. in the case of bridging from non-Matter devices, or in case + * of bridging Matter devices from an earlier revision which were not required to provide a UniqueID + * attribute), the bridge shall generate a unique id on behalf of the bridged device. + * + * NOTE The UniqueID attribute was optional in cluster revisions prior to revision 4. + * + * @see {@link MatterSpecification.v13.Core} § 9.13.5.2 */ - uniqueId: OptionalFixedAttribute(0x12, TlvString.bound({ maxLength: 32 })), + uniqueId: FixedAttribute(0x12, TlvString.bound({ maxLength: 32 })), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.4 + * @see {@link MatterSpecification.v13.Core} § 9.13.5 */ productAppearance: OptionalFixedAttribute(0x14, BasicInformation.TlvProductAppearance) }, events: { /** - * @see {@link MatterSpecification.v13.Core} § 9.13.5 + * @see {@link MatterSpecification.v13.Core} § 9.13.7 */ startUp: OptionalEvent(0x0, EventPriority.Critical, TlvStartUpEvent), /** - * @see {@link MatterSpecification.v13.Core} § 9.13.5 + * @see {@link MatterSpecification.v13.Core} § 9.13.7 */ shutDown: OptionalEvent(0x1, EventPriority.Critical, TlvNoArguments), @@ -185,28 +356,41 @@ export namespace BridgedDeviceBasicInformation { * context of Bridged Device Basic Information cluster, has no usable fields, but the original Basic * Information cluster’s field definition is kept for completeness. * - * @see {@link MatterSpecification.v13.Core} § 9.13.5.1 + * @see {@link MatterSpecification.v13.Core} § 9.13.7.1 */ leave: OptionalEvent(0x2, EventPriority.Critical, TlvNoArguments), /** * This event shall be generated when there is a change in the Reachable attribute. Its purpose is to - * provide an indication towards interested parties that the reachability of a bridged device (over the - * non-Matter network) has changed, so they may take appropriate action. + * provide an indication towards interested parties that the reachability of a bridged device has changed + * over its native connectivity technology, so they may take appropriate action. * * After (re)start of a bridge this event may be generated. * - * @see {@link MatterSpecification.v13.Core} § 9.13.5.2 + * @see {@link MatterSpecification.v13.Core} § 9.13.7.2 */ reachableChanged: Event(0x3, EventPriority.Critical, TlvReachableChangedEvent) - } + }, + + /** + * This metadata controls which BridgedDeviceBasicInformationCluster elements matter.js activates for specific + * feature combinations. + */ + extensions: MutableCluster.Extensions( + { flags: { bridgedIcdSupport: true }, component: BridgedIcdSupportComponent } + ) }); /** - * This Cluster serves two purposes towards a Node communicating with a Bridge: + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster(Base); + + /** + * This cluster is a derived cluster of the Basic Information cluster and serves two purposes towards a Node + * communicating with a Bridge: * - * • Indicate that the functionality on the Endpoint where it is placed (and its Parts) is bridged from a - * non-Matter technology, and + * • Indicate that the functionality on the Endpoint where it is placed (and its Parts) is bridged, and * * • Provide a centralized collection of attributes that the Node may collect to aid in conveying information * regarding the Bridged Device to a user, such as the vendor name, the model name, or user-assigned name. @@ -226,12 +410,51 @@ export namespace BridgedDeviceBasicInformation { * particular attribute is not available, the Bridge SHOULD NOT include the attribute in the cluster for this * Bridged Device. See below for Conformance details. * + * BridgedDeviceBasicInformationCluster supports optional features that you can enable with the + * BridgedDeviceBasicInformationCluster.with() factory method. + * * @see {@link MatterSpecification.v13.Core} § 9.13 */ export interface Cluster extends Identity {} export const Cluster: Cluster = ClusterInstance; - export const Complete = Cluster; + const BIS = { bridgedIcdSupport: true }; + + /** + * @see {@link Complete} + */ + export const CompleteInstance = MutableCluster({ + id: Cluster.id, + name: Cluster.name, + revision: Cluster.revision, + features: Cluster.features, + attributes: Cluster.attributes, + + commands: { + keepActive: MutableCluster.AsConditional( + BridgedIcdSupportComponent.commands.keepActive, + { mandatoryIf: [BIS] } + ) + }, + + events: { + ...Cluster.events, + activeChanged: MutableCluster.AsConditional( + BridgedIcdSupportComponent.events.activeChanged, + { mandatoryIf: [BIS] } + ) + } + }); + + /** + * This cluster supports all BridgedDeviceBasicInformation features. It may support illegal feature combinations. + * + * If you use this cluster you must manually specify which features are active and ensure the set of active + * features is legal per the Matter specification. + */ + export interface Complete extends Identity {} + + export const Complete: Complete = CompleteInstance; } export type BridgedDeviceBasicInformationCluster = BridgedDeviceBasicInformation.Cluster; diff --git a/packages/types/src/clusters/carbon-dioxide-concentration-measurement.ts b/packages/types/src/clusters/carbon-dioxide-concentration-measurement.ts index c691e24a28..42bbc672f2 100644 --- a/packages/types/src/clusters/carbon-dioxide-concentration-measurement.ts +++ b/packages/types/src/clusters/carbon-dioxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/carbon-monoxide-concentration-measurement.ts b/packages/types/src/clusters/carbon-monoxide-concentration-measurement.ts index 39e47dd036..06fd72490c 100644 --- a/packages/types/src/clusters/carbon-monoxide-concentration-measurement.ts +++ b/packages/types/src/clusters/carbon-monoxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/channel.ts b/packages/types/src/clusters/channel.ts index 56fda312f7..0d2b01191a 100644 --- a/packages/types/src/clusters/channel.ts +++ b/packages/types/src/clusters/channel.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -127,9 +127,8 @@ export namespace Channel { callSign: TlvOptionalField(3, TlvString), /** - * This field shall indicate the local affiliate call sign, such as "KCTS". This field is optional, but - * - * SHOULD be provided when known. + * This field shall indicate the local affiliate call sign, such as "KCTS". This field is optional, but SHOULD + * be provided when known. * * @see {@link MatterSpecification.v13.Cluster} § 6.6.5.5.5 */ @@ -602,33 +601,35 @@ export namespace Channel { /** * This field shall be used for indicating the level of parental guidance recommended for of a particular - * program. This can be any rating system used in the country or region where the program is - * - * broadcast. For example, in the United States “TV-PG” may contain material that parents can find not suitable - * for younger children but can be accepted in general for older children. This field is optional but shall be - * provided if known. + * program. This can be any rating system used in the country or region where the program is broadcast. For + * example, in the United States “TV-PG” may contain material that parents can find not suitable for younger + * children but can be accepted in general for older children. This field is optional but shall be provided if + * known. * * @see {@link MatterSpecification.v13.Cluster} § 6.6.5.7.9 */ ratings: TlvOptionalField(8, TlvArray(TlvString, { maxLength: 255 })), /** - * This field shall represent a url of a thumbnail that clients can use to render an image for the program. + * This field shall represent a URL of a thumbnail that clients can use to render an image for the program. The + * syntax of this field shall follow the syntax as specified in RFC 1738 and shall use the https scheme. * * @see {@link MatterSpecification.v13.Cluster} § 6.6.5.7.10 */ thumbnailUrl: TlvOptionalField(9, TlvString.bound({ maxLength: 8192 })), /** - * This field shall represent a url of a poster that clients can use to render an image for the program on the - * detail view. + * This field shall represent a URL of a poster that clients can use to render an image for the program on the + * detail view. The syntax of this field shall follow the syntax as specified in RFC 1738 and shall use the + * https scheme. * * @see {@link MatterSpecification.v13.Cluster} § 6.6.5.7.11 */ posterArtUrl: TlvOptionalField(10, TlvString.bound({ maxLength: 8192 })), /** - * This field shall represent the DVB-I url associated to the program. + * This field shall represent the DVB-I URL associated to the program. The syntax of this field shall follow + * the syntax as specified in RFC 1738 and shall use the https scheme. * * @see {@link MatterSpecification.v13.Cluster} § 6.6.5.7.12 */ @@ -923,10 +924,8 @@ export namespace Channel { /** * This command retrieves the program guide. It accepts several filter parameters to return specific * schedule and program information from a content app. The command shall receive in response a - * ProgramGuideResponse. Standard error codes shall be used when arguments provided are not - * - * valid. For example, if StartTime is greater than EndTime, the status code INVALID_ACTION shall be - * returned. + * ProgramGuideResponse. Standard error codes shall be used when arguments provided are not valid. For + * example, if StartTime is greater than EndTime, the status code INVALID_ACTION shall be returned. * * @see {@link MatterSpecification.v13.Cluster} § 6.6.7.5 */ @@ -1051,7 +1050,11 @@ export namespace Channel { * * This cluster server would be supported on Video Player devices or endpoints that allow Channel control such as a * Content App. This cluster provides a list of available channels and provides commands for absolute and relative - * channel changes. + * channel changes. Some of these commands and/or their responses may be large (see Large Message Quality under + * Data Model section in [MatterCore]), but they do not have the Large quality indicator (L) because they can also + * be transferred over MRP (see Message Reliability Protocol in [MatterCore]) in pages that fit within the MRP MTU + * limit. However, an implementation may leverage a transport like TCP that allows large payloads, if available, to + * minimize the number of messages required to transfer the corresponding payload. * * The cluster server for Channel is implemented by an endpoint that controls the current Channel. * diff --git a/packages/types/src/clusters/color-control.ts b/packages/types/src/clusters/color-control.ts index 9f598fb02e..c1021ec61b 100644 --- a/packages/types/src/clusters/color-control.ts +++ b/packages/types/src/clusters/color-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -19,7 +19,7 @@ import { } from "../cluster/Cluster.js"; import { TlvUInt8, TlvEnum, TlvUInt16, TlvBitmap, TlvInt16 } from "../tlv/TlvNumber.js"; import { TlvField, TlvObject } from "../tlv/TlvObject.js"; -import { BitFlag, BitField } from "../schema/BitmapSchema.js"; +import { BitFlag } from "../schema/BitmapSchema.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; import { AccessLevel } from "#model"; @@ -31,7 +31,7 @@ export namespace ColorControl { /** * These are optional features supported by ColorControlCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.5 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.4 */ export enum Feature { /** @@ -71,49 +71,68 @@ export namespace ColorControl { } /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.4.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.7 */ export enum Direction { - ShortestDistance = 0, - LongestDistance = 1, + /** + * Shortest distance + */ + Shortest = 0, + + /** + * Longest distance + */ + Longest = 1, + + /** + * Up + */ Up = 2, + + /** + * Down + */ Down = 3 } /** - * The value of the ColorControl options attribute - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.11 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.2 */ - export const Options = { executeIfOff: BitFlag(0) }; + export const Options = { + /** + * Dependency on On/Off cluster + * + * This bit shall indicate if this cluster server instance has a dependency with the On/Off cluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.2.1 + */ + executeIfOff: BitFlag(0) + }; /** * Input to the ColorControl moveToHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.4 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.4 */ export const TlvMoveToHueRequest = TlvObject({ /** - * The Hue field specifies the hue to be moved to. + * This field shall indicate the hue to be moved to. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.4.1 */ hue: TlvField(0, TlvUInt8.bound({ max: 254 })), /** - * The Direction field shall be one of the non-reserved values in Values of the Direction Field. + * This field shall indicate the movement direction. * - * ### Table 17. Values of the Direction Field - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.4.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.4.2 */ direction: TlvField(1, TlvEnum()), /** - * The TransitionTime field specifies, in 1/10ths of a second, the time that shall be taken to move to the new - * hue. + * This field shall indicate, in 1/10ths of a second, the time that shall be taken to move to the new hue. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.4.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.4.3 */ transitionTime: TlvField(2, TlvUInt16.bound({ max: 65534 })), @@ -124,42 +143,48 @@ export namespace ColorControl { /** * Input to the ColorControl moveToHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.4 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.4 */ export interface MoveToHueRequest extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.5.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.8 */ export enum MoveMode { + /** + * Stop the movement + */ Stop = 0, + + /** + * Move in an upwards direction + */ Up = 1, + + /** + * Move in a downwards direction + */ Down = 3 } /** * Input to the ColorControl moveHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.5 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.5 */ export const TlvMoveHueRequest = TlvObject({ /** - * The MoveMode field shall be one of the non-reserved values in Values of the MoveMode Field. If the MoveMode - * field is equal to 0 (Stop), the Rate field shall be ignored. - * - * ### Table 18. Values of the MoveMode Field + * This field shall indicate the mode of movement. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.5.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.5.1 */ moveMode: TlvField(0, TlvEnum()), /** - * The Rate field specifies the rate of movement in steps per second. A step is a change in the device’s hue of - * one unit. If the MoveMode field is set to 1 (up) or 3 (down) and the Rate field has a value of zero, the - * command has no effect and a response command shall be sent in response, with the status code set to - * INVALID_COMMAND. If the MoveMode field is set to 0 (stop) the Rate field shall be ignored. + * This field shall indicate the rate of movement in steps per second. A step is a change in the device’s hue + * of one unit. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.5.2 */ rate: TlvField(1, TlvUInt8), @@ -170,50 +195,57 @@ export namespace ColorControl { /** * Input to the ColorControl moveHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.5 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.5 */ export interface MoveHueRequest extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.6.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.9 */ export enum StepMode { + /** + * Step in an upwards direction + */ Up = 1, + + /** + * Step in a downwards direction + */ Down = 3 } /** * Input to the ColorControl stepHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.6 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.6 */ export const TlvStepHueRequest = TlvObject({ /** - * The StepMode field shall be one of the non-reserved values in Values of the StepMode Field. + * This field shall indicate the mode of the step to be performed. * - * ### Table 20. Values of the StepMode Field - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.6.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.6.1 */ stepMode: TlvField(0, TlvEnum()), /** - * The change to be added to (or subtracted from) the current value of the device’s hue. + * This field shall indicate the change to be added to (or subtracted from) the current value of the device’s + * hue. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.6.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.6.2 */ stepSize: TlvField(1, TlvUInt8), /** - * The TransitionTime field specifies, in 1/10ths of a second, the time that shall be taken to perform the - * step. A step is a change in the device’s hue of ‘Step size’ units. + * This field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the step. + * + * A step is a change in the device’s hue of Step size units. * * NOTE * * Here the TransitionTime data field is of data type uint8, where uint16 is more common for TransitionTime * data fields in other clusters / commands. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.6.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.6.3 */ transitionTime: TlvField(2, TlvUInt8), @@ -224,14 +256,14 @@ export namespace ColorControl { /** * Input to the ColorControl stepHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.6 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.6 */ export interface StepHueRequest extends TypeFromSchema {} /** * Input to the ColorControl moveToSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.7 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.7 */ export const TlvMoveToSaturationRequest = TlvObject({ saturation: TlvField(0, TlvUInt8.bound({ max: 254 })), @@ -243,33 +275,28 @@ export namespace ColorControl { /** * Input to the ColorControl moveToSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.7 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.7 */ export interface MoveToSaturationRequest extends TypeFromSchema {} /** * Input to the ColorControl moveSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.8 */ export const TlvMoveSaturationRequest = TlvObject({ /** - * The MoveMode field shall be one of the non-reserved values in Values of the MoveMode Field. If the MoveMode - * field is equal to 0 (Stop), the Rate field shall be ignored. + * This field shall indicate the mode of movement, as described in the MoveHue command. * - * ### Table 22. Values of the MoveMode Field - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.8.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.8.1 */ moveMode: TlvField(0, TlvEnum()), /** - * The Rate field specifies the rate of movement in steps per second. A step is a change in the device’s - * saturation of one unit. If the MoveMode field is set to 1 (up) or 3 (down) and the Rate field has a value of - * zero, the command has no effect and a response command shall be sent in response, with the status code set - * to INVALID_COMMAND. If the MoveMode field is set to 0 (stop) the Rate field shall be ignored. + * This field shall indicate the rate of movement in steps per second. A step is a change in the device’s + * saturation of one unit. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.8.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.8.2 */ rate: TlvField(1, TlvUInt8), @@ -280,42 +307,41 @@ export namespace ColorControl { /** * Input to the ColorControl moveSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.8 */ export interface MoveSaturationRequest extends TypeFromSchema {} /** * Input to the ColorControl stepSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.9 */ export const TlvStepSaturationRequest = TlvObject({ /** - * The StepMode field shall be one of the non-reserved values in Values of the StepMode Field. - * - * ### Table 24. Values of the StepMode Field + * This field shall indicate the mode of the step to be performed, as described in the StepHue command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.9.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.9.1 */ stepMode: TlvField(0, TlvEnum()), /** - * The change to be added to (or subtracted from) the current value of the device’s saturation. + * This field shall indicate the change to be added to (or subtracted from) the current value of the device’s + * saturation. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.9.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.9.2 */ stepSize: TlvField(1, TlvUInt8), /** - * The TransitionTime field specifies, in 1/10ths of a second, the time that shall be taken to perform the - * step. A step is a change in the device’s saturation of ‘Step size’ units. + * This field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the step. A step + * is a change in the device’s saturation of Step size units. * * NOTE * * Here the TransitionTime data field is of data type uint8, where uint16 is more common for TransitionTime * data fields in other clusters / commands. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.9.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.9.3 */ transitionTime: TlvField(2, TlvUInt8), @@ -326,14 +352,14 @@ export namespace ColorControl { /** * Input to the ColorControl stepSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.9 */ export interface StepSaturationRequest extends TypeFromSchema {} /** * Input to the ColorControl moveToHueAndSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.10 */ export const TlvMoveToHueAndSaturationRequest = TlvObject({ hue: TlvField(0, TlvUInt8.bound({ max: 254 })), @@ -346,14 +372,14 @@ export namespace ColorControl { /** * Input to the ColorControl moveToHueAndSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.10 */ export interface MoveToHueAndSaturationRequest extends TypeFromSchema {} /** * Input to the ColorControl moveToColor command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.11 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.11 */ export const TlvMoveToColorRequest = TlvObject({ colorX: TlvField(0, TlvUInt16.bound({ max: 65279 })), @@ -366,29 +392,29 @@ export namespace ColorControl { /** * Input to the ColorControl moveToColor command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.11 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.11 */ export interface MoveToColorRequest extends TypeFromSchema {} /** * Input to the ColorControl moveColor command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.12 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.12 */ export const TlvMoveColorRequest = TlvObject({ /** - * The RateX field specifies the rate of movement in steps per second. A step is a change in the device’s + * This field shall indicate the rate of movement in steps per second. A step is a change in the device’s * CurrentX attribute of one unit. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.12.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.12.1 */ rateX: TlvField(0, TlvInt16), /** - * The RateY field specifies the rate of movement in steps per second. A step is a change in the device’s + * This field shall indicate the rate of movement in steps per second. A step is a change in the device’s * CurrentY attribute of one unit. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.12.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.12.2 */ rateY: TlvField(1, TlvInt16), @@ -399,24 +425,23 @@ export namespace ColorControl { /** * Input to the ColorControl moveColor command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.12 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.12 */ export interface MoveColorRequest extends TypeFromSchema {} /** * Input to the ColorControl stepColor command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.13 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.13 */ export const TlvStepColorRequest = TlvObject({ stepX: TlvField(0, TlvInt16), stepY: TlvField(1, TlvInt16), /** - * The TransitionTime field specifies, in 1/10ths of a second, the time that shall be taken to perform the - * color change. + * The field shall indicate, in 1/10ths of a second, the time that shall be taken to perform the color change. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.13.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.13.2 */ transitionTime: TlvField(2, TlvUInt16.bound({ max: 65534 })), @@ -427,14 +452,14 @@ export namespace ColorControl { /** * Input to the ColorControl stepColor command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.13 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.13 */ export interface StepColorRequest extends TypeFromSchema {} /** * Input to the ColorControl moveToColorTemperature command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.14 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.14 */ export const TlvMoveToColorTemperatureRequest = TlvObject({ colorTemperatureMireds: TlvField(0, TlvUInt16.bound({ max: 65279 })), @@ -446,37 +471,34 @@ export namespace ColorControl { /** * Input to the ColorControl moveToColorTemperature command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.14 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.14 */ export interface MoveToColorTemperatureRequest extends TypeFromSchema {} /** * Input to the ColorControl moveColorTemperature command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.21 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.21 */ export const TlvMoveColorTemperatureRequest = TlvObject({ /** - * This field is identical to the MoveMode field of the MoveHue command of the Color Control cluster (see - * sub-clause MoveHue Command). If the MoveMode field is equal to 0 (Stop), the Rate field shall be ignored. + * This field shall indicate the mode of movement, as described in the MoveHue command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.21.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.21.1 */ moveMode: TlvField(0, TlvEnum()), /** - * The Rate field specifies the rate of movement in steps per second. A step is a change in the color - * temperature of a device by one unit. If the MoveMode field is set to 1 (up) or 3 (down) and the Rate field - * has a value of zero, the command has no effect and a response command shall be sent in response, with the - * status code set to INVALID_COMMAND. If the MoveMode field is set to 0 (stop) the Rate field shall be ignored. + * This field shall indicate the rate of movement in steps per second. A step is a change in the color + * temperature of a device by one unit. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.21.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.21.2 */ rate: TlvField(1, TlvUInt16), /** - * The ColorTemperatureMinimumMireds field specifies a lower bound on the ColorTemperatureMireds attribute (≡ - * an upper bound on the color temperature in kelvins) for the current move operation + * This field shall indicate a lower bound on the ColorTemperatureMireds attribute (≡ an upper bound on the + * color temperature in kelvins) for the current move operation * * ColorTempPhysicalMinMireds <= ColorTemperatureMinimumMireds field <= ColorTemperatureMireds * @@ -485,13 +507,13 @@ export namespace ColorControl { * ColorTemperatureMinimumMireds field is set to 0, ColorTempPhysicalMinMireds shall be used as the lower bound * for the ColorTemperatureMireds attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.21.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.21.3 */ colorTemperatureMinimumMireds: TlvField(2, TlvUInt16.bound({ max: 65279 })), /** - * The ColorTemperatureMaximumMireds field specifies an upper bound on the ColorTemperatureMireds attribute (≡ - * a lower bound on the color temperature in kelvins) for the current move operation + * This field shall indicate an upper bound on the ColorTemperatureMireds attribute (≡ a lower bound on the + * color temperature in kelvins) for the current move operation * * ColorTemperatureMireds <= ColorTemperatureMaximumMireds field <= ColorTempPhysicalMaxMireds * @@ -500,7 +522,7 @@ export namespace ColorControl { * ColorTemperatureMaximumMireds field is set to 0, ColorTempPhysicalMaxMireds shall be used as the upper bound * for the ColorTemperatureMireds attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.21.4 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.21.4 */ colorTemperatureMaximumMireds: TlvField(3, TlvUInt16.bound({ max: 65279 })), @@ -511,68 +533,67 @@ export namespace ColorControl { /** * Input to the ColorControl moveColorTemperature command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.21 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.21 */ export interface MoveColorTemperatureRequest extends TypeFromSchema {} /** * Input to the ColorControl stepColorTemperature command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22 */ export const TlvStepColorTemperatureRequest = TlvObject({ /** - * This field is identical to the StepMode field of the StepHue command of the Color Control cluster (see - * sub-clause StepHue Command). + * This field shall indicate the mode of the step to be performed, as described in the StepHue command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22.1 */ stepMode: TlvField(0, TlvEnum()), /** - * The StepSize field specifies the change to be added to (or subtracted from) the current value of the - * device’s color temperature. + * This field shall indicate the change to be added to (or subtracted from) the current value of the device’s + * color temperature. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22.2 */ stepSize: TlvField(1, TlvUInt16), /** - * The TransitionTime field specifies, in units of 1/10ths of a second, the time that shall be taken to perform - * the step. A step is a change to the device’s color temperature of a magnitude corresponding to the StepSize + * This field shall indicate, in units of 1/10ths of a second, the time that shall be taken to perform the + * step. A step is a change to the device’s color temperature of a magnitude corresponding to the StepSize * field. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22.3 */ transitionTime: TlvField(2, TlvUInt16.bound({ max: 65534 })), /** - * The ColorTemperatureMinimumMireds field specifies a lower bound on the ColorTemperatureMireds attribute (≡ - * an upper bound on the color temperature in kelvins) for the current step operation + * This field shall indicate a lower bound on the ColorTemperatureMireds attribute (≡ an upper bound on the + * color temperature in kelvins) for the current step operation * * ColorTempPhysicalMinMireds <= ColorTemperatureMinimumMireds field <= ColorTemperatureMireds * - * As such if the step operation takes the ColorTemperatureMireds attribute towards the value of the Color - * Temperature Minimum Mireds field it shall be clipped so that the above invariant is satisfied. If the + * As such if the step operation takes the ColorTemperatureMireds attribute towards the value of the + * ColorTemperatureMinimumMireds field it shall be clipped so that the above invariant is satisfied. If the * ColorTemperatureMinimumMireds field is set to 0, ColorTempPhysicalMinMireds shall be used as the lower bound * for the ColorTemperatureMireds attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22.4 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22.4 */ colorTemperatureMinimumMireds: TlvField(3, TlvUInt16.bound({ max: 65279 })), /** - * The ColorTemperatureMaximumMireds field specifies an upper bound on the ColorTemperatureMireds attribute (≡ - * a lower bound on the color temperature in kelvins) for the current step operation + * This field shall indicate an upper bound on the ColorTemperatureMireds attribute (≡ a lower bound on the + * color temperature in kelvins) for the current step operation * * ColorTemperatureMireds ≤ ColorTemperatureMaximumMireds field ≤ ColorTempPhysicalMaxMireds * * As such if the step operation takes the ColorTemperatureMireds attribute towards the value of the * ColorTemperatureMaximumMireds field it shall be clipped so that the above invariant is satisfied. If the - * ColorTemperatureMaximum Mireds field is set to 0, ColorTempPhysicalMaxMireds shall be used as the upper - * bound for the ColorTemperatureMireds attribute. + * ColorTemperatureMaximumMireds field is set to 0, ColorTempPhysicalMaxMireds shall be used as the upper bound + * for the ColorTemperatureMireds attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22.5 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22.5 */ colorTemperatureMaximumMireds: TlvField(4, TlvUInt16.bound({ max: 65279 })), @@ -583,36 +604,34 @@ export namespace ColorControl { /** * Input to the ColorControl stepColorTemperature command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22 */ export interface StepColorTemperatureRequest extends TypeFromSchema {} /** * Input to the ColorControl enhancedMoveToHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.15 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.15 */ export const TlvEnhancedMoveToHueRequest = TlvObject({ /** - * The EnhancedHue field specifies the target extended hue for the lamp. + * This field shall indicate the target extended hue for the light. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.15.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.15.1 */ enhancedHue: TlvField(0, TlvUInt16), /** - * This field is identical to the Direction field of the MoveToHue command of the Color Control cluster (see - * sub-clause Use of the OptionsMask and OptionsOverride fields). + * This field shall indicate the movement direction. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.15.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.15.2 */ direction: TlvField(1, TlvEnum()), /** - * This field is identical to the TransitionTime field of the MoveToHue command of the Color Control cluster - * (see sub-clause Use of the OptionsMask and OptionsOverride fields). + * This field shall indicate the transition time, as described in the MoveToHue command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.15.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.15.3 */ transitionTime: TlvField(2, TlvUInt16.bound({ max: 65534 })), @@ -623,31 +642,28 @@ export namespace ColorControl { /** * Input to the ColorControl enhancedMoveToHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.15 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.15 */ export interface EnhancedMoveToHueRequest extends TypeFromSchema {} /** * Input to the ColorControl enhancedMoveHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.16 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.16 */ export const TlvEnhancedMoveHueRequest = TlvObject({ /** - * This field is identical to the MoveMode field of the MoveHue command of the Color Control cluster (see - * sub-clause MoveHue Command). If the MoveMode field is equal to 0 (Stop), the Rate field shall be ignored. + * This field shall indicate the mode of movement, as described in the MoveHue command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.16.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.16.1 */ moveMode: TlvField(0, TlvEnum()), /** - * The Rate field specifies the rate of movement in steps per second. A step is a change in the extended hue of - * a device by one unit. If the MoveMode field is set to 1 (up) or 3 (down) and the Rate field has a value of - * zero, the command has no effect and a response command shall be sent in response, with the status code set - * to INVALID_COMMAND. If the MoveMode field is set to 0 (stop) the Rate field shall be ignored. + * This field shall indicate the rate of movement in steps per second. A step is a change in the extended hue + * of a device by one unit. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.16.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.16.2 */ rate: TlvField(1, TlvUInt16), @@ -658,42 +674,41 @@ export namespace ColorControl { /** * Input to the ColorControl enhancedMoveHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.16 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.16 */ export interface EnhancedMoveHueRequest extends TypeFromSchema {} /** * Input to the ColorControl enhancedStepHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.17 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.17 */ export const TlvEnhancedStepHueRequest = TlvObject({ /** - * This field is identical to the StepMode field of the StepHue command of the Color Control cluster (see - * sub-clause StepHue Command). + * This field shall indicate the mode of the step to be performed, as described in the StepHue command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.17.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.17.1 */ stepMode: TlvField(0, TlvEnum()), /** - * The StepSize field specifies the change to be added to (or subtracted from) the current value of the - * device’s enhanced hue. + * This field shall indicate the change to be added to (or subtracted from) the current value of the device’s + * enhanced hue. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.17.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.17.2 */ stepSize: TlvField(1, TlvUInt16), /** - * The TransitionTime field specifies, in units of 1/10ths of a second, the time that shall be taken to perform - * the step. A step is a change to the device’s enhanced hue of a magnitude corresponding to the StepSize field. + * The field shall indicate, in units of 1/10ths of a second, the time that shall be taken to perform the step. + * A step is a change to the device’s enhanced hue of a magnitude corresponding to the StepSize field. * * NOTE * * Here TransitionTime data field is of data type uint16, while the TransitionTime data field of the StepHue * command is of data type uint8. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.17.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.17.3 */ transitionTime: TlvField(2, TlvUInt16.bound({ max: 65534 })), @@ -704,36 +719,34 @@ export namespace ColorControl { /** * Input to the ColorControl enhancedStepHue command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.17 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.17 */ export interface EnhancedStepHueRequest extends TypeFromSchema {} /** * Input to the ColorControl enhancedMoveToHueAndSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.18 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.18 */ export const TlvEnhancedMoveToHueAndSaturationRequest = TlvObject({ /** - * The EnhancedHue field specifies the target extended hue for the lamp. + * This field shall indicate the target extended hue for the light. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.18.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.18.1 */ enhancedHue: TlvField(0, TlvUInt16), /** - * This field is identical to the Saturation field of the MoveToHueAndSaturation command of the Color Control - * cluster (see sub-clause MoveToHueAndSaturation Command). + * This field shall indicate the saturation, as described in the MoveToHueAndSaturation command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.18.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.18.2 */ saturation: TlvField(1, TlvUInt8.bound({ max: 254 })), /** - * This field is identical to the TransitionTime field of the MoveToHue command of the Color Control cluster - * (see sub-clause MoveToHueAndSaturation Command). + * This field shall indicate the transition time, as described in the MoveToHue command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.18.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.18.3 */ transitionTime: TlvField(2, TlvUInt16.bound({ max: 65534 })), @@ -744,7 +757,7 @@ export namespace ColorControl { /** * Input to the ColorControl enhancedMoveToHueAndSaturation command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.18 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.18 */ export interface EnhancedMoveToHueAndSaturationRequest extends TypeFromSchema {} @@ -759,111 +772,133 @@ export namespace ColorControl { } /** - * The value of the ColorControl colorLoopDirection attribute - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.15 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.11 */ export enum ColorLoopDirection { + /** + * Decrement the hue in the color loop. + */ Decrement = 0, + + /** + * Increment the hue in the color loop. + */ Increment = 1 } /** - * The value of ColorControl.updateFlags + * This data type is derived from map8 and is used in the ColorLoopSet command. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.3 */ export const UpdateFlags = { + /** + * Device adheres to the associated action field. + * + * This bit shall indicate whether the server adheres to the Action field in order to process the command. + * + * • 0 = Device shall ignore the Action field. + * + * • 1 = Device shall adhere to the Action field. + * + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.3.1 + */ updateAction: BitFlag(0), + + /** + * Device updates the associated direction attribute. + * + * This bit shall indicate whether the device updates the ColorLoopDirection attribute with the Direction field. + * + * • 0 = Device shall ignore the Direction field. + * + * • 1 = Device shall update the ColorLoopDirection attribute with the value of the Direction field. + * + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.3.2 + */ updateDirection: BitFlag(1), + + /** + * Device updates the associated time attribute. + * + * This bit shall indicate whether the device updates the ColorLoopTime attribute with the Time field. + * + * • 0 = Device shall ignore the Time field. + * + * • 1 = Device shall update the value of the ColorLoopTime attribute with the value of the Time field. + * + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.3.3 + */ updateTime: BitFlag(2), - updateStartHue: BitFlag(3), - reserved: BitField(4, 4) + + /** + * Device updates the associated start hue attribute. + * + * This bit shall indicate whether the device updates the ColorLoopStartEnhancedHue attribute with the value of + * the StartHue field. + * + * • 0 = Device shall ignore the StartHue field. + * + * • 1 = Device shall update the value of the ColorLoopStartEnhancedHue attribute with the value of the + * StartHue field. + * + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.3.4 + */ + updateStartHue: BitFlag(3) }; /** - * The value of ColorControl.action - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.10 */ - export enum Action { - DeActivateTheColorLoop = 0, - ActivateTheColorLoopFromTheValueInTheColorLoopStartEnhancedHueField = 1, - ActivateTheColorLoopFromTheValueOfTheEnhancedCurrentHueAttribute = 2 - } + export enum ColorLoopAction { + /** + * De-activate the color loop. + */ + Deactivate = 0, - /** - * The value of ColorControl.direction - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19.3 - */ - export enum ColorLoopSetDirection { - DecrementTheHueInTheColorLoop = 0, - IncrementTheHueInTheColorLoop = 1 + /** + * Activate the color loop from the value in the ColorLoopStartEnhancedHue field. + */ + ActivateFromColorLoopStartEnhancedHue = 1, + + /** + * Activate the color loop from the value of the EnhancedCurrentHue attribute. + */ + ActivateFromEnhancedCurrentHue = 2 } /** * Input to the ColorControl colorLoopSet command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.19 */ export const TlvColorLoopSetRequest = TlvObject({ /** - * The UpdateFlags field specifies which color loop attributes to update before the color loop is started. This - * field shall be formatted as illustrated in Format of the UpdateFlags Field of the ColorLoopSet Command. - * - * ### Table 28. Format of the UpdateFlags Field of the ColorLoopSet Command - * - * The UpdateAction sub-field is 1 bit in length and specifies whether the device shall adhere to the action - * field in order to process the command. If this sub-field is set to 1, the device shall adhere to the action - * field. If this sub-field is set to 0, the device shall ignore the Action field. - * - * The UpdateDirection sub-field is 1 bit in length and specifies whether the device shall update the - * ColorLoopDirection attribute with the Direction field. If this sub-field is set to 1, the device shall - * update the value of the ColorLoopDirection attribute with the value of the Direction field. If this - * sub-field is set to 0, the device shall ignore the Direction field. + * This field shall indicate which color loop attributes to update (from the values supplied in the other + * fields, see field descriptions below) before the color loop is started. * - * The UpdateTime sub-field is 1 bit in length and specifies whether the device shall update the ColorLoopTime - * attribute with the Time field. If this sub-field is set to 1, the device shall update the value of the - * ColorLoopTime attribute with the value of the Time field. If this sub-field is set to 0, the device shall - * ignore the Time field. - * - * The UpdateStartHue sub-field is 1 bit in length and specifies whether the device shall update the - * ColorLoopStartEnhancedHue attribute with the StartHue field. If this sub-field is set to 1, the device shall - * update the value of the ColorLoopStartEnhancedHue attribute with the value of the StartHue field. If this - * sub-field is set to 0, the device shall ignore the StartHue field. - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.19.1 */ updateFlags: TlvField(0, TlvBitmap(TlvUInt8, UpdateFlags)), /** - * The Action field specifies the action to take for the color loop if the UpdateAction sub-field of the - * UpdateFlags field is set to 1. This field shall be set to one of the non-reserved values listed in Values of - * the Action Field of the ColorLoopSet Command. - * - * ### Table 29. Values of the Action Field of the ColorLoopSet Command + * This field shall indicate the action to take for the color loop. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.19.2 */ - action: TlvField(1, TlvEnum()), + action: TlvField(1, TlvEnum()), /** - * The Direction field specifies the direction for the color loop if the Update Direction field of the - * UpdateFlags field is set to 1. This field shall be set to one of the non-reserved values listed in Values of - * the Direction Field of the ColorLoopSet Command. + * This field shall indicate the direction for the color loop. * - * ### Table 30. Values of the Direction Field of the ColorLoopSet Command - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.19.3 */ - direction: TlvField(2, TlvEnum()), + direction: TlvField(2, TlvEnum()), /** - * The Time field specifies the number of seconds over which to perform a full color loop if the UpdateTime - * sub-field of the UpdateFlags field is set to 1. + * This field shall indicate the number of seconds over which to perform a full color loop. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19.4 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.19.4 */ time: TlvField(3, TlvUInt16), @@ -875,14 +910,14 @@ export namespace ColorControl { /** * Input to the ColorControl colorLoopSet command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.19 */ export interface ColorLoopSetRequest extends TypeFromSchema {} /** * Input to the ColorControl stopMoveStep command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.20 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.20 */ export const TlvStopMoveStepRequest = TlvObject({ optionsMask: TlvField(0, TlvBitmap(TlvUInt8, Options)), @@ -892,43 +927,82 @@ export namespace ColorControl { /** * Input to the ColorControl stopMoveStep command * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.20 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.20 */ export interface StopMoveStepRequest extends TypeFromSchema {} /** - * The value of the ColorControl driftCompensation attribute - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.7 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.4 */ export enum DriftCompensation { + /** + * There is no compensation. + */ None = 0, - OtherUnknown = 1, + + /** + * The compensation is based on other or unknown mechanism. + */ + OtherOrUnknown = 1, + + /** + * The compensation is based on temperature monitoring. + */ TemperatureMonitoring = 2, + + /** + * The compensation is based on optical luminance monitoring and feedback. + */ OpticalLuminanceMonitoringAndFeedback = 3, + + /** + * The compensation is based on optical color monitoring and feedback. + */ OpticalColorMonitoringAndFeedback = 4 } /** - * The value of the ColorControl colorMode attribute - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.5 */ export enum ColorMode { + /** + * The current hue and saturation attributes determine the color. + */ CurrentHueAndCurrentSaturation = 0, + + /** + * The current X and Y attributes determine the color. + */ CurrentXAndCurrentY = 1, + + /** + * The color temperature attribute determines the color. + */ ColorTemperatureMireds = 2 } /** - * The value of the ColorControl enhancedColorMode attribute - * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.13 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.6.6 */ export enum EnhancedColorMode { + /** + * The current hue and saturation attributes determine the color. + */ CurrentHueAndCurrentSaturation = 0, + + /** + * The current X and Y attributes determine the color. + */ CurrentXAndCurrentY = 1, + + /** + * The color temperature attribute determines the color. + */ ColorTemperatureMireds = 2, + + /** + * The enhanced current hue and saturation attributes determine the color. + */ EnhancedCurrentHueAndCurrentSaturation = 3 } @@ -938,10 +1012,29 @@ export namespace ColorControl { * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.19 */ export const ColorCapabilities = { + /** + * Supports color specification via hue/saturation. + */ hueSaturation: BitFlag(0), + + /** + * Enhanced hue is supported. + */ enhancedHue: BitFlag(1), + + /** + * Color loop is supported. + */ colorLoop: BitFlag(2), + + /** + * Supports color specification via XY. + */ xy: BitFlag(3), + + /** + * Supports color specification via color temperature. + */ colorTemperature: BitFlag(4) }; @@ -954,24 +1047,38 @@ export namespace ColorControl { * The CurrentHue attribute contains the current hue value of the light. It is updated as fast as practical * during commands that change the hue. * - * The hue in degrees shall be related to the CurrentHue attribute by the relationship: Hue = CurrentHue x - * 360 / 254 (CurrentHue in the range 0 to 254 inclusive) + * The hue in degrees shall be related to the CurrentHue attribute by the relationship: * - * If this attribute is implemented then the CurrentSaturation and ColorMode attributes shall also be - * implemented. + * Hue = "CurrentHue" * 360 / 254 + * + * where CurrentHue is in the range from 0 to 254 inclusive. + * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once per second or + * + * • At the end of the movement/transition. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.2 */ currentHue: Attribute(0x0, TlvUInt8.bound({ max: 254 }), { persistent: true, default: 0 }), /** - * The CurrentSaturation attribute holds the current saturation value of the light. It is updated as fast - * as practical during commands that change the saturation. + * Indicates the current saturation value of the light. It is updated as fast as practical during commands + * that change the saturation. * - * The saturation shall be related to the CurrentSaturation attribute by the relationship: Saturation = - * CurrentSaturation/254 (CurrentSaturation in the range 0 to 254 inclusive) + * The saturation (on a scale from 0.0 to 1.0) shall be related to the CurrentSaturation attribute by the + * relationship: * - * If this attribute is implemented then the CurrentHue and ColorMode attributes shall also be implemented. + * Saturation = "CurrentSaturation" / 254 + * + * where CurrentSaturation is in the range from 0 to 254 inclusive. + * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once per second or + * + * • At the end of the movement/transition. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.3 */ @@ -984,37 +1091,37 @@ export namespace ColorControl { commands: { /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.4 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.4 */ moveToHue: Command(0x0, TlvMoveToHueRequest, 0x0, TlvNoResponse), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.5 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.5 */ moveHue: Command(0x1, TlvMoveHueRequest, 0x1, TlvNoResponse), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.6 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.6 */ stepHue: Command(0x2, TlvStepHueRequest, 0x2, TlvNoResponse), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.7 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.7 */ moveToSaturation: Command(0x3, TlvMoveToSaturationRequest, 0x3, TlvNoResponse), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.8 */ moveSaturation: Command(0x4, TlvMoveSaturationRequest, 0x4, TlvNoResponse), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.9 */ stepSaturation: Command(0x5, TlvStepSaturationRequest, 0x5, TlvNoResponse), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.10 */ moveToHueAndSaturation: Command(0x6, TlvMoveToHueAndSaturationRequest, 0x6, TlvNoResponse) } @@ -1026,11 +1133,20 @@ export namespace ColorControl { export const XyComponent = MutableCluster.Component({ attributes: { /** - * The CurrentX attribute contains the current value of the normalized chromaticity value x, as defined in - * the CIE xyY Color Space. It is updated as fast as practical during commands that change the color. + * Indicates the current value of the normalized chromaticity value x, as defined in the CIE xyY Color + * Space. It is updated as fast as practical during commands that change the color. + * + * The value of x shall be related to the CurrentX attribute by the relationship + * + * x = "CurrentX" / 65536 * - * The value of x shall be related to the CurrentX attribute by the relationship x = CurrentX / 65536 - * (CurrentX in the range 0 to 65279 inclusive) + * where CurrentX is in the range from 0 to 65279 inclusive. + * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once per second or + * + * • At the end of the movement/transition. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.5 */ @@ -1041,11 +1157,20 @@ export namespace ColorControl { ), /** - * The CurrentY attribute contains the current value of the normalized chromaticity value y, as defined in - * the CIE xyY Color Space. It is updated as fast as practical during commands that change the color. + * Indicates the current value of the normalized chromaticity value y, as defined in the CIE xyY Color + * Space. It is updated as fast as practical during commands that change the color. + * + * The value of y shall be related to the CurrentY attribute by the relationship + * + * y = "CurrentY" / 65536 + * + * where CurrentY is in the range from 0 to 65279 inclusive. * - * The value of y shall be related to the CurrentY attribute by the relationship y = CurrentY / 65536 - * (CurrentY in the range 0 to 65279 inclusive) + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once per second or + * + * • At the end of the movement/transition. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.6 */ @@ -1058,17 +1183,17 @@ export namespace ColorControl { commands: { /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.11 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.11 */ moveToColor: Command(0x7, TlvMoveToColorRequest, 0x7, TlvNoResponse), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.12 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.12 */ moveColor: Command(0x8, TlvMoveColorRequest, 0x8, TlvNoResponse), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.13 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.13 */ stepColor: Command(0x9, TlvStepColorRequest, 0x9, TlvNoResponse) } @@ -1080,16 +1205,23 @@ export namespace ColorControl { export const ColorTemperatureComponent = MutableCluster.Component({ attributes: { /** - * The ColorTemperatureMireds attribute contains a scaled inverse of the current value of the color - * temperature. The unit of ColorTemperatureMireds is the mired (micro reciprocal degree), a.k.a. mirek - * (micro reciprocal kelvin). It is updated as fast as practical during commands that change the color. + * Indicates a scaled inverse of the current value of the color temperature. The unit of + * ColorTemperatureMireds is the mired (micro reciprocal degree), a.k.a. mirek (micro reciprocal kelvin). + * It is updated as fast as practical during commands that change the color. + * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once per second or + * + * • At the end of the movement/transition. + * + * The color temperature value in kelvins shall be related to the ColorTemperatureMireds attribute in mired + * by the relationship * - * The color temperature value in kelvins shall be related to the ColorTemperatureMireds attribute in - * mireds by the relationship + * "Color temperature [K]" = "1,000,000" / "ColorTemperatureMireds" * - * Color temperature in kelvins = 1,000,000 / ColorTemperatureMireds, where ColorTemperatureMireds is in - * the range 1 to 65279 mireds inclusive, giving a color temperature range from 1,000,000 kelvins to 15.32 - * kelvins. + * where ColorTemperatureMireds is in the range from 1 to 65279 inclusive, giving a color temperature range + * from 1,000,000 K to 15.32 K. * * If this attribute is implemented then the ColorMode attribute shall also be implemented. * @@ -1098,78 +1230,78 @@ export namespace ColorControl { colorTemperatureMireds: Attribute(0x7, TlvUInt16, { scene: true, persistent: true, default: 250 }), /** - * The ColorTempPhysicalMinMireds attribute indicates the minimum mired value supported by the hardware. - * ColorTempPhysicalMinMireds corresponds to the maximum color temperature in kelvins supported by the - * hardware. ColorTempPhysicalMinMireds <= ColorTemperatureMireds. + * Indicates the minimum mired value supported by the hardware. ColorTempPhysicalMinMireds corresponds to + * the maximum color temperature in kelvins supported by the hardware. + * + * ColorTempPhysicalMinMireds <= ColorTemperatureMireds. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.20 */ - colorTempPhysicalMinMireds: Attribute(0x400b, TlvUInt16.bound({ max: 65279 }), { default: 0 }), + colorTempPhysicalMinMireds: Attribute(0x400b, TlvUInt16.bound({ min: 1, max: 65279 }), { default: 1 }), /** - * The ColorTempPhysicalMaxMireds attribute indicates the maximum mired value supported by the hardware. - * ColorTempPhysicalMaxMireds corresponds to the minimum color temperature in kelvins supported by the - * hardware. ColorTemperatureMireds <= ColorTempPhysicalMaxMireds. + * Indicates the maximum mired value supported by the hardware. ColorTempPhysicalMaxMireds corresponds to + * the minimum color temperature in kelvins supported by the hardware. + * + * ColorTemperatureMireds <= ColorTempPhysicalMaxMireds. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.21 */ colorTempPhysicalMaxMireds: Attribute(0x400c, TlvUInt16.bound({ max: 65279 }), { default: 65279 }), /** - * The CoupleColorTempToLevelMinMireds attribute specifies a lower bound on the value of the - * ColorTemperatureMireds attribute for the purposes of coupling the ColorTemperatureMireds attribute to - * the CurrentLevel attribute when the CoupleColorTempToLevel bit of the Options attribute of the Level - * Control cluster is equal to 1. When coupling the ColorTemperatureMireds attribute to the CurrentLevel - * attribute, this value shall correspond to a CurrentLevel value of 0xFE (100%). + * Indicates a lower bound on the value of the ColorTemperatureMireds attribute for the purposes of + * coupling the ColorTemperatureMireds attribute to the CurrentLevel attribute when the + * CoupleColorTempToLevel bit of the Options attribute of the Level Control cluster is equal to 1. When + * coupling the ColorTemperatureMireds attribute to the CurrentLevel attribute, this value shall correspond + * to a CurrentLevel value of 254 (100%). * - * This attribute shall be set such that the following relationship exists: ColorTempPhysicalMinMireds ≤ - * CoupleColorTempToLevelMinMireds ≤ ColorTemperatureMireds + * This attribute shall be set such that the following relationship exists: ColorTempPhysicalMinMireds <= + * CoupleColorTempToLevelMinMireds <= ColorTemperatureMireds * * Note that since this attribute is stored as a micro reciprocal degree (mired) value (i.e. color * temperature in kelvins = 1,000,000 / CoupleColorTempToLevelMinMireds), the * CoupleColorTempToLevelMinMireds attribute corresponds to an upper bound on the value of the color - * temperature in kelvins supported by the device. + * temperature + * + * in kelvins supported by the device. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.22 */ coupleColorTempToLevelMinMireds: OptionalAttribute(0x400d, TlvUInt16), /** - * The StartUpColorTemperatureMireds attribute shall define the desired startup color temperature value a - * lamp shall use when it is supplied with power and this value shall be reflected in the - * ColorTemperatureMireds attribute. In addition, the ColorMode and EnhancedColorMode attributes shall be - * set to 0x02 (color temperature). The values of the StartUpColorTemperatureMireds attribute are listed in - * the table below, - * - * Table 12. Values of the StartUpColorTemperatureMireds attribute + * Indicates the desired startup color temperature value the light shall use when it is supplied with power + * and this value shall be reflected in the ColorTemperatureMireds attribute. In addition, the ColorMode + * and EnhancedColorMode attributes shall be set to 2 (ColorTemperatureMireds). The values of the + * StartUpColorTemperatureMireds attribute are listed in the table below, * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.23 */ startUpColorTemperatureMireds: OptionalWritableAttribute( 0x4010, - TlvNullable(TlvUInt16.bound({ max: 65279 })), + TlvNullable(TlvUInt16.bound({ min: 1, max: 65279 })), { persistent: true, writeAcl: AccessLevel.Manage } ) }, commands: { /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.14 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.14 */ moveToColorTemperature: Command(0xa, TlvMoveToColorTemperatureRequest, 0xa, TlvNoResponse), /** - * The MoveColorTemperature command allows the color temperature of a lamp to be moved at a specified rate. + * This command allows the color temperature of the light to be moved at a specified rate. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.21 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.21 */ moveColorTemperature: Command(0x4b, TlvMoveColorTemperatureRequest, 0x4b, TlvNoResponse), /** - * The StepColorTemperature command allows the color temperature of a lamp to be stepped with a specified - * step size. + * This command allows the color temperature of the light to be stepped with a specified step size. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.22 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.22 */ stepColorTemperature: Command(0x4c, TlvStepColorTemperatureRequest, 0x4c, TlvNoResponse) } @@ -1181,15 +1313,20 @@ export namespace ColorControl { export const EnhancedHueComponent = MutableCluster.Component({ attributes: { /** - * The EnhancedCurrentHue attribute represents non-equidistant steps along the CIE 1931 color triangle, and - * it provides 16-bits precision. + * Indicates the non-equidistant steps along the CIE 1931 color triangle, and it provides 16-bits precision. * * The upper 8 bits of this attribute shall be used as an index in the implementation specific XY lookup - * table to provide the non-equidistance steps. The lower 8 bits shall be used to interpolate between these + * table to provide the non-equidistant steps. The lower 8 bits shall be used to interpolate between these * steps in a linear way in order to provide color zoom for the user. * - * To provide compatibility with standard ZCL, the CurrentHue attribute shall contain a hue value in the - * range 0 to 254, calculated from the EnhancedCurrentHue attribute. + * To provide compatibility with clients not supporting EHUE, the CurrentHue attribute shall contain a hue + * value in the range 0 to 254, calculated from the EnhancedCurrentHue attribute. + * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once per second or + * + * • At the end of the movement/transition. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.12 */ @@ -1198,34 +1335,33 @@ export namespace ColorControl { commands: { /** - * The EnhancedMoveToHue command allows lamps to be moved in a smooth continuous transition from their - * current hue to a target hue. + * This command allows the light to be moved in a smooth continuous transition from their current hue to a + * target hue. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.15 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.15 */ enhancedMoveToHue: Command(0x40, TlvEnhancedMoveToHueRequest, 0x40, TlvNoResponse), /** - * The EnhancedMoveHue command allows lamps to be moved in a continuous stepped transition from their - * current hue to a target hue. + * This command allows the light to start a continuous transition starting from their current hue. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.16 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.16 */ enhancedMoveHue: Command(0x41, TlvEnhancedMoveHueRequest, 0x41, TlvNoResponse), /** - * The EnhancedStepHue command allows lamps to be moved in a stepped transition from their current hue to a - * target hue, resulting in a linear transition through XY space. + * This command allows the light to be moved in a stepped transition from their current hue, resulting in a + * linear transition through XY space. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.17 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.17 */ enhancedStepHue: Command(0x42, TlvEnhancedStepHueRequest, 0x42, TlvNoResponse), /** - * The EnhancedMoveToHueAndSaturation command allows lamps to be moved in a smooth continuous transition - * from their current hue to a target hue and from their current saturation to a target saturation. + * This command allows the light to be moved in a smooth continuous transition from their current hue to a + * target hue and from their current saturation to a target saturation. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.18 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.18 */ enhancedMoveToHueAndSaturation: Command( 0x43, @@ -1242,9 +1378,8 @@ export namespace ColorControl { export const ColorLoopComponent = MutableCluster.Component({ attributes: { /** - * The ColorLoopActive attribute specifies the current active status of the color loop. If this attribute - * has the value 0, the color loop shall not be active. If this attribute has the value 1, the color loop - * shall be active. All other values (2 to 254) are reserved. + * Indicates the current active status of the color loop. If this attribute has the value 0, the color loop + * shall NOT be active. If this attribute has the value 1, the color loop shall be active. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.14 */ @@ -1255,9 +1390,9 @@ export namespace ColorControl { ), /** - * The ColorLoopDirection attribute specifies the current direction of the color loop. If this attribute - * has the value 0, the EnhancedCurrentHue attribute shall be decremented. If this attribute has the value - * 1, the EnhancedCurrentHue attribute shall be incremented. All other values (2 to 254) are reserved. + * Indicates the current direction of the color loop. If this attribute has the value 0, the + * EnhancedCurrentHue attribute shall be decremented. If this attribute has the value 1, the + * EnhancedCurrentHue attribute shall be incremented. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.15 */ @@ -1268,25 +1403,23 @@ export namespace ColorControl { ), /** - * The ColorLoopTime attribute specifies the number of seconds it shall take to perform a full color loop, - * i.e., to cycle all values of the EnhancedCurrentHue attribute (between 0 and 0xFFFE). + * Indicates the number of seconds it shall take to perform a full color loop, i.e., to cycle all values of + * the EnhancedCurrentHue attribute (between 0 and 65534). * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.16 */ colorLoopTime: Attribute(0x4004, TlvUInt16, { scene: true, persistent: true, default: 25 }), /** - * The ColorLoopStartEnhancedHue attribute specifies the value of the EnhancedCurrentHue attribute from - * which the color loop shall be started. + * Indicates the value of the EnhancedCurrentHue attribute from which the color loop shall be started. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.17 */ colorLoopStartEnhancedHue: Attribute(0x4005, TlvUInt16, { default: 8960 }), /** - * The ColorLoopStoredEnhancedHue attribute specifies the value of the EnhancedCurrentHue attribute before - * the color loop was started. Once the color loop is complete, the EnhancedCurrentHue attribute shall be - * restored to this value. + * Indicates the value of the EnhancedCurrentHue attribute before the color loop was started. Once the + * color loop is complete, the EnhancedCurrentHue attribute shall be restored to this value. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.18 */ @@ -1295,10 +1428,10 @@ export namespace ColorControl { commands: { /** - * The Color Loop Set command allows a color loop to be activated such that the color lamp cycles through - * its range of hues. + * This command allows a color loop to be activated such that the color light cycles through its range of + * hues. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.19 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.19 */ colorLoopSet: Command(0x44, TlvColorLoopSetRequest, 0x44, TlvNoResponse) } @@ -1310,12 +1443,13 @@ export namespace ColorControl { export const HueSaturationOrXyOrColorTemperatureComponent = MutableCluster.Component({ commands: { /** - * The StopMoveStep command is provided to allow MoveTo and Step commands to be stopped. (Note this - * automatically provides symmetry to the Level Control cluster.) + * This command is provided to allow MoveTo and Step commands to be stopped. + * + * NOTE This automatically provides symmetry to the Level Control cluster. * - * NOTE the StopMoveStep command has no effect on an active color loop. + * NOTE The StopMoveStep command has no effect on an active color loop. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.11.20 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.20 */ stopMoveStep: Command(0x47, TlvStopMoveStepRequest, 0x47, TlvNoResponse) } @@ -1327,7 +1461,7 @@ export namespace ColorControl { export const Base = MutableCluster.Component({ id: 0x300, name: "ColorControl", - revision: 6, + revision: 7, features: { /** @@ -1368,58 +1502,64 @@ export namespace ColorControl { attributes: { /** - * The RemainingTime attribute holds the time remaining, in 1/10ths of a second, until the currently active + * Indicates the time remaining, in 1/10ths of a second, until transitions due to the currently active * command will be complete. * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • When it changes from 0 to any value higher than 10, or + * + * • When it changes, with a delta larger than 10, caused by the invoke of a command, or + * + * • When it changes to 0. + * + * For commands with a transition time or changes to the transition time less than 1 second, changes to + * this attribute shall NOT be reported. + * + * As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the + * reporting of this attribute in order to keep track of the remaining duration. + * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.4 */ remainingTime: OptionalAttribute(0x2, TlvUInt16, { default: 0 }), /** - * The DriftCompensation attribute indicates what mechanism, if any, is in use for compensation for - * color/intensity drift over time. It shall be one of the non-reserved values in Values of the - * DriftCompensation Attribute. - * - * ### Table 8. Values of the DriftCompensation Attribute + * Indicates what mechanism, if any, is in use for compensation for color/intensity drift over time. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.7 */ driftCompensation: OptionalAttribute(0x5, TlvEnum()), /** - * The CompensationText attribute holds a textual indication of what mechanism, if any, is in use to - * compensate for color/intensity drift over time. + * This attribute shall contain a textual indication of what mechanism, if any, is in use to compensate for + * color/intensity drift over time. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.8 */ compensationText: OptionalAttribute(0x6, TlvString.bound({ maxLength: 254 })), /** - * The ColorMode attribute indicates which attributes are currently determining the color of the device. + * Indicates which attributes are currently determining the color of the device. * * The value of the ColorMode attribute cannot be written directly - it is set upon reception of any * command in section Commands to the appropriate mode for that command. * - * Table 9. Values of the ColorMode Attribute - * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.10 */ colorMode: Attribute(0x8, TlvEnum(), { persistent: true }), /** - * The Options attribute is meant to be changed only during commissioning. The Options attribute is a - * bitmap that determines the default behavior of some cluster commands. Each command that is dependent on - * the Options attribute shall first construct a temporary Options bitmap that is in effect during the - * command processing. The temporary Options bitmap has the same format and meaning as the Options - * attribute, but includes any bits that may be overridden by command fields. + * Indicates a bitmap that determines the default behavior of some cluster commands. Each command that is + * dependent on the Options attribute shall first construct a temporary Options bitmap that is in effect + * during the command processing. The temporary Options bitmap has the same format and meaning as the + * Options attribute, but includes any bits that may be overridden by command fields. + * + * This attribute is meant to be changed only during commissioning. * * Below is the format and description of the Options attribute and temporary Options bitmap and the effect * on dependent commands. * - * Table 10. Options Attribute - * - * ExecuteIfOff Options bit: Command execution shall NOT continue beyond the Options processing if all of - * these criteria are true: + * Command execution shall NOT continue beyond the Options processing if all of these criteria are true: * * • The On/Off cluster exists on the same endpoint as this cluster. * @@ -1432,134 +1572,139 @@ export namespace ColorControl { options: WritableAttribute(0xf, TlvBitmap(TlvUInt8, Options)), /** - * The NumberOfPrimaries attribute contains the number of color primaries implemented on this device. A - * value of null shall indicate that the number of primaries is unknown. + * Indicates the number of color primaries implemented on this device. A value of null shall indicate that + * the number of primaries is unknown. * * Where this attribute is implemented, the attributes below for indicating the “x” and “y” color values of * the primaries shall also be implemented for each of the primaries from 1 to NumberOfPrimaries, without * leaving gaps. Implementation of the Primary1Intensity attribute and subsequent intensity attributes is * optional. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.24 */ numberOfPrimaries: FixedAttribute(0x10, TlvNullable(TlvUInt8.bound({ max: 6 }))), /** - * The Primary1X attribute contains the normalized chromaticity value x for this primary, as defined in the - * CIE xyY Color Space. + * Indicates the normalized chromaticity value x for this primary, as defined in the CIE xyY Color Space. * * The value of x shall be related to the Primary1X attribute by the relationship x = Primary1X / 65536 * (Primary1X in the range 0 to 65279 inclusive) * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.25 */ primary1X: OptionalFixedAttribute(0x11, TlvUInt16.bound({ max: 65279 })), /** - * The Primary1Y attribute contains the normalized chromaticity value y for this primary, as defined in the - * CIE xyY Color Space. + * Indicates the normalized chromaticity value y for this primary, as defined in the CIE xyY Color Space. * * The value of y shall be related to the Primary1Y attribute by the relationship y = Primary1Y / 65536 * (Primary1Y in the range 0 to 65279 inclusive) * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.26 */ primary1Y: OptionalFixedAttribute(0x12, TlvUInt16.bound({ max: 65279 })), /** - * The Primary1intensity attribute contains a representation of the maximum intensity of this primary as - * defined in the Dimming Light Curve in the Ballast Configuration cluster (see Ballast Configuration - * Cluster), normalized such that the primary with the highest maximum intensity contains the value 0xFE. + * Indicates a representation of the maximum intensity of this primary as defined in the Dimming Light + * Curve in the Ballast Configuration cluster (see Ballast Configuration Cluster), normalized such that the + * primary with the highest maximum intensity contains the value 254. * * A value of null shall indicate that this primary is not available. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8.4 + * 3.2.7.28. Primary2X, Primary2Y, Primary2Intensity, Primary3X, Primary3Y, Primary3Intensity, Primary4X, + * Primary4Y, Primary4Intensity, Primary5X, Primary5Y, Primary5Intensity, Primary6X, Primary6Y and + * Primary6Intensity Attributes + * + * These attributes shall represent the capabilities of the 2nd, 3rd, 4th, 5th and 6th primaries, where + * present, in the same way as for the Primary1X, Primary1Y and Primary1Intensity attributes. + * + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.27 */ primary1Intensity: OptionalFixedAttribute(0x13, TlvNullable(TlvUInt8)), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary2X: OptionalFixedAttribute(0x15, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary2Y: OptionalFixedAttribute(0x16, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary2Intensity: OptionalFixedAttribute(0x17, TlvNullable(TlvUInt8)), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary3X: OptionalFixedAttribute(0x19, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary3Y: OptionalFixedAttribute(0x1a, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.8 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary3Intensity: OptionalFixedAttribute(0x1b, TlvNullable(TlvUInt8)), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary4X: OptionalFixedAttribute(0x20, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary4Y: OptionalFixedAttribute(0x21, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary4Intensity: OptionalFixedAttribute(0x22, TlvNullable(TlvUInt8)), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary5X: OptionalFixedAttribute(0x24, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary5Y: OptionalFixedAttribute(0x25, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary5Intensity: OptionalFixedAttribute(0x26, TlvNullable(TlvUInt8)), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary6X: OptionalFixedAttribute(0x28, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary6Y: OptionalFixedAttribute(0x29, TlvUInt16.bound({ max: 65279 })), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.9 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ primary6Intensity: OptionalFixedAttribute(0x2a, TlvNullable(TlvUInt8)), /** - * The WhitePointX attribute contains the normalized chromaticity value x, as defined in the CIE xyY Color - * Space, of the current white point of the device. + * Indicates the normalized chromaticity value x, as defined in the CIE xyY Color Space, of the current + * white point of the device. * * The value of x shall be related to the WhitePointX attribute by the relationship x = WhitePointX / 65536 * (WhitePointX in the range 0 to 65279 inclusive) * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10.1 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.29 */ whitePointX: OptionalWritableAttribute( 0x30, @@ -1568,14 +1713,13 @@ export namespace ColorControl { ), /** - * The WhitePointY attribute contains the normalized chromaticity value y, as defined in the CIE xyY - * - * Color Space, of the current white point of the device. + * Indicates the normalized chromaticity value y, as defined in the CIE xyY Color Space, of the current + * white point of the device. * * The value of y shall be related to the WhitePointY attribute by the relationship y = WhitePointY / 65536 * (WhitePointY in the range 0 to 65279 inclusive) * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10.2 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.30 */ whitePointY: OptionalWritableAttribute( 0x31, @@ -1584,13 +1728,13 @@ export namespace ColorControl { ), /** - * The ColorPointRX attribute contains the normalized chromaticity value x, as defined in the CIE xyY Color - * Space, of the red color point of the device. + * Indicates the normalized chromaticity value x, as defined in the CIE xyY Color Space, of the red color + * point of the device. * * The value of x shall be related to the ColorPointRX attribute by the relationship x = ColorPointRX / * 65536 (ColorPointRX in the range 0 to 65279 inclusive) * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10.3 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.31 */ colorPointRx: OptionalWritableAttribute( 0x32, @@ -1599,13 +1743,13 @@ export namespace ColorControl { ), /** - * The ColorPointRY attribute contains the normalized chromaticity value y, as defined in the CIE xyY Color - * Space, of the red color point of the device. + * Indicates the normalized chromaticity value y, as defined in the CIE xyY Color Space, of the red color + * point of the device. * * The value of y shall be related to the ColorPointRY attribute by the relationship y = ColorPointRY / * 65536 (ColorPointRY in the range 0 to 65279 inclusive) * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.32 */ colorPointRy: OptionalWritableAttribute( 0x33, @@ -1614,14 +1758,22 @@ export namespace ColorControl { ), /** - * The ColorPointRIntensity attribute contains a representation of the relative intensity of the red color - * point as defined in the Dimming Light Curve in the Ballast Configuration cluster (see Ballast - * Configuration Cluster), normalized such that the color point with the highest relative intensity - * contains the value 0xFE. + * Indicates a representation of the relative intensity of the red color point as defined in the Dimming + * Light Curve in the Ballast Configuration cluster (see Ballast Configuration Cluster), normalized such + * that the color point with the highest relative intensity contains the value 254. * * A value of null shall indicate an invalid value. * - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10.5 + * 3.2.7.34. ColorPointGX, ColorPointGY, ColorPointGIntensity, ColorPointBX, ColorPointBY and + * ColorPointBIntensity Attributes + * + * These attributes shall represent the chromaticity values and intensities of the green and blue color + * points, in the same way as for the ColorPointRX, ColorPointRY and ColorPointRIntensity attributes. + * + * If any one of these red, green or blue color point attributes is implemented then they shall all be + * implemented. + * + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.33 */ colorPointRIntensity: OptionalWritableAttribute( 0x34, @@ -1630,7 +1782,7 @@ export namespace ColorControl { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ colorPointGx: OptionalWritableAttribute( 0x36, @@ -1639,7 +1791,7 @@ export namespace ColorControl { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ colorPointGy: OptionalWritableAttribute( 0x37, @@ -1648,7 +1800,7 @@ export namespace ColorControl { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ colorPointGIntensity: OptionalWritableAttribute( 0x38, @@ -1657,7 +1809,7 @@ export namespace ColorControl { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ colorPointBx: OptionalWritableAttribute( 0x3a, @@ -1666,7 +1818,7 @@ export namespace ColorControl { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ colorPointBy: OptionalWritableAttribute( 0x3b, @@ -1675,7 +1827,7 @@ export namespace ColorControl { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 3.2.10 + * @see {@link MatterSpecification.v13.Cluster} § 3.2.7 */ colorPointBIntensity: OptionalWritableAttribute( 0x3c, @@ -1684,15 +1836,11 @@ export namespace ColorControl { ), /** - * The EnhancedColorMode attribute specifies which attributes are currently determining the color of the - * device, as detailed in Values of the EnhancedColorMode Attribute. - * - * ### Table 11. Values of the EnhancedColorMode Attribute + * Indicates which attributes are currently determining the color of the device. * - * To provide compatibility with standard ZCL, the original ColorMode attribute shall indicate ‘CurrentHue - * and CurrentSaturation’ when the light uses the EnhancedCurrentHue attribute. If the ColorMode attribute - * is changed, e.g., due to one of the standard Color Control cluster commands defined in the ZCL, its new - * value shall be copied to the EnhancedColorMode attribute. + * To provide compatibility with clients not supporting EHUE, the original ColorMode attribute shall + * indicate CurrentHue and CurrentSaturation when the light uses the EnhancedCurrentHue attribute. If the + * ColorMode attribute is changed, its new value shall be copied to the EnhancedColorMode attribute. * * @see {@link MatterSpecification.v13.Cluster} § 3.2.7.13 */ @@ -1703,6 +1851,8 @@ export namespace ColorControl { ), /** + * Indicates the color control capabilities of the device. + * * Bits 0-4 of the ColorCapabilities attribute shall have the same values as the corresponding bits of the * FeatureMap attribute. All other bits in ColorCapabilities shall be 0. * @@ -1723,7 +1873,9 @@ export namespace ColorControl { { flags: { colorLoop: true }, component: ColorLoopComponent }, { flags: { hueSaturation: true }, component: HueSaturationOrXyOrColorTemperatureComponent }, { flags: { xy: true }, component: HueSaturationOrXyOrColorTemperatureComponent }, - { flags: { colorTemperature: true }, component: HueSaturationOrXyOrColorTemperatureComponent } + { flags: { colorTemperature: true }, component: HueSaturationOrXyOrColorTemperatureComponent }, + { flags: { enhancedHue: true, hueSaturation: false }, component: false }, + { flags: { colorLoop: true, enhancedHue: false }, component: false } ) }); @@ -1733,6 +1885,17 @@ export namespace ColorControl { export const ClusterInstance = MutableCluster(Base); /** + * This cluster provides an interface for changing the color of a light. Color is specified according to the CIE + * 1931 Color space. Color control is carried out in terms of x,y values, as defined by this specification. + * + * Additionally, color may optionally be controlled in terms of color temperature, or as hue and saturation values + * based on optionally variable RGB and W color points. It is recommended that the hue and saturation are + * interpreted according to the HSV (a.k.a. HSB) color model. + * + * Control over luminance is not included, as this is provided by means of the Level Control for Lighting cluster. + * It is recommended that the level provided by this cluster be interpreted as representing a proportion of the + * maximum intensity achievable at the current color. + * * ColorControlCluster supports optional features that you can enable with the ColorControlCluster.with() factory * method. * diff --git a/packages/types/src/clusters/commissioner-control.ts b/packages/types/src/clusters/commissioner-control.ts new file mode 100644 index 0000000000..42d290d41d --- /dev/null +++ b/packages/types/src/clusters/commissioner-control.ts @@ -0,0 +1,282 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { Attribute, Command, TlvNoResponse, Event, EventPriority } from "../cluster/Cluster.js"; +import { BitFlag } from "../schema/BitmapSchema.js"; +import { TlvUInt32, TlvBitmap, TlvUInt64, TlvUInt16, TlvEnum } from "../tlv/TlvNumber.js"; +import { AccessLevel } from "#model"; +import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvVendorId } from "../datatype/VendorId.js"; +import { TlvString, TlvByteString } from "../tlv/TlvString.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { TlvNodeId } from "../datatype/NodeId.js"; +import { Status } from "../globals/Status.js"; +import { TlvFabricIndex } from "../datatype/FabricIndex.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace CommissionerControl { + /** + * @see {@link MatterSpecification.v13.Core} § 11.26.4.1 + */ + export const SupportedDeviceCategory = { + /** + * Aggregators which support Fabric Synchronization may be commissioned. + * + * The FabricSynchronization bit shall be set to 1 if and only if the server supports commissioning nodes that + * support Fabric Synchronization. + * + * @see {@link MatterSpecification.v13.Core} § 11.26.4.1.1 + */ + fabricSynchronization: BitFlag(0) + }; + + /** + * Input to the CommissionerControl requestCommissioningApproval command + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.1 + */ + export const TlvRequestCommissioningApprovalRequest = TlvObject({ + requestId: TlvField(0, TlvUInt64), + vendorId: TlvField(1, TlvVendorId), + productId: TlvField(2, TlvUInt16), + label: TlvOptionalField(3, TlvString.bound({ maxLength: 64 })) + }); + + /** + * Input to the CommissionerControl requestCommissioningApproval command + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.1 + */ + export interface RequestCommissioningApprovalRequest extends TypeFromSchema {} + + /** + * Input to the CommissionerControl commissionNode command + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.5 + */ + export const TlvCommissionNodeRequest = TlvObject({ + requestId: TlvField(0, TlvUInt64), + responseTimeoutSeconds: TlvField(1, TlvUInt16.bound({ min: 30, max: 120 })) + }); + + /** + * Input to the CommissionerControl commissionNode command + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.5 + */ + export interface CommissionNodeRequest extends TypeFromSchema {} + + /** + * When received within the timeout specified by ResponseTimeoutSeconds in the CommissionNode command, the client + * shall open a commissioning window on a node which matches the VendorID and ProductID provided in the associated + * RequestCommissioningApproval command. + * + * When commissioning this node, the server shall check that the VendorID and ProductID fields provided in the + * RequestCommissioningApproval command match the VendorID and ProductID attributes of the Basic Information + * Cluster which have already been verified during the Device Attestation Procedure. If they do not match, the + * server shall NOT complete commissioning and SHOULD indicate an error to the user. + * + * NOTE + * + * This is an alias onto the Open Commissioning Window command within the Administrator Commissioning Cluster. + * Refer to the Open Commissioning Window command for a description of the command behavior and parameters. + * + * The parameters for ReverseOpenCommissioningWindow command are as follows: + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.8 + */ + export const TlvReverseOpenCommissioningWindowResponse = TlvObject({ + commissioningTimeout: TlvField(0, TlvUInt16), + pakePasscodeVerifier: TlvField(1, TlvByteString), + discriminator: TlvField(2, TlvUInt16.bound({ max: 4095 })), + iterations: TlvField(3, TlvUInt32.bound({ min: 1000, max: 100000 })), + salt: TlvField(4, TlvByteString.bound({ minLength: 16, maxLength: 32 })) + }); + + /** + * When received within the timeout specified by ResponseTimeoutSeconds in the CommissionNode command, the client + * shall open a commissioning window on a node which matches the VendorID and ProductID provided in the associated + * RequestCommissioningApproval command. + * + * When commissioning this node, the server shall check that the VendorID and ProductID fields provided in the + * RequestCommissioningApproval command match the VendorID and ProductID attributes of the Basic Information + * Cluster which have already been verified during the Device Attestation Procedure. If they do not match, the + * server shall NOT complete commissioning and SHOULD indicate an error to the user. + * + * NOTE + * + * This is an alias onto the Open Commissioning Window command within the Administrator Commissioning Cluster. + * Refer to the Open Commissioning Window command for a description of the command behavior and parameters. + * + * The parameters for ReverseOpenCommissioningWindow command are as follows: + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.8 + */ + export interface ReverseOpenCommissioningWindowResponse extends TypeFromSchema {} + + /** + * Body of the CommissionerControl commissioningRequestResult event + * + * @see {@link MatterSpecification.v13.Core} § 11.26.7.1 + */ + export const TlvCommissioningRequestResultEvent = TlvObject({ + requestId: TlvField(0, TlvUInt64), + clientNodeId: TlvField(1, TlvNodeId), + statusCode: TlvField(2, TlvEnum()), + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * Body of the CommissionerControl commissioningRequestResult event + * + * @see {@link MatterSpecification.v13.Core} § 11.26.7.1 + */ + export interface CommissioningRequestResultEvent extends TypeFromSchema {} + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster({ + id: 0x751, + name: "CommissionerControl", + revision: 1, + + attributes: { + /** + * Indicates the device categories specified in SupportedDeviceCategoryBitmap that are supported by this + * Commissioner Control Cluster server. + * + * A client shall NOT send the RequestCommissioningApproval command if the intended node to be commissioned + * does not conform to any of the values specified in SupportedDeviceCategories. + * + * @see {@link MatterSpecification.v13.Core} § 11.26.5.1 + */ + supportedDeviceCategories: Attribute( + 0x0, + TlvBitmap(TlvUInt32, SupportedDeviceCategory), + { readAcl: AccessLevel.Manage, writeAcl: AccessLevel.Manage } + ) + }, + + commands: { + /** + * This command is sent by a client to request approval for a future CommissionNode call. This is required + * to be a separate step in order to provide the server time for interacting with a user before informing + * the client that the CommissionNode operation may be successful. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * UNSUPPORTED_ACCESS. + * + * The server may request approval from the user, but it is not required. + * + * The server shall always return SUCCESS to a correctly formatted RequestCommissioningApproval command, + * and then generate a CommissioningRequestResult event associated with the command’s + * + * accessing fabric once the result is ready. + * + * Clients SHOULD avoid using the same RequestID. If the RequestID and client NodeID of a + * RequestCommissioningApproval match a previously received RequestCommissioningApproval and the server has + * not returned an error or completed commissioning of a device for the prior request, then the server + * SHOULD return FAILURE. + * + * The parameters for RequestCommissioningApproval command are as follows: + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.1 + */ + requestCommissioningApproval: Command( + 0x0, + TlvRequestCommissioningApprovalRequest, + 0x0, + TlvNoResponse, + { invokeAcl: AccessLevel.Manage } + ), + + /** + * This command is sent by a client to request that the server begins commissioning a previously approved + * request. + * + * The server shall return FAILURE if the CommissionNode command is not sent from the same NodeID and on + * the same fabric as the RequestCommissioningApproval or if the provided RequestID to CommissionNode does + * not match the value provided to RequestCommissioningApproval. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * + * UNSUPPORTED_ACCESS. + * + * Upon receipt, the server shall respond with ReverseOpenCommissioningWindow if CommissioningRequestResult + * was generated with StatusCode of SUCCESS for the matching RequestID field and NodeID of the client. + * + * The server shall return FAILURE if the CommissionNode command is received after the server has already + * responded to a client with ReverseOpenCommissioningWindow for a matching RequestID field and NodeID of + * the client unless the client has sent another RequestCommissioningApproval and received an additional + * CommissioningRequestResult. + * + * The parameters for CommissionNode command are as follows: + * + * @see {@link MatterSpecification.v13.Core} § 11.26.6.5 + */ + commissionNode: Command( + 0x1, + TlvCommissionNodeRequest, + 0x2, + TlvReverseOpenCommissioningWindowResponse, + { invokeAcl: AccessLevel.Manage } + ) + }, + + events: { + /** + * This event shall be generated by the server following a RequestCommissioningApproval command which the + * server responded to with SUCCESS. + * + * NOTE + * + * The approval is valid for a period determined by the manufacturer and characteristics of the node + * presenting the Commissioner Control Cluster. Clients SHOULD send the CommissionNode command immediately + * upon receiving a CommissioningRequestResult event. + * + * 11.26.7.2. RequestID / ClientNodeID Fields + * + * The RequestID shall match the RequestID provided to RequestCommissioningApproval and the ClientNodeID + * shall match the NodeID of the client which generated the RequestCommissioningAp + * + * proval command. + * + * @see {@link MatterSpecification.v13.Core} § 11.26.7.1 + */ + commissioningRequestResult: Event( + 0x0, + EventPriority.Info, + TlvCommissioningRequestResultEvent, + { readAcl: AccessLevel.Manage } + ) + } + }); + + /** + * The Commissioner Control Cluster supports the ability for clients to request the commissioning of themselves or + * other nodes onto a fabric which the cluster server can commission onto. An example use case is ecosystem to + * ecosystem Fabric Synchronization setup. + * + * The generalized flow supported by the Commissioner Control Cluster can be seen in the following diagram. + * + * Figure 101. Commissioner Control Cluster - General Flow + * + * @see {@link MatterSpecification.v13.Core} § 11.26 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + export const Complete = Cluster; +} + +export type CommissionerControlCluster = CommissionerControl.Cluster; +export const CommissionerControlCluster = CommissionerControl.Cluster; +ClusterRegistry.register(CommissionerControl.Complete); diff --git a/packages/types/src/clusters/concentration-measurement.ts b/packages/types/src/clusters/concentration-measurement.ts index 483d3d90d2..e368c5c51e 100644 --- a/packages/types/src/clusters/concentration-measurement.ts +++ b/packages/types/src/clusters/concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/content-app-observer.ts b/packages/types/src/clusters/content-app-observer.ts index 645f2158f9..8ae5d3bec0 100644 --- a/packages/types/src/clusters/content-app-observer.ts +++ b/packages/types/src/clusters/content-app-observer.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/content-control.ts b/packages/types/src/clusters/content-control.ts index 1c68807c0f..f086697a06 100644 --- a/packages/types/src/clusters/content-control.ts +++ b/packages/types/src/clusters/content-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { AccessLevel } from "#model"; -import { TlvUInt32, TlvUInt16, TlvEnum, TlvUInt8 } from "../tlv/TlvNumber.js"; +import { TlvUInt32, TlvUInt16, TlvUInt8, TlvBitmap } from "../tlv/TlvNumber.js"; import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; import { TlvBoolean } from "../tlv/TlvBoolean.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; @@ -87,7 +87,7 @@ export namespace ContentControl { } /** - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.1 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2 */ export const TlvRatingName = TlvObject({ /** @@ -95,20 +95,20 @@ export namespace ContentControl { * system is dependent upon the region or country where the Node has been provisioned, and may vary from one * country to another. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.1.1 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2.1 */ ratingName: TlvField(0, TlvString.bound({ maxLength: 8 })), /** * This field shall specify a human readable (displayable) description for RatingName. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.1.2 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2.2 */ ratingNameDesc: TlvOptionalField(1, TlvString.bound({ maxLength: 64 })) }); /** - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.1 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2 */ export interface RatingName extends TypeFromSchema {} @@ -141,9 +141,8 @@ export namespace ContentControl { */ export const TlvSetScheduledContentRatingThresholdRequest = TlvObject({ /** - * This field indicates a threshold rating for filtering scheduled content. This field shall be set to one - * - * of the values present in the ScheduledContentRatings attribute. + * This field indicates a threshold rating for filtering scheduled content. This field shall be set to one of + * the values present in the ScheduledContentRatings attribute. * * @see {@link MatterSpecification.v13.Cluster} § 6.13.8.11.1 */ @@ -177,7 +176,7 @@ export namespace ContentControl { /** * This field shall indicate the amount of extra time (in seconds) to increase RemainingScreenTime. This field - * shall not exceed the remaining time of this day. + * shall NOT exceed the remaining time of this day. * * @see {@link MatterSpecification.v13.Cluster} § 6.13.8.6.2 */ @@ -198,9 +197,8 @@ export namespace ContentControl { */ export const TlvSetScreenDailyTimeRequest = TlvObject({ /** - * This field shall indicate the time (in seconds) which the User is allowed to spend watching TV on - * - * this media device within one day. + * This field shall indicate the time (in seconds) which the User is allowed to spend watching TV on this media + * device within one day. * * @see {@link MatterSpecification.v13.Cluster} § 6.13.8.7.1 */ @@ -215,16 +213,14 @@ export namespace ContentControl { export interface SetScreenDailyTimeRequest extends TypeFromSchema {} /** - * [options="header",valign="middle"]b - * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3 */ export const TlvBlockChannel = TlvObject({ /** * This field shall indicate a unique index value for a blocked channel. This value may be used to indicate one * selected channel which will be removed from BlockChannelList attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2.1 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3.1 */ blockChannelIndex: TlvField(0, TlvNullable(TlvUInt16)), @@ -234,7 +230,7 @@ export namespace ContentControl { * This field is required but shall be set to 0 for channels such as over-the-top channels that are not * represented by a major or minor number. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2.2 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3.2 */ majorNumber: TlvField(1, TlvUInt16), @@ -244,7 +240,7 @@ export namespace ContentControl { * This field is required but shall be set to 0 for channels such as over-the-top channels that are not * represented by a major or minor number. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2.3 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3.3 */ minorNumber: TlvField(2, TlvUInt16), @@ -252,15 +248,13 @@ export namespace ContentControl { * This field shall indicate the unique identifier for a specific channel. This field is optional, but SHOULD * be provided when MajorNumber and MinorNumber are not available. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2.4 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3.4 */ identifier: TlvOptionalField(3, TlvString) }); /** - * [options="header",valign="middle"]b - * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3 */ export interface BlockChannel extends TypeFromSchema {} @@ -310,7 +304,7 @@ export namespace ContentControl { export interface RemoveBlockChannelsRequest extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4 */ export const TlvAppInfo = TlvObject({ /** @@ -319,7 +313,7 @@ export namespace ContentControl { * Content App Platform providers will have their own catalog vendor ID (set to their own Vendor ID) and will * assign an ApplicationID to each Content App. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3.1 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4.1 */ catalogVendorId: TlvField(0, TlvUInt16), @@ -327,13 +321,13 @@ export namespace ContentControl { * This field shall indicate the application identifier, expressed as a string, such as "PruneVideo" or * "Company X". This field shall be unique within a catalog. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3.2 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4.2 */ applicationId: TlvField(1, TlvString) }); /** - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.3 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4 */ export interface AppInfo extends TypeFromSchema {} @@ -381,44 +375,44 @@ export namespace ContentControl { export interface RemoveBlockApplicationsRequest extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.5 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.1 */ - export enum DayOfWeek { + export const DayOfWeek = { /** * Sunday */ - Sunday = 0, + sunday: BitFlag(0), /** * Monday */ - Monday = 1, + monday: BitFlag(1), /** * Tuesday */ - Tuesday = 2, + tuesday: BitFlag(2), /** * Wednesday */ - Wednesday = 3, + wednesday: BitFlag(3), /** * Thursday */ - Thursday = 4, + thursday: BitFlag(4), /** * Friday */ - Friday = 5, + friday: BitFlag(5), /** * Saturday */ - Saturday = 6 - } + saturday: BitFlag(6) + }; /** * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.6 @@ -461,34 +455,34 @@ export namespace ContentControl { export interface TimePeriod extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.5 */ export const TlvTimeWindow = TlvObject({ /** * This field shall indicate a unique index of a specific time window. This value may be used to indicate a * selected time window which will be removed from the BlockContentTimeWindow attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.5.1 */ timeWindowIndex: TlvField(0, TlvNullable(TlvUInt16)), /** * This field shall indicate a day of week. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4.2 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.5.2 */ - dayOfWeek: TlvField(1, TlvEnum()), + dayOfWeek: TlvField(1, TlvBitmap(TlvUInt8, DayOfWeek)), /** * This field shall indicate one or more discrete time periods. * - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4.3 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.5.3 */ timePeriod: TlvField(2, TlvArray(TlvTimePeriod)) }); /** - * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.4 + * @see {@link MatterSpecification.v13.Cluster} § 6.13.5.5 */ export interface TimeWindow extends TypeFromSchema {} @@ -788,9 +782,8 @@ export namespace ContentControl { /** * The purpose of this command is to add the extra screen time for the user. * - * If a client with Operate privilege invokes this command, the media device shall check whether - * - * the PINCode passed in the command matches the current PINCode value. If these match, then the + * If a client with Operate privilege invokes this command, the media device shall check whether the + * PINCode passed in the command matches the current PINCode value. If these match, then the * RemainingScreenTime attribute shall be increased by the specified BonusTime value. * * If the PINs do not match, then a response with InvalidPINCode error status shall be returned, and no @@ -844,9 +837,8 @@ export namespace ContentControl { attributes: { /** * Indicates whether the playback of unrated content is allowed when the Content Control feature is - * activated. If this attribute equals FALSE, then playback of unrated content - * - * shall be permitted. Otherwise, the media device shall prevent the playback of unrated content. + * activated. If this attribute equals FALSE, then playback of unrated content shall be permitted. + * Otherwise, the media device shall prevent the playback of unrated content. * * When this attribute changes, the device SHOULD make the user aware of any limits of this feature. For * example, if the feature does not control content within apps, then the device should make this clear to @@ -899,9 +891,10 @@ export namespace ContentControl { /** * The purpose of this command is to set BlockChannelList attribute. * - * Upon receipt of the AddBlockChannels command, the media device shall check if the channels passed in - * this command are valid. If the channel is invalid, then a response with InvalidChannel error Status - * shall be returned. + * Upon receipt of the AddBlockChannels command, the media device shall check if the channels + * + * passed in this command are valid. If the channel is invalid, then a response with InvalidChannel error + * Status shall be returned. * * If there is at least one channel in Channels field which is not in the BlockChannelList attribute, the * media device shall process the request by adding these new channels into the BlockChannelList attribute @@ -960,7 +953,9 @@ export namespace ContentControl { * * Upon receipt of the AddBlockApplications command, the media device shall check if the Applications * passed in this command are installed. If there is an application in Applications field which is not - * identified by media device, then a response with UnidentifiableApplication error Status may be returned. + * identified by media device, then a response with UnidentifiableApplication error Status may be + * + * returned. * * If there is one or more applications which are not present in BlockApplicationList attribute, the media * device shall process the request by adding the new application to the BlockApplicationList attribute and @@ -1009,7 +1004,7 @@ export namespace ContentControl { * the Content Control feature is activated. The media device shall reject any request to play content * during one period of this attribute. If it is entering any one period of this attribute, the media * device shall block content which is playing and generate an event EnteringBlockContentTimeWindow. There - * shall not be multiple entries in this attribute list for the same day of week. + * shall NOT be multiple entries in this attribute list for the same day of week. * * @see {@link MatterSpecification.v13.Cluster} § 6.13.7.11 */ @@ -1021,7 +1016,6 @@ export namespace ContentControl { * The purpose of this command is to set the BlockContentTimeWindow attribute. * * Upon receipt of the SetBlockContentTimeWindow command, the media device shall check if the - * * TimeWindowIndex field passed in this command is NULL. If the TimeWindowIndex field is NULL, the media * device shall check if there is an entry in the BlockContentTimeWindow attribute which matches with the * TimePeriod and DayOfWeek fields passed in this command. * If Yes, then a response with diff --git a/packages/types/src/clusters/content-launcher.ts b/packages/types/src/clusters/content-launcher.ts index 1d55347b7f..8c44fe3405 100644 --- a/packages/types/src/clusters/content-launcher.ts +++ b/packages/types/src/clusters/content-launcher.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -150,7 +150,8 @@ export namespace ContentLauncher { export const TlvStyleInformation = TlvObject({ /** * This field shall indicate the URL of image used for Styling different Video Player sections like Logo, - * Watermark etc. + * Watermark etc. The syntax of this field shall follow the syntax as specified in RFC 1738 and shall use the + * https scheme. * * @see {@link MatterSpecification.v13.Cluster} § 6.7.5.9.1 */ @@ -170,8 +171,9 @@ export namespace ContentLauncher { color: TlvOptionalField(1, TlvString), /** - * This field shall indicate the size of the image used for Styling different Video Player sections like Logo, - * Watermark etc. + * This field shall indicate the size of the image used for Styling different Video Player sections like + * + * Logo, Watermark etc. * * @see {@link MatterSpecification.v13.Cluster} § 6.7.5.9.3 */ @@ -276,9 +278,8 @@ export namespace ContentLauncher { * * This field shall NOT be present if the track is not an audio track. * - * If the track is an audio track, this field MUST be present. A value of null shall indicate that the - * - * server can choose the audio output(s) to play the Audio Track on. + * If the track is an audio track, this field MUST be present. A value of null shall indicate that the server + * can choose the audio output(s) to play the Audio Track on. * * @see {@link MatterSpecification.v13.Cluster} § 6.7.5.12.3 */ @@ -303,9 +304,8 @@ export namespace ContentLauncher { * This field shall indicate the preferred position (in milliseconds) in the media to launch playback from. In * case the position falls in the middle of a frame, the server shall set the position to the beginning of that * frame and set the SampledPosition attribute on the MediaPlayback cluster accordingly. A value of null shall - * indicate that playback position is not applicable for the current state of the media playback. - * - * ported). + * indicate that playback position is not applicable for the current state of the media playback. (For example + * : Live media with no known duration and where seek is not supported). * * @see {@link MatterSpecification.v13.Cluster} § 6.7.5.11.1 */ @@ -346,7 +346,8 @@ export namespace ContentLauncher { */ export const TlvLaunchUrlRequest = TlvObject({ /** - * This field shall indicate the URL of content to launch. + * This field shall indicate the URL of content to launch. The syntax of this field shall follow the syntax as + * specified in RFC 1738 and shall use the https scheme. * * @see {@link MatterSpecification.v13.Cluster} § 6.7.7.2.1 */ @@ -703,8 +704,9 @@ export namespace ContentLauncher { export const UrlPlaybackComponent = MutableCluster.Component({ attributes: { /** - * This attribute shall provide a list of content types supported by the Video Player or Content App in the - * form of entries in the HTTP "Accept" request header. + * This attribute shall provide a list of content types supported by the Video Player or Content App + * + * in the form of entries in the HTTP "Accept" request header. * * @see {@link MatterSpecification.v13.Cluster} § 6.7.6.1 */ @@ -722,9 +724,8 @@ export namespace ContentLauncher { /** * Upon receipt, this shall launch content from the specified URL. * - * The content types supported include those identified in the AcceptHeader and SupportedStreaming - * - * Protocols attributes. + * The content types supported include those identified in the AcceptHeader and SupportedStreamingProtocols + * attributes. * * A check shall be made to ensure the URL is secure (uses HTTPS). * diff --git a/packages/types/src/clusters/descriptor.ts b/packages/types/src/clusters/descriptor.ts index c26c160695..36cddc765a 100644 --- a/packages/types/src/clusters/descriptor.ts +++ b/packages/types/src/clusters/descriptor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/device-energy-management-mode.ts b/packages/types/src/clusters/device-energy-management-mode.ts index e78fc2cfc4..e2c07c4538 100644 --- a/packages/types/src/clusters/device-energy-management-mode.ts +++ b/packages/types/src/clusters/device-energy-management-mode.ts @@ -1,29 +1,21 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; -import { - WritableAttribute, - FixedAttribute, - Attribute, - OptionalWritableAttribute, - Command, - TlvNoResponse -} from "../cluster/Cluster.js"; -import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; -import { TlvNullable } from "../tlv/TlvNullable.js"; import { BitFlag } from "../schema/BitmapSchema.js"; +import { FixedAttribute, Attribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; +import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -31,120 +23,96 @@ export namespace DeviceEnergyManagementMode { /** * These are optional features supported by DeviceEnergyManagementModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } export enum ModeTag { /** - * The device prohibits optimization of energy usage management: its energy usage is determined only by the - * user configuration and internal device needs. This tag cannot be included with any of the other tags defined - * below in a mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.6.5.1.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - NoOptimization = 16384, + Auto = 0, /** - * The device is permitted to manage its own energy usage. For example, using tariff information it may obtain. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.6.5.1.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - DeviceOptimization = 16385, + Quick = 1, /** - * The device permits management of energy usage by an energy manager to optimize the local energy usage. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.6.5.1.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - LocalOptimization = 16386, + Quiet = 2, /** - * The device permits management of energy usage by an energy manager to optimize the grid energy usage. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.6.5.1.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - GridOptimization = 16387, + LowNoise = 3, /** - * The device decides which options, features and setting values to use. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - Auto = 0, + LowEnergy = 4, /** - * The mode of the device is optimizing for faster completion. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - Quick = 1, + Vacation = 5, /** - * The device is silent or barely audible while in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - Quiet = 2, + Min = 6, /** - * Either the mode is inherently low noise or the device optimizes for that. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - LowNoise = 3, + Max = 7, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - LowEnergy = 4, + Night = 8, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1 */ - Vacation = 5, + Day = 9, /** - * The mode uses the lowest available setting value. + * The device prohibits optimization of energy usage management: its energy usage is determined only by the + * user configuration and internal device needs. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1.1 */ - Min = 6, + NoOptimization = 16384, /** - * The mode uses the highest available setting value. + * The device is permitted to manage its own energy usage. For example, using tariff information it may obtain. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1.2 */ - Max = 7, + DeviceOptimization = 16385, /** - * The mode is recommended or suitable for use during night time. + * The device permits management of energy usage by an energy manager to optimize the local energy usage. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1.3 */ - Night = 8, + LocalOptimization = 16386, /** - * The mode is recommended or suitable for use during day time. + * The device permits management of energy usage by an energy manager to optimize the grid energy usage. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.7.1.4 */ - Day = 9 + GridOptimization = 16387 } /** @@ -174,7 +142,7 @@ export namespace DeviceEnergyManagementMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -188,7 +156,7 @@ export namespace DeviceEnergyManagementMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * @see {@link MatterSpecification.v13.Cluster} § 9.6.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.5.1 */ export const TlvModeOption = TlvObject({ /** @@ -250,92 +218,53 @@ export namespace DeviceEnergyManagementMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * @see {@link MatterSpecification.v13.Cluster} § 9.6.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.5.1 */ export interface ModeOption extends TypeFromSchema {} - /** - * A DeviceEnergyManagementModeCluster supports these elements if it supports feature OnOff. - */ - export const OnOffComponent = MutableCluster.Component({ - attributes: { - /** - * Indicates whether the value of CurrentMode depends on the state of the On/Off cluster on the same - * endpoint. If this attribute is not present or is set to null, there is no dependency, otherwise the - * CurrentMode attribute shall depend on the OnOff attribute in the On/Off cluster - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.5 - */ - onMode: WritableAttribute(0x3, TlvNullable(TlvUInt8), { persistent: true, default: null }) - } - }); - /** * These elements and properties are present in all DeviceEnergyManagementMode clusters. */ export const Base = MutableCluster.Component({ id: 0x9f, name: "DeviceEnergyManagementMode", - revision: 1, + revision: 2, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * This attribute shall contain the list of supported modes that may be selected for the CurrentMode - * attribute. Each item in this list represents a unique mode as indicated by the Mode field of the - * ModeOptionStruct. + * At least one entry in the SupportedModes attribute shall include the NoOptimization mode tag in the + * ModeTags field. * - * Each entry in this list shall have a unique value for the Mode field. Each entry in this list shall have - * a unique value for the Label field. + * At least one entry in the SupportedModes attribute shall include the LocalOptimization mode tag in the + * ModeTags field list. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.2 - */ - supportedModes: FixedAttribute(0x0, TlvArray(TlvModeOption, { minLength: 2, maxLength: 255 })), - - /** - * Indicates the current mode of the server. - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. + * At least one entry in the SupportedModes attribute shall include the GridOptimization mode tag in the + * ModeTags field list. * - * The value of this attribute may change at any time via an out-of-band interaction outside of the server, - * such as interactions with a user interface, via internal mode changes due to autonomously progressing - * through a sequence of operations, on system time-outs or idle delays, or via interactions coming from a - * fabric other than the one which last executed a ChangeToMode. + * An entry in the SupportedModes attribute that includes one of an DeviceOptimization, LocalOptimization, + * or GridOptimization tags shall NOT also include NoOptimization tag. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.6.1 */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }), + supportedModes: FixedAttribute( + 0x0, + TlvArray(TlvModeOption, { minLength: 2, maxLength: 255 }), + { default: [] } + ), /** - * Indicates the desired startup mode for the server when it is supplied with power. - * - * If this attribute is not null, the CurrentMode attribute shall be set to the StartUpMode value, when the - * server is powered up, except in the case when the OnMode attribute overrides the StartUpMode attribute - * (see OnModeWithPowerUp). - * - * This behavior does not apply to reboots associated with OTA. After an OTA restart, the CurrentMode - * attribute shall return to its value prior to the restart. - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. - * - * If this attribute is not implemented, or is set to the null value, it shall have no effect. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.8.6 */ - startUpMode: OptionalWritableAttribute(0x2, TlvNullable(TlvUInt8), { persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, commands: { @@ -353,7 +282,7 @@ export namespace DeviceEnergyManagementMode { * This metadata controls which DeviceEnergyManagementModeCluster elements matter.js activates for specific * feature combinations. */ - extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: OnOffComponent }) + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -362,45 +291,18 @@ export namespace DeviceEnergyManagementMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced enumerated + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated * values for Device Energy Management devices. * - * NOTE Support for Device Energy Management Mode cluster is provisional. - * * DeviceEnergyManagementModeCluster supports optional features that you can enable with the * DeviceEnergyManagementModeCluster.with() factory method. * - * @see {@link MatterSpecification.v13.Cluster} § 9.6 + * @see {@link MatterSpecification.v13.Cluster} § 9.8 */ export interface Cluster extends Identity {} export const Cluster: Cluster = ClusterInstance; - const DEPONOFF = { onOff: true }; - - /** - * @see {@link Complete} - */ - export const CompleteInstance = MutableCluster({ - id: Cluster.id, - name: Cluster.name, - revision: Cluster.revision, - features: Cluster.features, - attributes: { - ...Cluster.attributes, - onMode: MutableCluster.AsConditional(OnOffComponent.attributes.onMode, { mandatoryIf: [DEPONOFF] }) - }, - commands: Cluster.commands - }); - - /** - * This cluster supports all DeviceEnergyManagementMode features. It may support illegal feature combinations. - * - * If you use this cluster you must manually specify which features are active and ensure the set of active - * features is legal per the Matter specification. - */ - export interface Complete extends Identity {} - - export const Complete: Complete = CompleteInstance; + export const Complete = Cluster; } export type DeviceEnergyManagementModeCluster = DeviceEnergyManagementMode.Cluster; diff --git a/packages/types/src/clusters/device-energy-management.ts b/packages/types/src/clusters/device-energy-management.ts index 681efe3c79..06fee77a30 100644 --- a/packages/types/src/clusters/device-energy-management.ts +++ b/packages/types/src/clusters/device-energy-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,8 +8,8 @@ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; import { Attribute, Command, TlvNoResponse, Event, EventPriority, FixedAttribute } from "../cluster/Cluster.js"; -import { TlvArray } from "../tlv/TlvArray.js"; import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js"; +import { TlvArray } from "../tlv/TlvArray.js"; import { TlvInt64, TlvUInt32, TlvEnum, TlvUInt16, TlvEpochS, TlvInt32, TlvUInt8, TlvInt8 } from "../tlv/TlvNumber.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; @@ -34,14 +34,15 @@ export namespace DeviceEnergyManagement { * curtail power requirements during peak periods, but can also be used to turn on an ESA if there is excess * renewable or local generation (Solar PV). * - * For example, a home may have solar PV which often produces more power than the home requires, - * - * resulting in the excess power flowing into the grid. This excess power naturally fluctuates when clouds pass - * overhead and other loads in the home are switched on and off. + * For example, a home may have solar PV which often produces more power than the home requires, resulting in + * the excess power flowing into the grid. This excess power naturally fluctuates when clouds pass overhead and + * other loads in the home are switched on and off. * * EVSE Example: An EMS may therefore be able to turn on the EVSE (if the vehicle is plugged in) and can start * charging the vehicle, and periodically modify the charging power depending on PV generation and other home - * loads, so as to minimize import and export to the grid. + * loads, so as to minimize import and export to the grid. An EMS may also use this feature to control the + * discharging (and re-charging) of the vehicle if the EVSE and vehicle support the V2X feature of the EVSE + * cluster of the associated EVSE device. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.4.1 */ @@ -139,8 +140,9 @@ export namespace DeviceEnergyManagement { /** * Pausable (PAU) * - * ESAs which support the Pausable feature, allow an EMS to recommend a pause in the middle of a forecast power - * profile that the ESA is currently using. + * ESAs which support the Pausable feature, allow an EMS to recommend a pause in the middle of a + * + * forecast power profile that the ESA is currently using. * * Washing machine example: A Washing Machine is in operation, and starting its water heating step. * @@ -197,8 +199,9 @@ export namespace DeviceEnergyManagement { * * ESAs which support the Constraint-Based Adjustment feature allow an EMS to inform the ESA of periods during * which power usage should be modified (for example when the EMS has been made aware that the grid supplier - * has requested reduced energy usage due to overall peak grid demand) and may cause the ESA to modify the - * intended power profile has previously suggested it would use. + * has requested reduced energy usage due to overall peak grid demand) + * + * and may cause the ESA to modify the intended power profile has previously suggested it would use. * * EVSE example: An EVSE scheduling system may have determined that the vehicle would be charged starting at a * moderate rate at 1am, so that it has enough charge by the time it is needed later that morning. @@ -206,9 +209,8 @@ export namespace DeviceEnergyManagement { * However, the DSR service provider has informed the EMS that due to high forecast winds it is now forecast * that there will be very cheap energy available from wind generation between 2am and 3am. * - * The EMS first requests the Forecast data from each of its registered ESAs. It determines that the - * - * EVSE has a power profile suggesting it plans to start charging the vehicle at 1am. + * The EMS first requests the Forecast data from each of its registered ESAs. It determines that the EVSE has a + * power profile suggesting it plans to start charging the vehicle at 1am. * * The EMS can then try to reduce the cost of charging the EV by informing the EVSE of the desire to increase * the charging between scheduled times. @@ -223,41 +225,37 @@ export namespace DeviceEnergyManagement { } /** - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10 */ export const TlvPowerAdjust = TlvObject({ /** * This field shall indicate the minimum power that the ESA can have its power adjusted to. * - * Note that this is a signed value. Negative values indicate power flows away from loads (e.g. charging a - * battery inverter). + * Note that this is a signed value. Negative values indicate power flows out of the node (e.g. discharging a + * battery). * - * MinPower shall be less than MaxPower. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.1 */ minPower: TlvField(0, TlvInt64), /** * This field shall indicate the maximum power that the ESA can have its power adjusted to. * - * Note that this is a signed value. Negative values indicate power flows away from loads (e.g. charging a - * battery inverter). - * - * MinPower shall be less than MaxPower. + * Note that this is a signed value. Negative values indicate power flows out of the node (e.g. discharging a + * battery). * * For example, if the charging current of an EVSE can be adjusted within the range of 6A to 32A on a 230V * supply, then the power adjustment range is between 1380W and 7360W. Here the MinPower would be 1380W, and * MaxPower would be 7360W. * - * For example, if a battery storage inverter can discharge between 0 to 3000W towards a load, then its - * MinPower would be 0W and its MaxPower would be 3000W. + * For example, if a battery storage inverter can discharge between 0 to 3000W towards a load, then power is + * flowing out of the node and is therefore negative. Its MinPower would be -3000W and its MaxPower would be 0W. * * In another example, if a battery storage inverter can charge its internal battery, between 0W and 2000W. - * Here power is flowing away from the home loads, so the power values need to be negative. As such the - * MinPower becomes -2000W and MaxPower becomes 0W. + * Here power is flowing into the node when charging. As such the MinPower becomes 0W and MaxPower becomes + * 2000W. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.2 */ maxPower: TlvField(1, TlvInt64), @@ -266,9 +264,7 @@ export namespace DeviceEnergyManagement { * adjustment. Manufacturers may use this to as an anti-cycling capability to avoid controllers from rapidly * making power adjustments. * - * Note that MinDuration shall be less than MaxDuration. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.3 */ minDuration: TlvField(2, TlvUInt32), @@ -277,18 +273,68 @@ export namespace DeviceEnergyManagement { * adjustment. Manufacturers may use this to protect the user experience, to avoid over heating of the ESA, * ensuring that there is sufficient headroom to use or store energy in the ESA or for any other reason. * - * Note that MinDuration shall be less than MaxDuration. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.4 */ maxDuration: TlvField(3, TlvUInt32) }); /** - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10 */ export interface PowerAdjust extends TypeFromSchema {} + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.8 + */ + export enum PowerAdjustReason { + /** + * There is no Power Adjustment active + */ + NoAdjustment = 0, + + /** + * There is PowerAdjustment active due to local EMS optimization + */ + LocalOptimizationAdjustment = 1, + + /** + * There is PowerAdjustment active due to local EMS optimization + */ + GridOptimizationAdjustment = 2 + } + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11 + */ + export const TlvPowerAdjustCapability = TlvObject({ + /** + * This field shall indicate how the ESA can be adjusted at the current time. + * + * For example, a battery storage inverter may need to regulate its internal temperature, or the charging rate + * of the battery may be limited due to cold temperatures, or a change in the state of charge of the battery + * may mean that the maximum charging or discharging rate is limited. + * + * An empty list shall indicate that no power adjustment is currently possible. + * + * Multiple entries in the list allow indicating that permutations of scenarios may be possible. + * + * For example, a 10kWh battery could be at 80% state of charge. If charging at 2kW, then it would be full in 1 + * hour. However, it could be discharged at 2kW for 4 hours. + * + * In this example the list of PowerAdjustStructs allows multiple scenarios to be offered as follows: + * + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.12 + */ + powerAdjustCapability: TlvField(0, TlvNullable(TlvArray(TlvPowerAdjust, { maxLength: 8 }))), + + cause: TlvField(1, TlvEnum()) + }); + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11 + */ + export interface PowerAdjustCapability extends TypeFromSchema {} + /** * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.6 */ @@ -398,9 +444,9 @@ export namespace DeviceEnergyManagement { /** * This field shall indicate the approximate energy used by the ESA during the session. * - * For example, if the ESA was on and was adjusted to be switched off, then this shall be 0W. If this was a - * battery inverter that was requested to charge it would have a negative energy use. If this was a normal load - * that was turned on, then it will have positive value. + * For example, if the ESA was on and was adjusted to be switched off, then this shall be 0 mWh. If this was a + * battery inverter that was requested to discharge it would have a negative EnergyUse value. If this was a + * normal load that was turned on, then it will have positive value. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.10.2.3 */ @@ -466,13 +512,13 @@ export namespace DeviceEnergyManagement { * This indicates a generic mechanism for expressing cost to run an appliance, in terms of financial, GHG * emissions, comfort value etc. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9 */ export const TlvCost = TlvObject({ /** * This field shall indicate the type of cost being represented (see CostTypeEnum). * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.8.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9.1 */ costType: TlvField(0, TlvEnum()), @@ -482,7 +528,7 @@ export namespace DeviceEnergyManagement { * * For example, if the Value was -302 and DecimalPoints was 2, then this would represent a benefit of 3.02. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.8.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9.2 */ value: TlvField(1, TlvInt32), @@ -490,7 +536,7 @@ export namespace DeviceEnergyManagement { * This field shall indicate the number of digits to the right of the decimal point in the Value field. For * example, if the Value was 102 and DecimalPoints was 2, then this would represent a cost of 1.02. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.8.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9.3 */ decimalPoints: TlvField(2, TlvUInt8), @@ -500,7 +546,7 @@ export namespace DeviceEnergyManagement { * * This is an optional field. It shall be included if CostType is Financial. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.8.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9.4 */ currency: TlvOptionalField(3, TlvUInt16.bound({ max: 999 })) }); @@ -509,34 +555,34 @@ export namespace DeviceEnergyManagement { * This indicates a generic mechanism for expressing cost to run an appliance, in terms of financial, GHG * emissions, comfort value etc. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.9 */ export interface Cost extends TypeFromSchema {} /** * This indicates a specific stage of an ESA’s operation. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14 */ export const TlvSlot = TlvObject({ /** * This field shall indicate the minimum time (in seconds) that the appliance expects to be in this slot for. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.1 */ minDuration: TlvField(0, TlvUInt32), /** * This field shall indicate the maximum time (in seconds) that the appliance expects to be in this slot for. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.2 */ maxDuration: TlvField(1, TlvUInt32), /** * This field shall indicate the expected time (in seconds) that the appliance expects to be in this slot for. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.3 */ defaultDuration: TlvField(2, TlvUInt32), @@ -550,7 +596,7 @@ export namespace DeviceEnergyManagement { * * When the Forecast attribute is read, then this value shall be the most recent value. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.4 */ elapsedSlotTime: TlvField(3, TlvUInt32), @@ -563,29 +609,34 @@ export namespace DeviceEnergyManagement { * When subscribed to, a change in this field value shall NOT cause the Forecast attribute to be updated, since * this value may change every 1 second. * - * Note that if the ESA is currently paused, then this value shall not change. + * Note that if the ESA is currently paused, then this value shall NOT change. * * When the Forecast attribute is read, then this value shall be the most recent value. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.5 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.5 */ remainingSlotTime: TlvField(4, TlvUInt32), - slotIsPauseable: TlvOptionalField(5, TlvBoolean), + /** + * This field shall indicate whether this slot can be paused. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.6 + */ + slotIsPausable: TlvOptionalField(5, TlvBoolean), /** * This field shall indicate the shortest period that the slot can be paused for. This can be set to avoid * controllers trying to pause ESAs for short periods and then resuming operation in a cyclic fashion which may * damage or cause excess energy to be consumed with restarting of an operation. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.7 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.7 */ minPauseDuration: TlvOptionalField(6, TlvUInt32), /** * This field shall indicate the longest period that the slot can be paused for. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.8 */ maxPauseDuration: TlvOptionalField(7, TlvUInt32), @@ -605,11 +656,11 @@ export namespace DeviceEnergyManagement { * NOTE An ESA shall always use the same value to represent the same operating state. * * By providing this information a smart EMS may be able to learn the observed power draw when the ESA is put - * into a specific state. It can potentially then use the information in the PowerForecastReporting data to - * predict the power draw from the appliance and potentially ask it to modify its timing via one of the - * adjustment request commands, or adjust other ESAs power to compensate. + * into a specific state. It can potentially then use the ManufacturerESAState field in the Forecast attribute + * along with observed power drawn to predict the power draw from the appliance and potentially ask it to + * modify its timing via one of the adjustment request commands, or adjust other ESAs power to compensate. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.9 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.9 */ manufacturerEsaState: TlvOptionalField(8, TlvUInt16), @@ -618,7 +669,7 @@ export namespace DeviceEnergyManagement { * considered the average value over the slot, and some variation from this would be expected (for example, as * it is ramping up). * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.10 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.10 */ nominalPower: TlvOptionalField(9, TlvInt64), @@ -628,7 +679,7 @@ export namespace DeviceEnergyManagement { * * Some appliances (e.g. battery inverters which can charge and discharge) may have a negative power. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.11 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.11 */ minPower: TlvOptionalField(10, TlvInt64), @@ -638,7 +689,7 @@ export namespace DeviceEnergyManagement { * * Some appliances (e.g. battery inverters which can charge and discharge) may have a negative power. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.12 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.12 */ maxPower: TlvOptionalField(11, TlvInt64), @@ -647,7 +698,7 @@ export namespace DeviceEnergyManagement { * * Some appliances (e.g. battery inverters which can charge and discharge) may have a negative energy. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.13 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.13 */ nominalEnergy: TlvOptionalField(12, TlvInt64), @@ -671,7 +722,7 @@ export namespace DeviceEnergyManagement { * If the ESA cannot calculate its cost for any reason (such as losing its connection to a Price server) it may * omit this field. This is treated as extra meta data that an EMS may use to optimize a system. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.14 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.14 */ costs: TlvOptionalField(13, TlvArray(TlvCost, { maxLength: 5 })), @@ -682,7 +733,7 @@ export namespace DeviceEnergyManagement { * If the slot indicates a NominalPower of 0W (indicating it is expecting to be off), this allows an ESA to * indicate it could be switched on to charge, but this would be the minimum power limit it can be set to. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.15 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.15 */ minPowerAdjustment: TlvOptionalField(14, TlvInt64), @@ -693,7 +744,7 @@ export namespace DeviceEnergyManagement { * the slot indicates a NominalPower of 0W (indicating it is expecting to be off), this allows an ESA to * indicate it could be switched on to charge, but this would be the maximum power limit it can be set to. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.16 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.16 */ maxPowerAdjustment: TlvOptionalField(15, TlvInt64), @@ -706,7 +757,7 @@ export namespace DeviceEnergyManagement { * * For example, a heat pump compressor may have a minimum cycle time of order a few minutes. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.17 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.17 */ minDurationAdjustment: TlvOptionalField(16, TlvUInt32), @@ -719,7 +770,7 @@ export namespace DeviceEnergyManagement { * which can be discharged, it may equally indicate the maximum time the battery could be discharged for (at * the MaxPowerAdjustment power level). * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11.18 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14.18 */ maxDurationAdjustment: TlvOptionalField(17, TlvUInt32) }); @@ -727,7 +778,7 @@ export namespace DeviceEnergyManagement { /** * This indicates a specific stage of an ESA’s operation. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.11 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.14 */ export interface Slot extends TypeFromSchema {} @@ -760,7 +811,7 @@ export namespace DeviceEnergyManagement { * * feature and instead report its internal state. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13 */ export const TlvForecast = TlvObject({ /** @@ -771,40 +822,39 @@ export namespace DeviceEnergyManagement { * previous subscriptions are lost if a device reboots. The loss of a subscription and subsequent * re-subscription allows the EMS to learn about any new forecasts. * - * The value of ForecastId is allowed to wrap. + * The value of ForecastID is allowed to wrap. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.1 */ - forecastId: TlvField(0, TlvUInt16), + forecastId: TlvField(0, TlvUInt32), /** * This field shall indicate which element of the Slots list is currently active in the Forecast sequence. A * null value indicates that the sequence has not yet started. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.2 */ activeSlotNumber: TlvField(1, TlvNullable(TlvUInt16)), /** * This field shall indicate the planned start time, in UTC, for the entire Forecast. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.3 */ startTime: TlvField(2, TlvEpochS), /** * This field shall indicate the planned end time, in UTC, for the entire Forecast. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.4 */ endTime: TlvField(3, TlvEpochS), /** - * This field shall indicate the earliest start time, in UTC, that the entire Forecast can be shifted to. - * - * A null value indicates that it can be started immediately. + * This field shall indicate the earliest start time, in UTC, that the entire Forecast can be shifted to. A + * null value indicates that it can be started immediately. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.5 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.5 */ earliestStartTime: TlvOptionalField(4, TlvNullable(TlvEpochS)), @@ -814,7 +864,7 @@ export namespace DeviceEnergyManagement { * e.g. for an EVSE charging session, this may indicate the departure time for the vehicle, by which time the * charging session must end. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.6 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.6 */ latestEndTime: TlvOptionalField(5, TlvEpochS), @@ -823,23 +873,23 @@ export namespace DeviceEnergyManagement { * this flag and if it is false, then none of the slots contain SlotIsPausable set to true. This can save a * client from having to check each slot in the list. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.7 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.7 */ - isPauseable: TlvField(6, TlvBoolean), + isPausable: TlvField(6, TlvBoolean), /** * This field shall contain a list of SlotStructs. * * It shall contain at least 1 entry, and a maximum of 10. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.8 */ slots: TlvField(7, TlvArray(TlvSlot, { maxLength: 10 })), /** * This field shall contain the reason the current Forecast was generated. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10.9 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.9 */ forecastUpdateReason: TlvField(8, TlvEnum()) }); @@ -853,7 +903,7 @@ export namespace DeviceEnergyManagement { * * feature and instead report its internal state. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.10 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13 */ export interface Forecast extends TypeFromSchema {} @@ -969,7 +1019,7 @@ export namespace DeviceEnergyManagement { export interface StartTimeAdjustRequest extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.12 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.15 */ export const TlvSlotAdjustment = TlvObject({ /** @@ -977,30 +1027,33 @@ export namespace DeviceEnergyManagement { * be less than the actual length of the Slots list (implicitly it must be in the range 0 to 9 based on the * maximum length of the Slots list constraint). * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.12.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.15.1 */ slotIndex: TlvField(0, TlvUInt8), /** * This field shall indicate the new requested power that the ESA shall operate at. It MUST be between the - * MinPowerAdjustment and MaxPowerAdjustment for the slot as advertised by the ESA. + * AbsMinPower and AbsMaxPower attributes as advertised by the ESA if it supports PFR. + * + * This is a signed value and can be used to indicate charging or discharging. If the ESA does NOT support PFR + * this value shall be ignored by the ESA. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.12.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.15.2 */ - nominalPower: TlvField(1, TlvInt64), + nominalPower: TlvOptionalField(1, TlvInt64), /** * This field shall indicate the new requested duration, in seconds, that the ESA shall extend or shorten the * slot duration to. It MUST be between the MinDurationAdjustment and MaxDurationAdjustment for the slot as * advertised by the ESA. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.12.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.15.3 */ duration: TlvField(2, TlvUInt32) }); /** - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.12 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.15 */ export interface SlotAdjustment extends TypeFromSchema {} @@ -1011,7 +1064,7 @@ export namespace DeviceEnergyManagement { */ export const TlvModifyForecastRequest = TlvObject({ /** - * This field shall indicate the ForecastId that is to be modified. + * This field shall indicate the ForecastID that is to be modified. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.9.6.1 */ @@ -1019,7 +1072,7 @@ export namespace DeviceEnergyManagement { /** * This field shall contain a list of SlotAdjustment parameters that should be modified in the corresponding - * Forecast with matching ForecastId. + * Forecast with matching ForecastID. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.9.6.2 */ @@ -1045,7 +1098,7 @@ export namespace DeviceEnergyManagement { * perhaps excess solar PV). The format allows the client to suggest that the ESA can either turn up its energy * consumption, or turn down its energy consumption during this period. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.16 */ export const TlvConstraints = TlvObject({ /** @@ -1054,26 +1107,25 @@ export namespace DeviceEnergyManagement { * * This value is in UTC and MUST be in the future. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.16.1 */ startTime: TlvField(0, TlvEpochS), /** * This field shall indicate the duration of the constraint in seconds. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.16.2 */ - duration: TlvField(1, TlvUInt32.bound({ min: 0, max: 86400 })), + duration: TlvField(1, TlvUInt32.bound({ max: 86400 })), /** * This field shall indicate the nominal power that client wishes the ESA to operate at during the constrained * period. It MUST be between the AbsMinPower and AbsMaxPower attributes as advertised by the ESA if it * supports PFR. * - * This is a signed value and can be used to indicate charging or discharging. If the ESA does NOT support PFR - * this value shall be ignored by the ESA. + * This is a signed value and can be used to indicate charging or discharging. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.16.3 */ nominalPower: TlvOptionalField(2, TlvInt64), @@ -1081,10 +1133,9 @@ export namespace DeviceEnergyManagement { * This field shall indicate the maximum energy that can be transferred to or from the ESA during the * constraint period. * - * This is a signed value and can be used to indicate charging or discharging. If the ESA does NOT support PFR - * this value may be ignored by the ESA. + * This is a signed value and can be used to indicate charging or discharging. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.16.4 */ maximumEnergy: TlvOptionalField(3, TlvInt64), @@ -1098,7 +1149,7 @@ export namespace DeviceEnergyManagement { * * Note that the mapping between values and operation is manufacturer specific. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13.5 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.16.5 */ loadControl: TlvOptionalField(4, TlvInt8) }); @@ -1108,7 +1159,7 @@ export namespace DeviceEnergyManagement { * perhaps excess solar PV). The format allows the client to suggest that the ESA can either turn up its energy * consumption, or turn down its energy consumption during this period. * - * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.13 + * @see {@link MatterSpecification.v13.Cluster} § 9.2.7.16 */ export interface Constraints extends TypeFromSchema {} @@ -1120,7 +1171,8 @@ export namespace DeviceEnergyManagement { export const TlvRequestConstraintBasedForecastRequest = TlvObject({ /** * This field shall indicate the series of turn up or turn down power requests that the ESA is being asked to - * constrain its operation within. + * constrain its operation within. These requests shall be in the future, shall be in chronological order, + * starting with the earliest start time, and shall NOT overlap in time. * * For example, a grid event which requires devices to reduce power (turn down) between 4pm and 6pm and due to * excess power on the grid overnight, may request ESAs to increase their power demand (turn up) between @@ -1129,8 +1181,9 @@ export namespace DeviceEnergyManagement { * If this ESA supports PFR this would have 2 entries in the list as follows: * * If this ESA supports SFR where it does not know the actual power, but has an understanding of the functions - * that use more energy, it could be requested to use more or less energy using the LoadControl field as - * follows: + * that use more energy, it could be requested to use more or less energy using the LoadCon + * + * trol field as follows: * * @see {@link MatterSpecification.v13.Cluster} § 9.2.9.7.1 */ @@ -1267,29 +1320,23 @@ export namespace DeviceEnergyManagement { export const PowerAdjustmentComponent = MutableCluster.Component({ attributes: { /** - * Indicates how the ESA can be adjusted at the current time. This attribute SHOULD be updated regularly by - * ESAs. + * Indicates how the ESA can be adjusted at the current time, and the state of any active adjustment. * - * For example, a battery storage inverter may need to regulate its internal temperature, or the charging - * rate of the battery may be limited due to cold temperatures, or a change in the state of charge of the - * battery may mean that the maximum charging or discharging rate is limited. + * A null value indicates that no power adjustment is currently possible, and nor is any adjustment + * currently active. * - * An empty list shall indicate that no power adjustment is currently possible. + * This attribute SHOULD be updated periodically by ESAs to reflect any changes in internal state, for + * example temperature or stored energy, which would affect the power or duration limits. * - * Multiple entries in the list allow to indicate that permutations of scenarios may be possible. + * Changes to this attribute shall only be marked as reportable in the following cases: * - * For example, a 10kWh battery could be at 80% state of charge. If charging at 2kW, then it would be full - * in 1 hour. However, it could be discharged at 2kW for 4 hours. + * • At most once every 10 seconds on changes, or * - * In this example the list of PowerAdjustStructs allows multiple scenarios to be offered as follows: + * • When it changes from null to any other value and vice versa. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.8.6 */ - powerAdjustmentCapability: Attribute( - 0x5, - TlvNullable(TlvArray(TlvPowerAdjust, { maxLength: 8 })), - { default: null } - ) + powerAdjustmentCapability: Attribute(0x5, TlvNullable(TlvPowerAdjustCapability), { default: null }) }, commands: { @@ -1335,13 +1382,23 @@ export namespace DeviceEnergyManagement { * This attribute allows an ESA to share its intended forecast with a client (such as an Energy Management * System). * - * A null value indicates that there is no forecast currently available - * - * yet been selected by the user). + * A null value indicates that there is no forecast currently available (for example, a program has not yet + * been selected by the user). * * A server may reset this value attribute to null on a reboot, and it does not need to persist any * previous forecasts. * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once every 10 seconds on changes, or + * + * • When it changes from null to any other value and vice versa, or + * + * • As a result of a command which causes the forecast to be updated, or + * + * • As a result of a change in the opt-out status which in turn may cause the ESA to recalculate its + * forecast. + * * @see {@link MatterSpecification.v13.Cluster} § 9.2.8.7 */ forecast: Attribute(0x6, TlvNullable(TlvForecast), { default: null }) @@ -1363,8 +1420,29 @@ export namespace DeviceEnergyManagement { * optimization reasons, it shall reject any commands which have the AdjustmentCauseEnum value * LocalOptimization. If the ESA is in the GridOptOut or OptOut states, so it cannot be controlled by an * EMS for grid optimization reasons, it shall reject any commands which have the AdjustmentCauseEnum value - * GridOptimization. If the ESA is in the LocalOptOut, GridOptOut, or NoOptOut states, the device is still - * permitted to optimize its own energy usage, for example, using tariff information it may obtain. + * GridOptimization. + * + * If the user changes the Opt-Out state of the ESA which is currently operating with a Forecast that is + * due to a previous StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast + * command that would now not be permitted due to the new Opt-out state + * + * attribute ForecastUpdateReason field currently contains a reason which is now opted out), the ESA shall + * behave as if it had received a CancelRequest command. + * + * If the user changes the Opt-Out state of the ESA which currently has the ESAStateEnum with value Paused + * due to a previous PauseRequest command that would now not be permitted due to the new Opt-out state, and + * the ESA supports the PFR or SFR features (i.e. the Forecast attribute ForecastUpdateReason field + * currently contains a reason which is now opted out), the ESA shall behave as if it had received a + * ResumeRequest command. + * + * If the user changes the Opt-Out state of the ESA which currently has the ESAStateEnum with value + * PowerAdjustActive due to a previous PowerAdjustRequest command that would now not be permitted due to + * the new Opt-out state (i.e. the Forecast attribute ForecastUpdateReason field currently contains a + * reason which is now opted out), the ESA shall behave as if it had received a CancelPowerAdjustRequest + * command. + * + * If the ESA is in the LocalOptOut, GridOptOut, or NoOptOut states, the device is still permitted to + * optimize its own energy usage, for example, using tariff information it may obtain. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.8.8 */ @@ -1474,7 +1552,7 @@ export namespace DeviceEnergyManagement { export const Base = MutableCluster.Component({ id: 0x98, name: "DeviceEnergyManagement", - revision: 3, + revision: 4, features: { /** @@ -1485,14 +1563,15 @@ export namespace DeviceEnergyManagement { * be to curtail power requirements during peak periods, but can also be used to turn on an ESA if there is * excess renewable or local generation (Solar PV). * - * For example, a home may have solar PV which often produces more power than the home requires, - * - * resulting in the excess power flowing into the grid. This excess power naturally fluctuates when clouds - * pass overhead and other loads in the home are switched on and off. + * For example, a home may have solar PV which often produces more power than the home requires, resulting + * in the excess power flowing into the grid. This excess power naturally fluctuates when clouds pass + * overhead and other loads in the home are switched on and off. * * EVSE Example: An EMS may therefore be able to turn on the EVSE (if the vehicle is plugged in) and can * start charging the vehicle, and periodically modify the charging power depending on PV generation and - * other home loads, so as to minimize import and export to the grid. + * other home loads, so as to minimize import and export to the grid. An EMS may also use this feature to + * control the discharging (and re-charging) of the vehicle if the EVSE and vehicle support the V2X feature + * of the EVSE cluster of the associated EVSE device. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.4.1 */ @@ -1592,8 +1671,9 @@ export namespace DeviceEnergyManagement { /** * Pausable * - * ESAs which support the Pausable feature, allow an EMS to recommend a pause in the middle of a forecast - * power profile that the ESA is currently using. + * ESAs which support the Pausable feature, allow an EMS to recommend a pause in the middle of a + * + * forecast power profile that the ESA is currently using. * * Washing machine example: A Washing Machine is in operation, and starting its water heating step. * @@ -1651,8 +1731,9 @@ export namespace DeviceEnergyManagement { * * ESAs which support the Constraint-Based Adjustment feature allow an EMS to inform the ESA of periods * during which power usage should be modified (for example when the EMS has been made aware that the grid - * supplier has requested reduced energy usage due to overall peak grid demand) and may cause the ESA to - * modify the intended power profile has previously suggested it would use. + * supplier has requested reduced energy usage due to overall peak grid demand) + * + * and may cause the ESA to modify the intended power profile has previously suggested it would use. * * EVSE example: An EVSE scheduling system may have determined that the vehicle would be charged starting * at a moderate rate at 1am, so that it has enough charge by the time it is needed later that morning. @@ -1660,9 +1741,8 @@ export namespace DeviceEnergyManagement { * However, the DSR service provider has informed the EMS that due to high forecast winds it is now * forecast that there will be very cheap energy available from wind generation between 2am and 3am. * - * The EMS first requests the Forecast data from each of its registered ESAs. It determines that the - * - * EVSE has a power profile suggesting it plans to start charging the vehicle at 1am. + * The EMS first requests the Forecast data from each of its registered ESAs. It determines that the EVSE + * has a power profile suggesting it plans to start charging the vehicle at 1am. * * The EMS can then try to reduce the cost of charging the EV by informing the EVSE of the desire to * increase the charging between scheduled times. @@ -1700,17 +1780,17 @@ export namespace DeviceEnergyManagement { * the power values reported by the ESA need to have their sign inverted when dealing with forecasts and * adjustments. * - * For example, a solar PV inverter (being a generator) may produce positive values to indicate generation, - * however an EMS when predicting the total home load would need to subtract these positive values from the - * loads to compute a net import at the grid meter. + * For example, a solar PV inverter (being a generator) may produce negative values to indicate generation + * (since power is flowing out of the node into the home), however a display showing the power to the + * consumers may need to present a positive solar production value to the consumer. * * For example, a home battery storage system (BESS) which needs to charge the battery and then discharge * to the home loads, would be classed as a generator. These types of devices shall have this field set to * true. When generating its forecast or advertising its PowerAdjustmentCapability, the power values shall - * be positive to indicate discharging to the loads in the home, and negative to indicate when it is + * be negative to indicate discharging to the loads in the home, and positive to indicate when it is * charging its battery. * - * GRID meter = Σ LoadPowers - Σ GeneratorPowers + * GRID meter = Σ LoadPowers + Σ GeneratorPowers * * Example: * @@ -1737,9 +1817,11 @@ export namespace DeviceEnergyManagement { * Indicates the minimum electrical power that the ESA can consume when switched on. This does not include * when in power save or standby modes. * - * Note that for Generator ESAs that can charge an internal battery (such as a battery storage inverter), - * the AbsMinPower will be a negative number representing the maximum power that the ESA can charge its - * internal battery. + * NOTE + * + * For Generator ESAs that can discharge an internal battery (such as a battery storage inverter) to loads + * in the home, the AbsMinPower will be a negative number representing the maximum power that the ESA can + * discharge its internal battery. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.8.4 */ @@ -1748,16 +1830,12 @@ export namespace DeviceEnergyManagement { /** * Indicates the maximum electrical power that the ESA can consume when switched on. * - * The value of the AbsMaxPower attribute shall be limited - * - * AbsMaxPower >= AbsMinPower - * - * Note that for Generator ESAs that can discharge a battery to loads in the home (such as a battery - * storage inverter), the AbsMaxPower will be a positive number representing the maximum power at which the - * ESA can discharge its internal battery. + * Note that for Generator ESAs that can charge a battery by importing power into the node (such as a + * battery storage inverter), the AbsMaxPower will be a positive number representing the maximum power at + * which the ESA can charge its internal battery. * * For example, a battery storage inverter that can charge its battery at a maximum power of 2000W and can - * discharge the battery at a maximum power of 3000W, would have a AbsMinPower: -2000, AbsMaxPower: 3000W. + * discharge the battery at a maximum power of 3000W, would have a AbsMinPower: -3000, AbsMaxPower: 2000W. * * @see {@link MatterSpecification.v13.Cluster} § 9.2.8.5 */ @@ -1814,34 +1892,9 @@ export namespace DeviceEnergyManagement { flags: { constraintBasedAdjustment: true }, component: StartTimeAdjustmentOrForecastAdjustmentOrConstraintBasedAdjustmentComponent }, - { flags: { feature: false, startTimeAdjustment: true, stateForecastReporting: false }, component: false }, - { flags: { feature: false, pausable: true, stateForecastReporting: false }, component: false }, - { flags: { feature: false, forecastAdjustment: true, stateForecastReporting: false }, component: false }, - { - flags: { feature: false, constraintBasedAdjustment: true, stateForecastReporting: false }, - component: false - }, - { flags: { feature: false, startTimeAdjustment: true, powerForecastReporting: false }, component: false }, - { flags: { feature: false, pausable: true, powerForecastReporting: false }, component: false }, - { flags: { feature: false, forecastAdjustment: true, powerForecastReporting: false }, component: false }, - { - flags: { feature: false, constraintBasedAdjustment: true, powerForecastReporting: false }, - component: false - }, - - { - flags: { - powerAdjustment: false, - powerForecastReporting: false, - stateForecastReporting: false, - startTimeAdjustment: false, - pausable: false, - forecastAdjustment: false, - constraintBasedAdjustment: false - }, - - component: false - } + { flags: { staTrue: true, pauTrue: false, faTrue: false, conTrue: false }, component: false }, + { flags: { powerForecastReporting: true, stateForecastReporting: true }, component: false }, + { flags: { powerForecastReporting: false, stateForecastReporting: false }, component: false } ) }); @@ -1851,12 +1904,14 @@ export namespace DeviceEnergyManagement { export const ClusterInstance = MutableCluster.ExtensibleOnly(Base); /** - * This cluster allows a client to manage the power draw of a device. An example of such a client could be an - * Energy Management System (EMS) which controls an Energy Smart Appliance (ESA). + * This cluster allows a client to manage the power draw of a device. An example of such a client could + * + * be an Energy Management System (EMS) which controls an Energy Smart Appliance (ESA). * - * In most deployments the EMS will be the client, and the ESA will host the Energy Management Cluster server. + * In most deployments the EMS will be the client, and the ESA will host the Device Energy Management Cluster + * server. * - * Figure 15. Example of the how an EMS is a client of multiple ESAs Energy Management clusters. + * Figure 17. Example of the how an EMS is a client of multiple ESAs Device Energy Management clusters. * * This cluster is intended to be generic in nature and could apply to any electrical load or generator (e.g. a * Battery Electric Storage System - BESS, solar PV inverter, EVSE, HVAC, heat pump, hot water heater, white goods @@ -1884,7 +1939,7 @@ export namespace DeviceEnergyManagement { * intensity', 'time of use' or 'type of use' tariffs to schedule its operation to run at the cheapest and greenest * times. * - * Figure 16. Example of the how an HVAC may use multiple clusters + * Figure 18. Example of the how an HVAC may use multiple clusters * * NOTE * @@ -1896,8 +1951,6 @@ export namespace DeviceEnergyManagement { * Different markets may follow different approaches, but the UK [PAS1878] and [EUCodeOfConduct] give examples of * how ESAs may be mandated to support these features in the future. * - * NOTE Support of Device Energy Management Cluster is provisional. - * * Per the Matter specification you cannot use {@link DeviceEnergyManagementCluster} without enabling certain * feature combinations. You must use the {@link with} factory method to obtain a working cluster. * diff --git a/packages/types/src/clusters/diagnostic-logs.ts b/packages/types/src/clusters/diagnostic-logs.ts index 75daae8e10..bbbb5261ca 100644 --- a/packages/types/src/clusters/diagnostic-logs.ts +++ b/packages/types/src/clusters/diagnostic-logs.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/dishwasher-alarm.ts b/packages/types/src/clusters/dishwasher-alarm.ts index f57cfd50c2..600c544a4e 100644 --- a/packages/types/src/clusters/dishwasher-alarm.ts +++ b/packages/types/src/clusters/dishwasher-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -120,10 +120,9 @@ export namespace DishwasherAlarm { * alarm shall respond with a status code of FAILURE; otherwise the server shall respond with a status code of * SUCCESS. * - * On a SUCCESS case, the server shall also change the value of the Mask attribute to the value of the - * - * Mask field from this command. After that the server shall also update the value of its State attribute to - * reflect the status of the new alarm set as indicated by the new value of the Mask attribute. + * On a SUCCESS case, the server shall also change the value of the Mask attribute to the value of the Mask + * field from this command. After that the server shall also update the value of its State attribute to reflect + * the status of the new alarm set as indicated by the new value of the Mask attribute. * * @see {@link MatterSpecification.v13.Cluster} § 1.15.7.2.1 */ @@ -284,7 +283,8 @@ export namespace DishwasherAlarm { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is a derived cluster of the Alarm Base cluster. + * This cluster is a derived cluster of the Alarm Base cluster and provides the alarm definition related to + * dishwasher devices. * * DishwasherAlarmCluster supports optional features that you can enable with the DishwasherAlarmCluster.with() * factory method. diff --git a/packages/types/src/clusters/dishwasher-mode.ts b/packages/types/src/clusters/dishwasher-mode.ts index 84ca6483b1..3777446ad3 100644 --- a/packages/types/src/clusters/dishwasher-mode.ts +++ b/packages/types/src/clusters/dishwasher-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,14 +8,14 @@ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; import { BitFlag } from "../schema/BitmapSchema.js"; -import { FixedAttribute, Attribute, WritableAttribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; +import { FixedAttribute, Attribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -23,111 +23,88 @@ export namespace DishwasherMode { /** * These are optional features supported by DishwasherModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } export enum ModeTag { /** - * The normal regime of operation. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.3.6.1.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - Normal = 16384, + Auto = 0, /** - * Mode optimized for washing heavily-soiled dishes. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.3.6.1.2 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - Heavy = 16385, + Quick = 1, /** - * Mode optimized for light washing. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.3.6.1.3 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - Light = 16386, + Quiet = 2, /** - * The device decides which options, features and setting values to use. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - Auto = 0, + LowNoise = 3, /** - * The mode of the device is optimizing for faster completion. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - Quick = 1, + LowEnergy = 4, /** - * The device is silent or barely audible while in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - Quiet = 2, + Vacation = 5, /** - * Either the mode is inherently low noise or the device optimizes for that. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - LowNoise = 3, + Min = 6, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - LowEnergy = 4, + Max = 7, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - Vacation = 5, + Night = 8, /** - * The mode uses the lowest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1 */ - Min = 6, + Day = 9, /** - * The mode uses the highest available setting value. + * The normal regime of operation. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1.1 */ - Max = 7, + Normal = 16384, /** - * The mode is recommended or suitable for use during night time. + * Mode optimized for washing heavily-soiled dishes. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1.2 */ - Night = 8, + Heavy = 16385, /** - * The mode is recommended or suitable for use during day time. + * Mode optimized for light washing. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.7.1.3 */ - Day = 9 + Light = 16386 } /** @@ -157,7 +134,7 @@ export namespace DishwasherMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -171,9 +148,7 @@ export namespace DishwasherMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags field list. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.3.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.5.1 */ export const TlvModeOption = TlvObject({ /** @@ -235,9 +210,7 @@ export namespace DishwasherMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags field list. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.3.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.5.1 */ export interface ModeOption extends TypeFromSchema {} @@ -247,23 +220,23 @@ export namespace DishwasherMode { export const Base = MutableCluster.Component({ id: 0x59, name: "DishwasherMode", - revision: 2, + revision: 3, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * @see {@link MatterSpecification.v13.Cluster} § 8.3.5 + * At least one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags + * field list. + * + * @see {@link MatterSpecification.v13.Cluster} § 8.3.6.1 */ supportedModes: FixedAttribute( 0x0, @@ -272,23 +245,9 @@ export namespace DishwasherMode { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 8.3.5 - */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }), - - /** - * If this attribute is supported, the device SHOULD initially set this to one of the supported modes that - * has the Normal tag associated with it. See the Mode Base cluster specification for full details about - * the StartUpMode attribute. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.3.5.1 - */ - startUpMode: WritableAttribute(0x2, TlvUInt8, { persistent: true }), - - /** - * @see {@link MatterSpecification.v13.Cluster} § 8.3.5 + * @see {@link MatterSpecification.v13.Cluster} § 8.3.6 */ - onMode: WritableAttribute(0x3, TlvUInt8, { persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, commands: { @@ -306,7 +265,7 @@ export namespace DishwasherMode { * This metadata controls which DishwasherModeCluster elements matter.js activates for specific feature * combinations. */ - extensions: MutableCluster.Extensions() + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -315,7 +274,7 @@ export namespace DishwasherMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced enumerated + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated * values for dishwasher devices. * * DishwasherModeCluster supports optional features that you can enable with the DishwasherModeCluster.with() diff --git a/packages/types/src/clusters/door-lock.ts b/packages/types/src/clusters/door-lock.ts index a3d703ce07..f2fa73407f 100644 --- a/packages/types/src/clusters/door-lock.ts +++ b/packages/types/src/clusters/door-lock.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,23 +13,23 @@ import { Event, EventPriority, FixedAttribute, - WritableAttribute, Command, TlvNoResponse, + WritableAttribute, OptionalCommand, OptionalAttribute } from "../cluster/Cluster.js"; -import { TlvEnum, TlvUInt32, TlvUInt16, TlvEpochS, TlvUInt8, TlvBitmap } from "../tlv/TlvNumber.js"; +import { TlvEnum, TlvUInt32, TlvUInt16, TlvUInt8, TlvBitmap, TlvEpochS } from "../tlv/TlvNumber.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; import { AccessLevel } from "#model"; import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; -import { TlvBoolean } from "../tlv/TlvBoolean.js"; -import { TlvByteString, TlvString } from "../tlv/TlvString.js"; import { BitFlag, BitsFromPartial } from "../schema/BitmapSchema.js"; +import { TlvString, TlvByteString } from "../tlv/TlvString.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvFabricIndex } from "../datatype/FabricIndex.js"; import { Status } from "../globals/Status.js"; +import { TlvBoolean } from "../tlv/TlvBoolean.js"; import { TlvNodeId } from "../datatype/NodeId.js"; import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; import { ClusterType } from "../cluster/ClusterType.js"; @@ -63,9 +63,8 @@ export namespace DoorLock { * User. * * A lock may support multiple credential types so if the User feature is supported the UserType, UserStatus - * and Schedules are all associated with a User index and not directly with a RFID index. A User - * - * Index may have several credentials associated with it. + * and Schedules are all associated with a User index and not directly with a RFID index. A User Index may have + * several credentials associated with it. * * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.2 */ @@ -87,27 +86,19 @@ export namespace DoorLock { */ FingerCredentials = "FingerCredentials", - /** - * Logging (LOG) - * - * If Events are not supported the logging feature shall replace the Event reporting structure. If Events are - * supported the logging feature shall NOT be supported. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.4 - */ - Logging = "Logging", - /** * WeekDayAccessSchedules (WDSCH) * * If the User feature is supported then Week Day Schedules are applied to a User and not a credential. * * Week Day Schedules are used to restrict access to a specified time window on certain days of the week. The - * schedule is repeated each week. When a schedule is cleared this clears the access restrictions and grants - * unrestricted access to the user. The lock may automatically adjust the UserType when a schedule is created - * or cleared. + * schedule is repeated each week. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.5 + * The lock may automatically adjust the UserType when a schedule is created or cleared. + * + * Support for WeekDayAccessSchedules requires that the lock has the capability of keeping track of local time. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.4 */ WeekDayAccessSchedules = "WeekDayAccessSchedules", @@ -117,7 +108,7 @@ export namespace DoorLock { * If this feature is supported this indicates that the lock has the ability to determine the position of the * door which is separate from the state of the lock. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.5 */ DoorPositionSensor = "DoorPositionSensor", @@ -132,7 +123,7 @@ export namespace DoorLock { * A lock may support multiple credential types so if the User feature is supported the UserType, UserStatus * and Schedules are all associated with a User and not directly with a credential. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.6 */ FaceCredentials = "FaceCredentials", @@ -140,10 +131,11 @@ export namespace DoorLock { * CredentialOverTheAirAccess (COTA) * * If this feature is supported then the lock supports the ability to verify a credential provided in a + * * lock/unlock command. Currently the cluster only supports providing the PIN credential to the lock/unlock * commands. If this feature is supported then the PIN Credential feature shall also be supported. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.8 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.7 */ CredentialOverTheAirAccess = "CredentialOverTheAirAccess", @@ -154,30 +146,21 @@ export namespace DoorLock { * used to associate credentials and schedules to single user record within the lock. This also means the * UserType and UserStatus fields are associated with a User and not a credential. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.9 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.8 */ User = "User", - /** - * Notification (NOT) - * - * This is a feature used before support of events. This feature supports notification commands and masks used - * to filter these notifications. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.10 - */ - Notification = "Notification", - /** * YearDayAccessSchedules (YDSCH) * - * If the User feature is supported then Year Day Schedules are applied to a User and not a credential. + * If the User feature is supported then Year Day Schedules are applied to a User and not a credential. Year + * Day Schedules are used to restrict access to a specified date and time window. * - * Year Day Schedules are used to restrict access to a specified date and time window. When a schedule is - * cleared this clears the access restrictions and grants unrestricted access to the user. The lock may - * automatically adjust the UserType when a schedule is created or cleared. + * The lock may automatically adjust the UserType when a schedule is created or cleared. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.11 + * Support for YearDayAccessSchedules requires that the lock has the capability of keeping track of local time. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.9 */ YearDayAccessSchedules = "YearDayAccessSchedules", @@ -187,7 +170,9 @@ export namespace DoorLock { * This feature is used to setup Holiday Schedule in the lock device. A Holiday Schedule sets a start and stop * end date/time for the lock to use the specified operating mode set by the Holiday Schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.12 + * Support for HolidaySchedules requires that the lock has the capability of keeping track of local time. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.10 */ HolidaySchedules = "HolidaySchedules", @@ -200,15 +185,34 @@ export namespace DoorLock { * Locks without unbolting support don’t differentiate between unbolting and unlocking and perform the same * operation for both commands. * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.11 + */ + Unbolting = "Unbolting", + + /** + * AliroProvisioning (ALIRO) + * + * Locks that support this feature implement the Aliro specification as defined in [Aliro] and support Matter + * as a method for provisioning Aliro credentials. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.12 + */ + AliroProvisioning = "AliroProvisioning", + + /** + * AliroBleuwb (ALBU) + * + * Locks that support this feature implement the Bluetooth LE + UWB Access Control Flow as defined in [Aliro]. + * * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.13 */ - Unbolting = "Unbolting" + AliroBleuwb = "AliroBleuwb" } /** * This enumeration shall indicate the current door state. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.12 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.11 */ export enum DoorState { /** @@ -263,142 +267,6 @@ export namespace DoorLock { */ export interface DoorStateChangeEvent extends TypeFromSchema {} - /** - * Input to the DoorLock getLogRecord command - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4 - */ - export const TlvGetLogRecordRequest = TlvObject({ logIndex: TlvField(0, TlvUInt16) }); - - /** - * Input to the DoorLock getLogRecord command - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4 - */ - export interface GetLogRecordRequest extends TypeFromSchema {} - - /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.24 - */ - export enum EventType { - /** - * Event type is operation - */ - Operation = 0, - - /** - * Event type is programming - */ - Programming = 1, - - /** - * Event type is alarm - */ - Alarm = 2 - } - - /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.25 - */ - export enum EventSource { - /** - * Event source is keypad - */ - Keypad = 0, - - /** - * Event source is remote - */ - Remote = 1, - - /** - * Event source is manual - */ - Manual = 2, - - /** - * Event source is RFID - */ - Rfid = 3, - - /** - * Event source is unknown - */ - Indeterminate = 255 - } - - /** - * Returns the specified log record. If an invalid log entry ID was requested, it is set to 0 and the most recent - * log entry will be returned. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5 - */ - export const TlvGetLogRecordResponse = TlvObject({ - /** - * This field shall indicate the index into the log table where this log entry is stored. If the log entry - * requested is 0, the most recent log is returned with the appropriate log entry ID. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5.1 - */ - logEntryId: TlvField(0, TlvUInt16), - - /** - * This field shall indicate the timestamp for all events and alarms on the door lock in Epoch Time in Seconds - * with local time offset based on the local timezone and DST offset on the day of the event. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5.2 - */ - timestamp: TlvField(1, TlvEpochS), - - /** - * This field shall indicate the type of event that took place on the door lock, as defined in EventTypeEnum. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5.3 - */ - eventType: TlvField(2, TlvEnum()), - - /** - * This field shall indicate the source value as defined in EventSourceEnum. - * - * If the EventType is 2 (Alarm) then the source SHOULD be, but does not have to be 255 (Indeterminate). - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5.4 - */ - source: TlvField(3, TlvEnum()), - - /** - * This field shall indicate the type of event that took place on the door lock depending on the event code - * table provided for a given event type and source. See Operation Event Codes. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5.5 - */ - eventId: TlvField(4, TlvUInt8), - - /** - * This field shall indicate the ID of the user who generated the event on the door lock if one is available. - * Otherwise, the value is 0xFFFF. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5.6 - */ - userId: TlvField(5, TlvUInt16), - - /** - * This field shall indicate the PIN code or RFID code that was used to create the event on the door lock if - * one is available. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5.7 - */ - pin: TlvField(6, TlvByteString) - }); - - /** - * Returns the specified log record. If an invalid log entry ID was requested, it is set to 0 and the most recent - * log entry will be returned. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5 - */ - export interface GetLogRecordResponse extends TypeFromSchema {} - /** * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.2 */ @@ -422,7 +290,7 @@ export namespace DoorLock { /** * This enumeration shall indicate the data operation performed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.11 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.10 */ export enum DataOperationType { /** @@ -444,7 +312,7 @@ export namespace DoorLock { /** * This enumeration shall indicate what the status is for a specific user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.17 */ export enum UserStatus { /** @@ -466,7 +334,7 @@ export namespace DoorLock { /** * This enumeration shall indicate what the type is for a specific user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18 */ export enum UserType { /** @@ -474,7 +342,7 @@ export namespace DoorLock { * * This value shall indicate the user has access 24/7 provided proper PIN or RFID is supplied (e.g., owner). * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.1 */ UnrestrictedUser = 0, @@ -483,7 +351,15 @@ export namespace DoorLock { * * This value shall indicate the user has the ability to open lock within a specific time period (e.g., guest). * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.2 + * When UserType is set to YearDayScheduleUser, user access shall be restricted as follows: + * + * • If no YearDaySchedules are set for the user, then access shall be denied + * + * • If one or more YearDaySchedules are set, user access shall be granted if and only if the current time + * falls within at least one of the YearDaySchedules. If current time is not known, user access shall NOT + * be granted. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.2 */ YearDayScheduleUser = 1, @@ -493,7 +369,15 @@ export namespace DoorLock { * This value shall indicate the user has the ability to open lock based on specific time period within a * reoccurring weekly schedule (e.g., cleaning worker). * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.3 + * When UserType is set to WeekDayScheduleUser, user access shall be restricted as follows: + * + * • If no WeekDaySchedules are set for the user, then access shall be denied + * + * • If one or more WeekDaySchedules are set, user access shall be granted if and only if the current time + * falls within at least one of the WeekDaySchedules. If current time is not known, user access shall NOT + * be granted. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.3 */ WeekDayScheduleUser = 2, @@ -504,7 +388,7 @@ export namespace DoorLock { * manage the users and user schedules. In all other respects this user matches the unrestricted (default) * user. ProgrammingUser is the only user that can disable the user interface (keypad, remote, etc…). * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.4 */ ProgrammingUser = 3, @@ -514,7 +398,7 @@ export namespace DoorLock { * This value shall indicate the user is recognized by the lock but does not have the ability to open the lock. * This user will only cause the lock to generate the appropriate event notification to any bound devices. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.5 */ NonAccessUser = 4, @@ -525,7 +409,7 @@ export namespace DoorLock { * ForcedUser silent alarm will be emitted to allow a notified Node to alert emergency services or contacts on * the user account when used. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.6 */ ForcedUser = 5, @@ -535,7 +419,7 @@ export namespace DoorLock { * This value shall indicate the user has the ability to open lock once after which the lock shall change the * corresponding user record UserStatus value to OccupiedDisabled automatically. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.7 */ DisposableUser = 6, @@ -547,16 +431,29 @@ export namespace DoorLock { * minutes the corresponding user record UserStatus value shall be set to OccupiedDisabled automatically by the * lock. The lock shall persist the timeout across reboots such that the ExpiringUserTimeout is honored. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.8 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.8 */ ExpiringUser = 7, /** * The user ID type is schedule restricted * - * This value shall indicate the user access is restricted by Week Day and/or Year Day schedule. + * This value shall indicate the user access is restricted by Week Day and/or Year Day schedule. When UserType + * is set to ScheduleRestrictedUser, user access shall be restricted as follows: + * + * • If no WeekDaySchedules and no YearDaySchedules are set for the user, then access shall be denied * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.9 + * • If one or more WeekDaySchedules are set, but no YearDaySchedules are set for the user, then user access + * shall be equivalent to the WeekDayScheduleUser UserType + * + * • If one or more YearDaySchedules are set, but no WeekDaySchedules are set for the user, then user access + * shall be equivalent to the YearDayScheduleUser UserType + * + * • If one or WeekDaySchedules are set AND one or more YearDaySchedules are set, then user access shall be + * granted if and only if the current time falls within at least one of the WeekDaySchedules AND the + * current time falls within at least one of the YearDaySchedules. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.9 */ ScheduleRestrictedUser = 8, @@ -568,7 +465,7 @@ export namespace DoorLock { * prevent a PIN code credential created for them from being used at the keypad. The PIN code credential would * only be provided over-the-air for the lock/unlock commands. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19.10 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.18.10 */ RemoteOnlyUser = 9 } @@ -576,7 +473,7 @@ export namespace DoorLock { /** * This enumeration shall indicate the credential rule that can be applied to a particular user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.9 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.8 */ export enum CredentialRule { /** @@ -598,20 +495,20 @@ export namespace DoorLock { /** * Input to the DoorLock setUser command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32 */ export const TlvSetUserRequest = TlvObject({ /** * This field shall indicate the type of operation. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32.1 */ operationType: TlvField(0, TlvEnum()), /** * This field shall indicate the user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32.2 */ userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })), @@ -626,7 +523,7 @@ export namespace DoorLock { * * If UserName is not null, the UserName in the user record shall be set to the provided value. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32.3 */ userName: TlvField(2, TlvNullable(TlvString.bound({ maxLength: 10 }))), @@ -644,7 +541,7 @@ export namespace DoorLock { * * If UserUniqueID is not null, the UserUniqueID in the user record shall be set to the provided value. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32.4 */ userUniqueId: TlvField(3, TlvNullable(TlvUInt32)), @@ -660,7 +557,7 @@ export namespace DoorLock { * * If UserStatus is not null, the UserStatus in the user record shall be set to the provided value. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32.5 */ userStatus: TlvField(4, TlvNullable(TlvEnum())), @@ -676,7 +573,7 @@ export namespace DoorLock { * * If UserType is not null, the UserType in the user record shall be set to the provided value. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32.6 */ userType: TlvField(5, TlvNullable(TlvEnum())), @@ -696,7 +593,7 @@ export namespace DoorLock { * * If CredentialRule is not null, the CredentialRule in the user record shall be set to the provided value. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32.7 */ credentialRule: TlvField(6, TlvNullable(TlvEnum())) }); @@ -704,28 +601,28 @@ export namespace DoorLock { /** * Input to the DoorLock setUser command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32 */ export interface SetUserRequest extends TypeFromSchema {} /** * Input to the DoorLock getUser command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.33 */ export const TlvGetUserRequest = TlvObject({ userIndex: TlvField(0, TlvUInt16.bound({ min: 1 })) }); /** * Input to the DoorLock getUser command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.33 */ export interface GetUserRequest extends TypeFromSchema {} /** * This enumeration shall indicate the credential type. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.10 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.9 */ export enum CredentialType { /** @@ -756,20 +653,81 @@ export namespace DoorLock { /** * Face identifier credential type */ - Face = 5 + Face = 5, + + /** + * A Credential Issuer public key as defined in [Aliro] + * + * Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in section + * 2.3.3 of SEC 1. + * + * Credentials of this type shall NOT be used to allow operating the lock. They shall be used, as defined in + * [Aliro], to create new credentials of type AliroEvictableEndpointKey via a step-up transaction. + * + * When performing the step-up transaction, the lock shall request the data element with identifier "matter1", + * and shall attempt to create a new credential of type AliroEvictableEndpointKey if and only if the data + * element is returned and the Access Credential can be validated using the AliroCredentialIssuerKey. + * + * When a new credential of type AliroEvictableEndpointKey is added in this manner, it shall be associated with + * the same user record as the AliroCredentialIssuerKey credential that allowed the new credential to be added. + * + * If there are no available credential slots to add a new AliroEvictableEndpointKey credential (i.e. either + * the NumberOfCredentialsSupportedPerUser or the NumberOfAliroEndpointKeysSupported limit has been reached) + * but there exist credentials of type AliroEvictableEndpointKey associated with the user record, the server + * shall remove one of those credentials using the same procedure it would follow for the ClearCredential + * command before adding the new credential. + * + * If there are no available credential slots to add a new AliroEvictableEndpointKey credential (i.e. either + * the NumberOfCredentialsSupportedPerUser or the NumberOfAliroEndpointKeysSupported limit has been reached) + * and there do not exist credentials of type AliroEvictableEndpointKey associated with the user record, a new + * AliroEvictableEndpointKey credential shall NOT be created. + * + * If the step-up process results in addition of new credentials, the corresponding LockUserChange event shall + * have OperationSource set to Aliro. + * + * If the step-up process results in the lock state changing (e.g. locking or unlocking), the credential + * associated with those changes in the LockOperation events shall be the newly provisioned + * AliroEvictableEndpointKey credential if one was created. If no new AliroEvictableEndpointKey credential was + * created, the credential associated with the changes in the LockOperation events shall be the + * AliroCredentialIssuerKey credential used for the step-up. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.9.1 + */ + AliroCredentialIssuerKey = 6, + + /** + * An Endpoint public key as defined in [Aliro] which can be evicted if space is needed for another endpoint key + * + * Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in section + * 2.3.3 of SEC 1. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.9.2 + */ + AliroEvictableEndpointKey = 7, + + /** + * An Endpoint public key as defined in [Aliro] which cannot be evicted if space is needed for another endpoint + * key + * + * Credentials of this type shall be 65-byte uncompressed elliptic curve public keys as defined in section + * 2.3.3 of SEC 1. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.9.3 + */ + AliroNonEvictableEndpointKey = 8 } /** * This struct shall indicate the credential types and their corresponding indices (if any) for the event or user * record. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.26 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.24 */ export const TlvCredential = TlvObject({ /** * This field shall indicate the credential field used to authorize the lock operation. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.26.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.24.1 */ credentialType: TlvField(0, TlvEnum()), @@ -778,7 +736,7 @@ export namespace DoorLock { * list of credentials identified by CredentialType (e.g. PIN, RFID, etc.). This field shall be set to 0 if * CredentialType is ProgrammingPIN or does not correspond to a list that can be indexed into. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.26.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.24.2 */ credentialIndex: TlvField(1, TlvUInt16) }); @@ -787,7 +745,7 @@ export namespace DoorLock { * This struct shall indicate the credential types and their corresponding indices (if any) for the event or user * record. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.26 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.24 */ export interface Credential extends TypeFromSchema {} @@ -798,55 +756,55 @@ export namespace DoorLock { * UserUniqueID, UserStatus, UserType, CredentialRule, Credentials, CreatorFabricIndex, and LastModifiedFabricIndex * shall all be null in the response. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34 */ export const TlvGetUserResponse = TlvObject({ /** * This field shall indicate the user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.1 */ userIndex: TlvField(0, TlvUInt16.bound({ min: 1 })), /** * This field shall contain a string to use as a human readable identifier for the user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.2 */ userName: TlvField(1, TlvNullable(TlvString.bound({ maxLength: 10 }))), /** * See UserUniqueID field. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.3 */ userUniqueId: TlvField(2, TlvNullable(TlvUInt32)), /** * This field shall indicate the UserStatus assigned to the user when created or modified. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.4 */ userStatus: TlvField(3, TlvNullable(TlvEnum())), /** * This field shall indicate the UserType assigned to this user when created or modified. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.5 */ userType: TlvField(4, TlvNullable(TlvEnum())), /** * This field shall indicate the CredentialRule set for this user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.6 */ credentialRule: TlvField(5, TlvNullable(TlvEnum())), /** * This field shall contain a list of credentials for this user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.7 */ credentials: TlvField(6, TlvNullable(TlvArray(TlvCredential, { minLength: 0 }))), @@ -856,7 +814,7 @@ export namespace DoorLock { * the Interaction Model) and shall NOT be null otherwise. This value shall be set to 0 if the original creator * fabric was deleted. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.8 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.8 */ creatorFabricIndex: TlvField(7, TlvNullable(TlvFabricIndex)), @@ -866,7 +824,7 @@ export namespace DoorLock { * modified outside the Interaction Model) and shall NOT be null otherwise. This value shall be set to 0 if the * last modifier fabric was deleted. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.9 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.9 */ lastModifiedFabricIndex: TlvField(8, TlvNullable(TlvFabricIndex)), @@ -876,7 +834,7 @@ export namespace DoorLock { * entry after the requested UserIndex in the User database and shall be null if there are no more occupied * entries. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.10 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34.10 */ nextUserIndex: TlvField(9, TlvNullable(TlvUInt16.bound({ min: 1 }))) }); @@ -888,20 +846,20 @@ export namespace DoorLock { * UserUniqueID, UserStatus, UserType, CredentialRule, Credentials, CreatorFabricIndex, and LastModifiedFabricIndex * shall all be null in the response. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34 */ export interface GetUserResponse extends TypeFromSchema {} /** * Input to the DoorLock clearUser command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35 */ export const TlvClearUserRequest = TlvObject({ /** * This field shall specify a valid User index or 0xFFFE to indicate all user slots shall be cleared. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35.1 */ userIndex: TlvField(0, TlvUInt16) }); @@ -909,20 +867,20 @@ export namespace DoorLock { /** * Input to the DoorLock clearUser command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35 */ export interface ClearUserRequest extends TypeFromSchema {} /** * Input to the DoorLock setCredential command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36 */ export const TlvSetCredentialRequest = TlvObject({ /** * This field shall indicate the set credential operation type requested. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.1 */ operationType: TlvField(0, TlvEnum()), @@ -930,7 +888,7 @@ export namespace DoorLock { * This field shall contain a credential structure that contains the CredentialTypeEnum and the credential * index (if applicable or 0 if not) to set. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.2 */ credential: TlvField(1, TlvCredential), @@ -939,7 +897,7 @@ export namespace DoorLock { * of the credential data shall conform to the limits of the CredentialType specified in the Credential * structure otherwise an INVALID_COMMAND status shall be returned in the SetCredentialResponse command. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.3 */ credentialData: TlvField(2, TlvByteString), @@ -948,7 +906,7 @@ export namespace DoorLock { * or modified. This shall be null if OperationType is add and a new credential and user is being added at the * same time. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.4 */ userIndex: TlvField(3, TlvNullable(TlvUInt16.bound({ min: 1 }))), @@ -956,7 +914,7 @@ export namespace DoorLock { * This field shall indicate the user status to use in the new user record if a new user is being created. This * shall be null if OperationType is Modify. This may be null when adding a new credential and user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.5 */ userStatus: TlvField(4, TlvNullable(TlvEnum())), @@ -964,7 +922,7 @@ export namespace DoorLock { * This field shall indicate the user type to use in the new user record if a new user is being created. This * shall be null if OperationType is Modify. This may be null when adding a new credential and user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36.6 */ userType: TlvField(5, TlvNullable(TlvEnum())) }); @@ -972,14 +930,14 @@ export namespace DoorLock { /** * Input to the DoorLock setCredential command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36 */ export interface SetCredentialRequest extends TypeFromSchema {} /** * Returns the status for setting the specified credential. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37 */ export const TlvSetCredentialResponse = TlvObject({ /** @@ -997,8 +955,15 @@ export namespace DoorLock { * • DUPLICATE, if CredentialData provided is a duplicate of another credential with the same CredentialType * (e.g. duplicate PIN code). * - * • RESOURCE_EXHAUSTED, if OperationType is Add and the user referred to by UserIndex already has - * NumberOfCredentialsSupportedPerUser credentials associated. + * • RESOURCE_EXHAUSTED, if OperationType is Add and the new credential cannot be added due to resource + * constraints such as: + * + * ◦ The user referred to by UserIndex already has NumberOfCredentialsSupportedPerUser credentials + * associated. + * + * ◦ The credential is of type AliroEvictableEndpointKey or AliroNonEvictableEndpointKey, and adding it + * would cause the total number of credentials of those two types to exceed + * NumberOfAliroEndpointKeysSupported. * * • INVALID_COMMAND, if one or more fields violate constraints or are invalid. * @@ -1007,7 +972,7 @@ export namespace DoorLock { * * • INVALID_COMMAND, if OperationType is Modify and UserIndex points to an available slot. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37.1 */ status: TlvField(0, TlvEnum()), @@ -1018,7 +983,7 @@ export namespace DoorLock { * created. If the OperationType was Add and an existing User was associated with the new credential then this * shall be null. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37.2 */ userIndex: TlvField(1, TlvNullable(TlvUInt16.bound({ min: 1 }))), @@ -1029,7 +994,7 @@ export namespace DoorLock { * be null if there are no more available entries. The NextCredentialIndex reported shall NOT exceed the * maximum number of credentials for a particular credential type. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37.3 */ nextCredentialIndex: TlvOptionalField(2, TlvNullable(TlvUInt16)) }); @@ -1037,21 +1002,21 @@ export namespace DoorLock { /** * Returns the status for setting the specified credential. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37 */ export interface SetCredentialResponse extends TypeFromSchema {} /** * Input to the DoorLock getCredentialStatus command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.38 */ export const TlvGetCredentialStatusRequest = TlvObject({ /** * This field shall contain a credential structure that contains the CredentialTypeEnum and the credential * index (if applicable or 0 if not) to retrieve the status for. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.38.1 */ credential: TlvField(0, TlvCredential) }); @@ -1059,21 +1024,21 @@ export namespace DoorLock { /** * Input to the DoorLock getCredentialStatus command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.38 */ export interface GetCredentialStatusRequest extends TypeFromSchema {} /** * Returns the status for the specified credential. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.39 */ export const TlvGetCredentialStatusResponse = TlvObject({ /** * This field shall indicate if the requested credential type and index exists and is populated for the * requested user index. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.39.1 */ credentialExists: TlvField(0, TlvBoolean), @@ -1082,7 +1047,7 @@ export namespace DoorLock { * CredentialType requested was ProgrammingPIN then UserIndex shall be null; otherwise, UserIndex shall be null * if CredentialExists is set to False and shall NOT be null if CredentialExists is set to True. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.39.2 */ userIndex: TlvField(1, TlvNullable(TlvUInt16.bound({ min: 1 }))), @@ -1092,7 +1057,7 @@ export namespace DoorLock { * credential was created outside the Interaction Model) and shall NOT be null otherwise. This value shall be * set to 0 if the original creator fabric was deleted. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.39.3 */ creatorFabricIndex: TlvField(2, TlvNullable(TlvFabricIndex)), @@ -1102,33 +1067,54 @@ export namespace DoorLock { * credential was modified outside the Interaction Model) and shall NOT be null otherwise. This value shall be * set to 0 if the last modifier fabric was deleted. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.39.4 */ lastModifiedFabricIndex: TlvField(3, TlvNullable(TlvFabricIndex)), /** * This field shall indicate the next occupied index in the database for the credential type requested, which * is useful for quickly identifying occupied credential slots in the database. This shall NOT be null if there - * is at least one occupied entry after the requested credential index in the corresponding database and shall - * be null if there are no more occupied entries. The NextCredentialIndex reported shall NOT exceed the maximum - * number of credentials for a particular credential type. + * is at least one occupied entry after the requested credential index in the corresponding + * + * database and shall be null if there are no more occupied entries. The NextCredentialIndex reported shall NOT + * exceed the maximum number of credentials for a particular credential type. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.39.5 + */ + nextCredentialIndex: TlvOptionalField(4, TlvNullable(TlvUInt16)), + + /** + * This field shall indicate the credential data for the requested user index. + * + * If the CredentialType in the GetCredentialStatus command was not AliroCredentialIssuerKey, + * AliroEvictableEndpointKey, or AliroNonEvictableEndpointKey, this field shall NOT be included. + * + * Otherwise, if CredentialExists is false this field shall be null. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43.5 + * Otherwise, the value of this field shall be the value of the relevant credential, as a 65-byte uncompressed + * elliptic curve public key as defined in section 2.3.3 of SEC 1. + * + * NOTE + * + * Since the Aliro credentials are public keys, there is no security risk in allowing them to be read. + * Possession of the credential octet string does not allow operating the lock. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.39.6 */ - nextCredentialIndex: TlvOptionalField(4, TlvNullable(TlvUInt16)) + credentialData: TlvOptionalField(5, TlvNullable(TlvByteString)) }); /** * Returns the status for the specified credential. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.39 */ export interface GetCredentialStatusResponse extends TypeFromSchema {} /** * Input to the DoorLock clearCredential command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.44 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40 */ export const TlvClearCredentialRequest = TlvObject({ /** @@ -1136,7 +1122,7 @@ export namespace DoorLock { * index (0xFFFE for all credentials or 0 if not applicable) to clear. This shall be null if clearing all * credential types otherwise it shall NOT be null. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.44.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40.1 */ credential: TlvField(0, TlvNullable(TlvCredential)) }); @@ -1144,14 +1130,14 @@ export namespace DoorLock { /** * Input to the DoorLock clearCredential command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.44 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40 */ export interface ClearCredentialRequest extends TypeFromSchema {} /** * This enumeration shall indicate the data type that is being or has changed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.13 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.12 */ export enum LockDataType { /** @@ -1207,13 +1193,28 @@ export namespace DoorLock { /** * Lock user face information was added, cleared, or modified. */ - Face = 10 + Face = 10, + + /** + * An Aliro credential issuer key credential was added, cleared, or modified. + */ + AliroCredentialIssuerKey = 11, + + /** + * An Aliro endpoint key credential which can be evicted credential was added, cleared, or modified. + */ + AliroEvictableEndpointKey = 12, + + /** + * An Aliro endpoint key credential which cannot be evicted was added, cleared, or modified. + */ + AliroNonEvictableEndpointKey = 13 } /** * This enumeration shall indicate the source of the Lock/Unlock or user change operation performed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.17 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.16 */ export enum OperationSource { /** @@ -1264,7 +1265,13 @@ export namespace DoorLock { /** * Lock/unlock operation came from biometric source (e.g. face, fingerprint/fingervein) */ - Biometric = 9 + Biometric = 9, + + /** + * Lock/unlock operation came from an interaction defined in [Aliro], or user change operation was a step-up + * credential provisioning as defined in [Aliro] + */ + Aliro = 10 } /** @@ -1384,36 +1391,41 @@ export namespace DoorLock { /** * Input to the DoorLock setWeekDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12 */ export const TlvSetWeekDayScheduleRequest = TlvObject({ /** * This field shall indicate the index of the Week Day schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12.1 */ weekDayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })), - userIndexUserId: TlvField(1, TlvUInt16.bound({ min: 1 })), + /** + * This field shall indicate the user ID. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12.2 + */ + userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })), /** * This field shall indicate which week days the schedule is active. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12.3 */ daysMask: TlvField(2, TlvBitmap(TlvUInt8, DaysMask)), /** * This field shall indicate the starting hour for the Week Day schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12.4 */ startHour: TlvField(3, TlvUInt8.bound({ max: 23 })), /** * This field shall indicate the starting minute for the Week Day schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12.5 */ startMinute: TlvField(4, TlvUInt8.bound({ max: 59 })), @@ -1421,7 +1433,7 @@ export namespace DoorLock { * This field shall indicate the ending hour for the Week Day schedule. EndHour shall be equal to or greater * than StartHour. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12.6 */ endHour: TlvField(5, TlvUInt8.bound({ max: 23 })), @@ -1432,7 +1444,7 @@ export namespace DoorLock { * If the EndHour is equal to 23 and the EndMinute is equal to 59 the Lock shall grant access to the user up * until 23:59:59. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12.7 */ endMinute: TlvField(6, TlvUInt8.bound({ max: 59 })) }); @@ -1440,43 +1452,46 @@ export namespace DoorLock { /** * Input to the DoorLock setWeekDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12 */ export interface SetWeekDayScheduleRequest extends TypeFromSchema {} /** * Input to the DoorLock getWeekDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.13 */ export const TlvGetWeekDayScheduleRequest = TlvObject({ weekDayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })), - userIndexUserId: TlvField(1, TlvUInt16.bound({ min: 1 })) + userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })) }); /** * Input to the DoorLock getWeekDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.13 */ export interface GetWeekDayScheduleRequest extends TypeFromSchema {} /** * Returns the weekly repeating schedule data for the specified schedule index. * - * † The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, respectively. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14 */ export const TlvGetWeekDayScheduleResponse = TlvObject({ /** * This field shall indicate the index of the Week Day schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.1 */ weekDayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })), - userIndexUserId: TlvField(1, TlvUInt16.bound({ min: 1 })), + /** + * This field shall indicate the user ID. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.2 + */ + userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })), /** * Status shall be one of the following values: @@ -1492,7 +1507,7 @@ export namespace DoorLock { * If this field is SUCCESS, the optional fields for this command shall be present. For other (error) status * values, only the fields up to the status field shall be present. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.3 */ status: TlvField(2, TlvEnum()), @@ -1501,14 +1516,14 @@ export namespace DoorLock { /** * This field shall indicate the starting hour for the Week Day schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.4 */ startHour: TlvOptionalField(4, TlvUInt8.bound({ max: 23 })), /** * This field shall indicate the starting minute for the Week Day schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.5 */ startMinute: TlvOptionalField(5, TlvUInt8.bound({ max: 59 })), @@ -1516,7 +1531,7 @@ export namespace DoorLock { * This field shall indicate the ending hour for the Week Day schedule. EndHour shall be equal to or greater * than StartHour. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.6 */ endHour: TlvOptionalField(6, TlvUInt8.bound({ max: 23 })), @@ -1524,7 +1539,7 @@ export namespace DoorLock { * This field shall indicate the ending minute for the Week Day schedule. If EndHour is equal to StartHour then * EndMinute shall be greater than StartMinute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14.7 */ endMinute: TlvOptionalField(7, TlvUInt8.bound({ max: 59 })) }); @@ -1532,56 +1547,64 @@ export namespace DoorLock { /** * Returns the weekly repeating schedule data for the specified schedule index. * - * † The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, respectively. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14 */ export interface GetWeekDayScheduleResponse extends TypeFromSchema {} /** * Input to the DoorLock clearWeekDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15 */ export const TlvClearWeekDayScheduleRequest = TlvObject({ /** * This field shall indicate the Week Day schedule index to clear or 0xFE to clear all Week Day schedules for * the specified user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15.1 */ weekDayIndex: TlvField(0, TlvUInt8), - userIndexUserId: TlvField(1, TlvUInt16.bound({ min: 1 })) + /** + * This field shall indicate the user ID. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15.2 + */ + userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })) }); /** * Input to the DoorLock clearWeekDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15 */ export interface ClearWeekDayScheduleRequest extends TypeFromSchema {} /** * Input to the DoorLock setYearDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16 */ export const TlvSetYearDayScheduleRequest = TlvObject({ /** * This field shall indicate the index of the Year Day schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.1 */ yearDayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })), - userIndexUserId: TlvField(1, TlvUInt16.bound({ min: 1 })), + /** + * This field shall indicate the user ID. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.2 + */ + userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })), /** * This field shall indicate the starting time for the Year Day schedule in Epoch Time in Seconds with local * time offset based on the local timezone and DST offset on the day represented by the value. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.3 */ localStartTime: TlvField(2, TlvEpochS), @@ -1590,7 +1613,7 @@ export namespace DoorLock { * offset based on the local timezone and DST offset on the day represented by the value. LocalEndTime shall be * greater than LocalStartTime. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16.4 */ localEndTime: TlvField(3, TlvEpochS) }); @@ -1598,43 +1621,46 @@ export namespace DoorLock { /** * Input to the DoorLock setYearDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16 */ export interface SetYearDayScheduleRequest extends TypeFromSchema {} /** * Input to the DoorLock getYearDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17 */ export const TlvGetYearDayScheduleRequest = TlvObject({ yearDayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })), - userIndexUserId: TlvField(1, TlvUInt16.bound({ min: 1 })) + userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })) }); /** * Input to the DoorLock getYearDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17 */ export interface GetYearDayScheduleRequest extends TypeFromSchema {} /** * Returns the year day schedule data for the specified schedule and user indexes. * - * † The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, respectively. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18 */ export const TlvGetYearDayScheduleResponse = TlvObject({ /** * This field shall indicate the index of the Year Day schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18.1 */ yearDayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })), - userIndexUserId: TlvField(1, TlvUInt16.bound({ min: 1 })), + /** + * This field shall indicate the user ID. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18.2 + */ + userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })), /** * Status shall be one of the following values: @@ -1650,7 +1676,7 @@ export namespace DoorLock { * If this field is SUCCESS, the optional fields for this command shall be present. For other (error) status * values, only the fields up to the status field shall be present. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18.3 */ status: TlvField(2, TlvEnum()), @@ -1659,7 +1685,7 @@ export namespace DoorLock { * time offset based on the local timezone and DST offset on the day represented by the value. This shall be * null if the schedule is not set for the YearDayIndex and UserIndex provided. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18.4 */ localStartTime: TlvOptionalField(2, TlvEpochS), @@ -1669,7 +1695,7 @@ export namespace DoorLock { * greater than LocalStartTime. This shall be null if the schedule is not set for the YearDayIndex and * UserIndex provided. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18.5 */ localEndTime: TlvOptionalField(3, TlvEpochS) }); @@ -1677,33 +1703,36 @@ export namespace DoorLock { /** * Returns the year day schedule data for the specified schedule and user indexes. * - * † The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, respectively. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18 */ export interface GetYearDayScheduleResponse extends TypeFromSchema {} /** * Input to the DoorLock clearYearDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19 */ export const TlvClearYearDayScheduleRequest = TlvObject({ /** * This field shall indicate the Year Day schedule index to clear or 0xFE to clear all Year Day schedules for * the specified user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19.1 */ yearDayIndex: TlvField(0, TlvUInt8), - userIndexUserId: TlvField(1, TlvUInt16.bound({ min: 1 })) + /** + * This field shall indicate the user ID. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19.2 + */ + userIndex: TlvField(1, TlvUInt16.bound({ min: 1 })) }); /** * Input to the DoorLock clearYearDaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19 */ export interface ClearYearDayScheduleRequest extends TypeFromSchema {} @@ -1721,20 +1750,20 @@ export namespace DoorLock { * door lock shall NOT disable the radio or otherwise unbind or leave the network. It shall still respond to all * other commands and requests. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.16 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.15 */ export enum OperatingMode { /** * The lock operates normally. All interfaces are enabled. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.16.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.15.1 */ Normal = 0, /** * Only remote interaction is enabled. The keypad shall only be operable by the master user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.16.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.15.2 */ Vacation = 1, @@ -1743,7 +1772,7 @@ export namespace DoorLock { * mode. All external interaction with the door lock is disabled. This mode is intended to be used so that * users, presumably inside the property, will have control over the entrance. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.16.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.15.3 */ Privacy = 2, @@ -1752,7 +1781,7 @@ export namespace DoorLock { * means of communication. It specifically applies to the Lock, Unlock, Toggle, and Unlock with Timeout * Commands. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.16.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.15.4 */ NoRemoteLockUnlock = 3, @@ -1760,7 +1789,7 @@ export namespace DoorLock { * The lock is open or can be opened or closed at will without the use of a Keypad or other means of user * validation (e.g. a lock for a business during work hours). * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.16.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.15.5 */ Passage = 4 } @@ -1768,13 +1797,13 @@ export namespace DoorLock { /** * Input to the DoorLock setHolidaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20 */ export const TlvSetHolidayScheduleRequest = TlvObject({ /** * This field shall indicate the index of the Holiday schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20.1 */ holidayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })), @@ -1782,7 +1811,7 @@ export namespace DoorLock { * This field shall indicate the starting time for the Holiday Day schedule in Epoch Time in Seconds with local * time offset based on the local timezone and DST offset on the day represented by the value. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20.2 */ localStartTime: TlvField(1, TlvEpochS), @@ -1791,14 +1820,14 @@ export namespace DoorLock { * time offset based on the local timezone and DST offset on the day represented by the value. LocalEndTime * shall be greater than LocalStartTime. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20.3 */ localEndTime: TlvField(2, TlvEpochS), /** * This field shall indicate the operating mode to use during this Holiday schedule start/end time. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20.4 */ operatingMode: TlvField(3, TlvEnum()) }); @@ -1806,36 +1835,34 @@ export namespace DoorLock { /** * Input to the DoorLock setHolidaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20 */ export interface SetHolidayScheduleRequest extends TypeFromSchema {} /** * Input to the DoorLock getHolidaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21 */ export const TlvGetHolidayScheduleRequest = TlvObject({ holidayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })) }); /** * Input to the DoorLock getHolidaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21 */ export interface GetHolidayScheduleRequest extends TypeFromSchema {} /** * Returns the Holiday Schedule Entry for the specified Holiday ID. * - * † The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22 */ export const TlvGetHolidayScheduleResponse = TlvObject({ /** * This field shall indicate the index of the Holiday schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.1 */ holidayIndex: TlvField(0, TlvUInt8.bound({ min: 1 })), @@ -1854,7 +1881,7 @@ export namespace DoorLock { * If this field is SUCCESS, the optional fields for this command shall be present. For other (error) status * values, only the fields up to the status field shall be present. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.2 */ status: TlvField(1, TlvEnum()), @@ -1863,7 +1890,7 @@ export namespace DoorLock { * time offset based on the local timezone and DST offset on the day represented by the value. This shall be * null if the schedule is not set for the HolidayIndex provided. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.3 */ localStartTime: TlvOptionalField(2, TlvNullable(TlvEpochS)), @@ -1872,7 +1899,7 @@ export namespace DoorLock { * offset based on the local timezone and DST offset on the day represented by the value. LocalEndTime shall be * greater than LocalStartTime. This shall be null if the schedule is not set for the HolidayIndex provided. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.4 */ localEndTime: TlvOptionalField(3, TlvNullable(TlvEpochS)), @@ -1880,7 +1907,7 @@ export namespace DoorLock { * This field shall indicate the operating mode to use during this Holiday schedule start/end time. This shall * be null if the schedule is not set for the HolidayIndex provided. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22.5 */ operatingMode: TlvOptionalField(4, TlvNullable(TlvEnum())) }); @@ -1888,22 +1915,20 @@ export namespace DoorLock { /** * Returns the Holiday Schedule Entry for the specified Holiday ID. * - * † The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22 */ export interface GetHolidayScheduleResponse extends TypeFromSchema {} /** * Input to the DoorLock clearHolidaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23 */ export const TlvClearHolidayScheduleRequest = TlvObject({ /** * This field shall indicate the Holiday schedule index to clear or 0xFE to clear all Holiday schedules. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23.1 */ holidayIndex: TlvField(0, TlvUInt8) }); @@ -1911,21 +1936,21 @@ export namespace DoorLock { /** * Input to the DoorLock clearHolidaySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23 */ export interface ClearHolidayScheduleRequest extends TypeFromSchema {} /** * Input to the DoorLock setPinCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4 */ export const TlvSetPinCodeRequest = TlvObject({ /** * This field shall indicate the user ID. The value of the UserID field shall be between 0 and the value of the * NumberOfPINUsersSupported attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.6.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4.1 */ userId: TlvField(0, TlvUInt16), @@ -1933,7 +1958,7 @@ export namespace DoorLock { * This field shall indicate the user status. Only the values 1 (Occupied/Enabled) and 3 (Occupied/Disabled) * are allowed for UserStatus. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.6.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4.2 */ userStatus: TlvField(1, TlvNullable(TlvEnum())), @@ -1944,21 +1969,21 @@ export namespace DoorLock { /** * Input to the DoorLock setPinCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4 */ export interface SetPinCodeRequest extends TypeFromSchema {} /** * Input to the DoorLock getPinCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5 */ export const TlvGetPinCodeRequest = TlvObject({ /** * This field shall indicate the user ID. The value of the UserID field shall be between 0 and the value of the * NumberOfPINUsersSupported attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5.1 */ userId: TlvField(0, TlvUInt16) }); @@ -1966,7 +1991,7 @@ export namespace DoorLock { /** * Input to the DoorLock getPinCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5 */ export interface GetPinCodeRequest extends TypeFromSchema {} @@ -1982,427 +2007,107 @@ export namespace DoorLock { * to CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and NOT_FOUND if greater than * or equal to the max number of users supported. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.6 */ export const TlvGetPinCodeResponse = TlvObject({ - userId: TlvField(0, TlvUInt16), - userStatus: TlvField(1, TlvNullable(TlvEnum())), - userType: TlvField(2, TlvNullable(TlvEnum())), - pinCode: TlvField(3, TlvNullable(TlvByteString)) - }); - - /** - * Returns the PIN for the specified user ID. - * - * If the requested UserID is valid and the Code doesn’t exist, Get RFID Code Response shall have the following - * format: - * - * UserID = requested User ID UserStatus = 0 (Available) UserType = Null (Not supported) PINCode = 0 (zero length) - * - * If the requested UserID is invalid, send Default Response with an error status. The error status shall be equal - * to CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and NOT_FOUND if greater than - * or equal to the max number of users supported. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.8 - */ - export interface GetPinCodeResponse extends TypeFromSchema {} - - /** - * Input to the DoorLock clearPinCode command - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9 - */ - export const TlvClearPinCodeRequest = TlvObject({ - /** - * This field shall specify a valid PIN code slot index or 0xFFFE to indicate all PIN code slots shall be - * cleared. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9.1 - */ - pinSlotIndex: TlvField(0, TlvUInt16) - }); - - /** - * Input to the DoorLock clearPinCode command - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9 - */ - export interface ClearPinCodeRequest extends TypeFromSchema {} - - /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.7 - */ - export const EventMask = { - /** - * State of bit 0 - */ - bit0: BitFlag(0), - - /** - * State of bit 1 - */ - bit1: BitFlag(1), - - /** - * State of bit 2 - */ - bit2: BitFlag(2), - - /** - * State of bit 3 - */ - bit3: BitFlag(3), - - /** - * State of bit 4 - */ - bit4: BitFlag(4), - - /** - * State of bit 5 - */ - bit5: BitFlag(5), - - /** - * State of bit 6 - */ - bit6: BitFlag(6), - - /** - * State of bit 7 - */ - bit7: BitFlag(7), - - /** - * State of bit 8 - */ - bit8: BitFlag(8), - - /** - * State of bit 9 - */ - bit9: BitFlag(9), - - /** - * State of bit 10 - */ - bit10: BitFlag(10), - - /** - * State of bit 11 - */ - bit11: BitFlag(11), - - /** - * State of bit 12 - */ - bit12: BitFlag(12), - - /** - * State of bit 13 - */ - bit13: BitFlag(13), - - /** - * State of bit 14 - */ - bit14: BitFlag(14), - - /** - * State of bit 15 - */ - bit15: BitFlag(15) - }; - - /** - * The value of the DoorLock keypadProgrammingEventMask attribute - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.45 - */ - export const KeypadProgrammingEventMask = { - unknown: BitFlag(0), - pinCodeChanged: BitFlag(1), - pinAdded: BitFlag(2), - pinCleared: BitFlag(3), - pinChanged: BitFlag(4), - - /** - * State of bit 0 - */ - bit0: BitFlag(0), - - /** - * State of bit 1 - */ - bit1: BitFlag(1), - - /** - * State of bit 2 - */ - bit2: BitFlag(2), - - /** - * State of bit 3 - */ - bit3: BitFlag(3), - - /** - * State of bit 4 - */ - bit4: BitFlag(4), - - /** - * State of bit 5 - */ - bit5: BitFlag(5), - - /** - * State of bit 6 - */ - bit6: BitFlag(6), - - /** - * State of bit 7 - */ - bit7: BitFlag(7), - - /** - * State of bit 8 - */ - bit8: BitFlag(8), - - /** - * State of bit 9 - */ - bit9: BitFlag(9), - - /** - * State of bit 10 - */ - bit10: BitFlag(10), - - /** - * State of bit 11 - */ - bit11: BitFlag(11), - - /** - * State of bit 12 - */ - bit12: BitFlag(12), - - /** - * State of bit 13 - */ - bit13: BitFlag(13), - - /** - * State of bit 14 - */ - bit14: BitFlag(14), - - /** - * State of bit 15 - */ - bit15: BitFlag(15) - }; - - /** - * The value of the DoorLock remoteProgrammingEventMask attribute - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.46 - */ - export const RemoteProgrammingEventMask = { - unknown: BitFlag(0), - pinAdded: BitFlag(2), - pinCleared: BitFlag(3), - pinChanged: BitFlag(4), - rfidCodeAdded: BitFlag(5), - rfidCodeCleared: BitFlag(6), - - /** - * State of bit 0 - */ - bit0: BitFlag(0), - - /** - * State of bit 1 - */ - bit1: BitFlag(1), - - /** - * State of bit 2 - */ - bit2: BitFlag(2), - - /** - * State of bit 3 - */ - bit3: BitFlag(3), - - /** - * State of bit 4 - */ - bit4: BitFlag(4), - - /** - * State of bit 5 - */ - bit5: BitFlag(5), - - /** - * State of bit 6 - */ - bit6: BitFlag(6), - - /** - * State of bit 7 - */ - bit7: BitFlag(7), - - /** - * State of bit 8 - */ - bit8: BitFlag(8), - - /** - * State of bit 9 - */ - bit9: BitFlag(9), - - /** - * State of bit 10 - */ - bit10: BitFlag(10), - - /** - * State of bit 11 - */ - bit11: BitFlag(11), - - /** - * State of bit 12 - */ - bit12: BitFlag(12), - - /** - * State of bit 13 - */ - bit13: BitFlag(13), - - /** - * State of bit 14 - */ - bit14: BitFlag(14), - - /** - * State of bit 15 - */ - bit15: BitFlag(15) - }; + userId: TlvField(0, TlvUInt16), + userStatus: TlvField(1, TlvNullable(TlvEnum())), + userType: TlvField(2, TlvNullable(TlvEnum())), + pinCode: TlvField(3, TlvNullable(TlvByteString)) + }); /** - * The value of the DoorLock rfidProgrammingEventMask attribute + * Returns the PIN for the specified user ID. + * + * If the requested UserID is valid and the Code doesn’t exist, Get RFID Code Response shall have the following + * format: + * + * UserID = requested User ID UserStatus = 0 (Available) UserType = Null (Not supported) PINCode = 0 (zero length) + * + * If the requested UserID is invalid, send Default Response with an error status. The error status shall be equal + * to CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and NOT_FOUND if greater than + * or equal to the max number of users supported. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.47 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.6 */ - export const RfidProgrammingEventMask = { - unknown: BitFlag(0), - idAdded: BitFlag(5), - idCleared: BitFlag(6), - - /** - * State of bit 0 - */ - bit0: BitFlag(0), - - /** - * State of bit 1 - */ - bit1: BitFlag(1), - - /** - * State of bit 2 - */ - bit2: BitFlag(2), - - /** - * State of bit 3 - */ - bit3: BitFlag(3), - - /** - * State of bit 4 - */ - bit4: BitFlag(4), - - /** - * State of bit 5 - */ - bit5: BitFlag(5), - - /** - * State of bit 6 - */ - bit6: BitFlag(6), - - /** - * State of bit 7 - */ - bit7: BitFlag(7), - - /** - * State of bit 8 - */ - bit8: BitFlag(8), + export interface GetPinCodeResponse extends TypeFromSchema {} + /** + * Input to the DoorLock clearPinCode command + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7 + */ + export const TlvClearPinCodeRequest = TlvObject({ /** - * State of bit 9 + * This field shall specify a valid PIN code slot index or 0xFFFE to indicate all PIN code slots shall be + * cleared. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7.1 */ - bit9: BitFlag(9), + pinSlotIndex: TlvField(0, TlvUInt16) + }); - /** - * State of bit 10 - */ - bit10: BitFlag(10), + /** + * Input to the DoorLock clearPinCode command + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7 + */ + export interface ClearPinCodeRequest extends TypeFromSchema {} + /** + * Input to the DoorLock setAliroReaderConfig command + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42 + */ + export const TlvSetAliroReaderConfigRequest = TlvObject({ /** - * State of bit 11 + * This field shall indicate the signing key component of the Reader’s key pair. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42.1 */ - bit11: BitFlag(11), + signingKey: TlvField(0, TlvByteString.bound({ length: 32 })), /** - * State of bit 12 + * This field shall indicate the verification key component of the Reader’s key pair. This shall be an + * uncompressed elliptic curve public key as defined in section 2.3.3 of SEC 1. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42.2 */ - bit12: BitFlag(12), + verificationKey: TlvField(1, TlvByteString.bound({ length: 65 })), /** - * State of bit 13 + * This field shall indicate the reader group identifier for the lock. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42.3 */ - bit13: BitFlag(13), + groupIdentifier: TlvField(2, TlvByteString.bound({ length: 16 })), /** - * State of bit 14 + * This field shall indicate the group resolving key for the lock. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42.4 */ - bit14: BitFlag(14), + groupResolvingKey: TlvOptionalField(3, TlvByteString.bound({ length: 16 })) + }); - /** - * State of bit 15 - */ - bit15: BitFlag(15) - }; + /** + * Input to the DoorLock setAliroReaderConfig command + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42 + */ + export interface SetAliroReaderConfigRequest extends TypeFromSchema {} /** * Input to the DoorLock setUserStatus command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9 */ export const TlvSetUserStatusRequest = TlvObject({ /** * This field shall indicate the user ID. The value of the UserID field shall be between 0 and the value of the * NumberOfPINUsersSupported attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9.1 */ userId: TlvField(0, TlvUInt16), @@ -2410,7 +2115,7 @@ export namespace DoorLock { * UserStatus value of Available is not allowed. In order to clear a user id, the ClearUser Command shall be * used. For user status value please refer to UserStatusEnum. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9.2 */ userStatus: TlvField(1, TlvEnum()) }); @@ -2418,21 +2123,21 @@ export namespace DoorLock { /** * Input to the DoorLock setUserStatus command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9 */ export interface SetUserStatusRequest extends TypeFromSchema {} /** * Input to the DoorLock getUserStatus command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.10 */ export const TlvGetUserStatusRequest = TlvObject({ /** * This field shall indicate the user ID. The value of the UserID field shall be between 0 and the value of the * NumberOfPINUsersSupported attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.10.1 */ userId: TlvField(0, TlvUInt16) }); @@ -2440,27 +2145,27 @@ export namespace DoorLock { /** * Input to the DoorLock getUserStatus command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.10 */ export interface GetUserStatusRequest extends TypeFromSchema {} /** * Returns the user status for the specified user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.13 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11 */ export const TlvGetUserStatusResponse = TlvObject({ /** * This field shall indicate the user ID provided in the request. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.13.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11.1 */ userId: TlvField(0, TlvUInt16), /** * This field shall indicate the current status of the requested user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.13.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11.2 */ userStatus: TlvField(1, TlvEnum()) }); @@ -2468,33 +2173,27 @@ export namespace DoorLock { /** * Returns the user status for the specified user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.13 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11 */ export interface GetUserStatusResponse extends TypeFromSchema {} /** * Input to the DoorLock setUserType command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.26 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24 */ export const TlvSetUserTypeRequest = TlvObject({ /** * This field shall indicate the user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.26.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24.1 */ userId: TlvField(0, TlvUInt16), /** * This field shall indicate the user type. * - * If UserType is currently YearDayScheduleUser, WeekDayScheduleUser, or ScheduleRestrictedUser and the new - * UserType is UnrestrictedUser then all existing Year Day and/or Week Day schedules shall be ignored or - * disabled (if this transition is supported by the door lock). If UserType is ScheduleRestrictedUser and the - * new UserType is ScheduleRestrictedUser then all existing Year Day and/or Week Day schedules shall be applied - * or enabled. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.26.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24.2 */ userType: TlvField(1, TlvEnum()) }); @@ -2502,21 +2201,21 @@ export namespace DoorLock { /** * Input to the DoorLock setUserType command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.26 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24 */ export interface SetUserTypeRequest extends TypeFromSchema {} /** * Input to the DoorLock getUserType command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25 */ export const TlvGetUserTypeRequest = TlvObject({ userId: TlvField(0, TlvUInt16) }); /** * Input to the DoorLock getUserType command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25 */ export interface GetUserTypeRequest extends TypeFromSchema {} @@ -2524,7 +2223,7 @@ export namespace DoorLock { * Returns the user type for the specified user ID. If the requested User ID is invalid, send Default Response with * an error status equal to FAILURE. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.28 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.26 */ export const TlvGetUserTypeResponse = TlvObject({ userId: TlvField(0, TlvUInt16), @@ -2535,14 +2234,14 @@ export namespace DoorLock { * Returns the user type for the specified user ID. If the requested User ID is invalid, send Default Response with * an error status equal to FAILURE. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.28 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.26 */ export interface GetUserTypeResponse extends TypeFromSchema {} /** * Input to the DoorLock setRfidCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27 */ export const TlvSetRfidCodeRequest = TlvObject({ /** @@ -2550,7 +2249,7 @@ export namespace DoorLock { * * The value of the UserID field shall be between 0 and the value of the NumberOfRFIDUsersSupported attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27.1 */ userId: TlvField(0, TlvUInt16), @@ -2560,14 +2259,14 @@ export namespace DoorLock { * * Only the values 1 (Occupied/Enabled) and 3 (Occupied/Disabled) are allowed for UserStatus. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27.2 */ userStatus: TlvField(1, TlvNullable(TlvEnum())), /** * The values are the same as used for SetPINCode command. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27.3 */ userType: TlvField(2, TlvNullable(TlvEnum())), @@ -2577,14 +2276,14 @@ export namespace DoorLock { /** * Input to the DoorLock setRfidCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27 */ export interface SetRfidCodeRequest extends TypeFromSchema {} /** * Input to the DoorLock getRfidCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.28 */ export const TlvGetRfidCodeRequest = TlvObject({ /** @@ -2592,7 +2291,7 @@ export namespace DoorLock { * * The value of the UserID field shall be between 0 and the value of the NumberOfRFIDUsersSupported attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.28.1 */ userId: TlvField(0, TlvUInt16) }); @@ -2600,7 +2299,7 @@ export namespace DoorLock { /** * Input to the DoorLock getRfidCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.28 */ export interface GetRfidCodeRequest extends TypeFromSchema {} @@ -2617,7 +2316,7 @@ export namespace DoorLock { * CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and NOT_FOUND if greater than or * equal to the max number of users supported. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.31 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29 */ export const TlvGetRfidCodeResponse = TlvObject({ userId: TlvField(0, TlvUInt16), @@ -2639,21 +2338,21 @@ export namespace DoorLock { * CONSTRAINT_ERROR when User_ID is less than the max number of users supported, and NOT_FOUND if greater than or * equal to the max number of users supported. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.31 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29 */ export interface GetRfidCodeResponse extends TypeFromSchema {} /** * Input to the DoorLock clearRfidCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30 */ export const TlvClearRfidCodeRequest = TlvObject({ /** * This field shall indicate a valid RFID code slot index or 0xFFFE to indicate all RFID code slots shall be * cleared. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30.1 */ rfidSlotIndex: TlvField(0, TlvUInt16) }); @@ -2661,20 +2360,20 @@ export namespace DoorLock { /** * Input to the DoorLock clearRfidCode command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30 */ export interface ClearRfidCodeRequest extends TypeFromSchema {} /** * Input to the DoorLock unboltDoor command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.45 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41 */ export const TlvUnboltDoorRequest = TlvObject({ /** * See PINCode field. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.45.1 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41.1 */ pinCode: TlvOptionalField(0, TlvByteString) }); @@ -2682,12 +2381,12 @@ export namespace DoorLock { /** * Input to the DoorLock unboltDoor command * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.45 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41 */ export interface UnboltDoorRequest extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.20 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.19 */ export enum LockState { /** @@ -2712,7 +2411,7 @@ export namespace DoorLock { } /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.21 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.20 */ export enum LockType { /** @@ -2777,7 +2476,7 @@ export namespace DoorLock { } /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.22 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.21 */ export enum LedSetting { /** @@ -2797,7 +2496,7 @@ export namespace DoorLock { } /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.23 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.22 */ export enum SoundVolume { /** @@ -3005,11 +2704,6 @@ export namespace DoorLock { */ lockFactoryReset: BitFlag(1), - /** - * Reserved - */ - na: BitFlag(2), - /** * RF Module Power Cycled */ @@ -3113,7 +2807,7 @@ export namespace DoorLock { /** * This enumeration shall indicate the alarm type. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.8 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.7 */ export enum AlarmCode { /** @@ -3181,7 +2875,7 @@ export namespace DoorLock { /** * This enumeration shall indicate the type of Lock operation performed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.14 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.13 */ export enum LockOperationType { /** @@ -3276,7 +2970,7 @@ export namespace DoorLock { /** * This enumeration shall indicate the error cause of the Lock/Unlock operation performed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.15 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.14 */ export enum OperationError { /** @@ -3375,128 +3069,23 @@ export namespace DoorLock { export interface LockOperationErrorEvent extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.25.1 - */ - export enum OperationEventCode { - /** - * Event code is unknown - */ - UnknownOrMfgSpecific = 0, - - /** - * Event code is lock - */ - Lock = 1, - - /** - * Event code is unlock - */ - Unlock = 2, - - /** - * Event code is lock failure due to invalid PIN or RFID - */ - LockFailureInvalidPiNorRfid = 3, - - /** - * Event code is lock failure due to invalid schedule - */ - LockFailureInvalidSchedule = 4, - - /** - * Event code is unlock failure due to invalid PIN or RFID - */ - UnlockFailureInvalidPiNorRfid = 5, - - /** - * Event code is unlock failure due to invalid schedule - */ - UnlockFailureInvalidSchedule = 6, - - /** - * Event code is one touch lock - */ - OneTouchLock = 7, - - /** - * Event code is key lock - */ - KeyLock = 8, - - /** - * Event code is key unlock - */ - KeyUnlock = 9, - - /** - * Event code is auto lock - */ - AutoLock = 10, - - /** - * Event code is schedule lock - */ - ScheduleLock = 11, - - /** - * Event code is schedule unlock - */ - ScheduleUnlock = 12, - - /** - * Event code is manual lock (Key or Thumbturn) - */ - ManualLock = 13, - - /** - * Event code is manual unlock (Key or Thumbturn) - */ - ManualUnlock = 14, - - /** - * Event code is non access user operation - */ - NonAccessUserOperationEvent = 15 - } - - /** - * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.25.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.6.23 */ - export enum ProgrammingEventCode { - /** - * Event code is unknown - */ - UnknownOrMfgSpecific = 0, - - /** - * Event code is code changed - */ - ProgrammingCodeChanged = 1, - - /** - * Event code is PIN added - */ - PinCodeAdded = 2, - - /** - * Event code is PIN cleared - */ - PinCodeCleared = 3, - + export enum EventType { /** - * Event code is PIN changed + * Event type is operation */ - PinCodeChanged = 4, + Operation = 0, /** - * Event code is RFID added + * Event type is programming */ - RfidCodeAdded = 5, + Programming = 1, /** - * Event code is RFID cleared + * Event type is alarm */ - RfidCodeCleared = 6 + Alarm = 2 } /** @@ -3524,21 +3113,21 @@ export namespace DoorLock { * * Null only if an internal error prevents the retrieval of the current door state. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.4 */ doorState: Attribute(0x3, TlvNullable(TlvEnum())), /** * This attribute shall hold the number of door open events that have occurred since it was last zeroed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.5 */ doorOpenEvents: OptionalWritableAttribute(0x4, TlvUInt32, { writeAcl: AccessLevel.Manage }), /** * This attribute shall hold the number of door closed events that have occurred since it was last zeroed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.6 */ doorClosedEvents: OptionalWritableAttribute(0x5, TlvUInt32, { writeAcl: AccessLevel.Manage }), @@ -3546,7 +3135,7 @@ export namespace DoorLock { * This attribute shall hold the number of minutes the door has been open since the last time it * transitioned from closed to open. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.8 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.7 */ openPeriod: OptionalWritableAttribute(0x6, TlvUInt16, { writeAcl: AccessLevel.Manage }) }, @@ -3561,51 +3150,6 @@ export namespace DoorLock { } }); - /** - * A DoorLockCluster supports these elements if it supports feature Logging. - */ - export const LoggingComponent = MutableCluster.Component({ - attributes: { - /** - * Indicates the number of available log records. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.9 - */ - numberOfLogRecordsSupported: FixedAttribute(0x10, TlvUInt16, { default: 0 }), - - /** - * This attribute shall enable/disable event logging. - * - * When event logging is enabled, all event messages are stored on the lock for retrieval. Logging events - * can be, but are not limited to, Tamper Alarm, Lock, Unlock, AutoRelock, User Code Added, User Code - * Cleared, Schedule Added, and Schedule Cleared. For a full detail of all the possible alarms and events, - * please refer to the full list in the Alarm and Event Masks Attribute Set. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.22 - */ - enableLogging: WritableAttribute(0x20, TlvBoolean, { default: true, writeAcl: AccessLevel.Administer }) - }, - - commands: { - /** - * Request a log record. Log number is between 1 – [Number of Log Records Supported attribute]. If log - * number 0 is requested then the most recent log entry is returned. - * - * Log record format: The log record format is defined in the description of the GetLogRecordResponse - * command. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4 - */ - getLogRecord: Command( - 0x4, - TlvGetLogRecordRequest, - 0x4, - TlvGetLogRecordResponse, - { invokeAcl: AccessLevel.Manage } - ) - } - }); - /** * A DoorLockCluster supports these elements if it supports feature User. */ @@ -3614,7 +3158,7 @@ export namespace DoorLock { /** * Indicates the number of total users supported by the lock. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.10 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.8 */ numberOfTotalUsersSupported: FixedAttribute(0x11, TlvUInt16, { default: 0 }), @@ -3622,7 +3166,7 @@ export namespace DoorLock { * This attribute shall contain a bitmap with the bits set for the values of CredentialRuleEnum supported * on this device. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.20 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.18 */ credentialRulesSupport: FixedAttribute( 0x1b, @@ -3641,7 +3185,7 @@ export namespace DoorLock { * NumberOfRFIDUsersSupported is set to 3, it will not be possible to actually assign 10 credentials for a * user because maximum number of credentials in the database is 8. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.21 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.19 */ numberOfCredentialsSupportedPerUser: FixedAttribute(0x1c, TlvUInt8, { default: 0 }), @@ -3650,7 +3194,7 @@ export namespace DoorLock { * type ExpiringUser shall remain valid after its first use before expiring. When the credential expires * the UserStatus for the corresponding user record shall be set to OccupiedDisabled. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.39 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.36 */ expiringUserTimeout: OptionalWritableAttribute( 0x35, @@ -3678,7 +3222,7 @@ export namespace DoorLock { * • INVALID_COMMAND, if one or more fields violate constraints or are invalid or if OperationType is * Modify and UserIndex points to an available slot. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.34 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32 */ setUser: Command( 0x1a, @@ -3696,7 +3240,7 @@ export namespace DoorLock { * COMMAND, etc.) as needed otherwise the GetUserResponse Command shall be sent implying a status of * SUCCESS. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.33 */ getUser: Command(0x1b, TlvGetUserRequest, 0x1c, TlvGetUserResponse, { invokeAcl: AccessLevel.Administer }), @@ -3709,7 +3253,7 @@ export namespace DoorLock { * * A LockUserChange event with the provided UserIndex shall be generated after successfully clearing users. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.37 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.35 */ clearUser: Command( 0x1d, @@ -3725,7 +3269,7 @@ export namespace DoorLock { * * Fields used for different use cases: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.36 */ setCredential: Command( 0x22, @@ -3741,7 +3285,7 @@ export namespace DoorLock { * An InvokeResponse command shall be sent with an appropriate error (e.g. FAILURE, INVALID_COMMAND, etc.) * as needed otherwise the GetCredentialStatusResponse command shall be sent implying a status of SUCCESS. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.38 */ getCredentialStatus: Command( 0x24, @@ -3758,12 +3302,12 @@ export namespace DoorLock { * * For each credential cleared whose user doesn’t have another valid credential, the corresponding user * record shall be reset back to default values and its UserStatus value shall be set to Available and - * UserType value shall be set to UnrestrictedUser and all schedules shall be cleared. In + * UserType value shall be set to UnrestrictedUser and all schedules shall be cleared. In this case a + * LockUserChange event shall be generated for the user being cleared. * - * this case a LockUserChange event shall be generated for the user being cleared. Return status shall be - * one of the following values: + * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.44 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.40 */ clearCredential: Command( 0x26, @@ -3793,21 +3337,21 @@ export namespace DoorLock { /** * Indicates the number of PIN users supported. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.11 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.9 */ numberOfPinUsersSupported: FixedAttribute(0x12, TlvUInt16, { default: 0 }), /** * Indicates the maximum length in bytes of a PIN Code on this device. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.16 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.14 */ maxPinCodeLength: FixedAttribute(0x17, TlvUInt8), /** * Indicates the minimum length in bytes of a PIN Code on this device. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.17 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.15 */ minPinCodeLength: FixedAttribute(0x18, TlvUInt8) } @@ -3821,7 +3365,7 @@ export namespace DoorLock { /** * Indicates the number of RFID users supported. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.12 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.10 */ numberOfRfidUsersSupported: FixedAttribute(0x13, TlvUInt16, { default: 0 }), @@ -3830,7 +3374,7 @@ export namespace DoorLock { * range specified by the manufacturer, if media anti-collision identifiers (UID) are used as RFID code, a * value of 20 (equals 10 Byte ISO 14443A UID) is recommended. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.18 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.16 */ maxRfidCodeLength: FixedAttribute(0x19, TlvUInt8), @@ -3839,7 +3383,7 @@ export namespace DoorLock { * range specified by the manufacturer, if media anti-collision identifiers (UID) are used as RFID code, a * value of 8 (equals 4 Byte ISO 14443A UID) is recommended. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.19 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.17 */ minRfidCodeLength: FixedAttribute(0x1a, TlvUInt8) } @@ -3853,24 +3397,25 @@ export namespace DoorLock { /** * Indicates the number of configurable week day schedule supported per user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.13 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.11 */ - numberOfWeekDaySchedulesSupportedPerUser: FixedAttribute(0x14, TlvUInt8, { default: 0 }) + numberOfWeekDaySchedulesSupportedPerUser: FixedAttribute( + 0x14, + TlvUInt8.bound({ max: 253 }), + { default: 0 } + ) }, commands: { /** * Set a weekly repeating schedule for a specified user. * - * † The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, - * respectively. - * * The associated UserType may be changed to ScheduleRestrictedUser by the lock when a Week Day schedule is * set. * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.14 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12 */ setWeekDaySchedule: Command( 0xb, @@ -3883,10 +3428,7 @@ export namespace DoorLock { /** * Retrieve the specific weekly schedule for the specific user. * - * † The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, - * respectively. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.13 */ getWeekDaySchedule: Command( 0xc, @@ -3899,12 +3441,9 @@ export namespace DoorLock { /** * Clear the specific weekly schedule or all weekly schedules for the specific user. * - * † The Schedule ID and User ID are obsolete field names, use WeekDayIndex and UserIndex instead, - * respectively. - * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.15 */ clearWeekDaySchedule: Command( 0xd, @@ -3924,24 +3463,25 @@ export namespace DoorLock { /** * Indicates the number of configurable year day schedule supported per user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.14 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.12 */ - numberOfYearDaySchedulesSupportedPerUser: FixedAttribute(0x15, TlvUInt8, { default: 0 }) + numberOfYearDaySchedulesSupportedPerUser: FixedAttribute( + 0x15, + TlvUInt8.bound({ max: 253 }), + { default: 0 } + ) }, commands: { /** * Set a time-specific schedule ID for a specified user. * - * † The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, - * respectively. - * * The associated UserType may be changed to ScheduleRestrictedUser by the lock when a Year Day schedule is * set. * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.18 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.16 */ setYearDaySchedule: Command( 0xe, @@ -3954,10 +3494,7 @@ export namespace DoorLock { /** * Retrieve the specific year day schedule for the specific schedule and user indexes. * - * † The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, - * respectively. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.17 */ getYearDaySchedule: Command( 0xf, @@ -3970,12 +3507,9 @@ export namespace DoorLock { /** * Clears the specific year day schedule or all year day schedules for the specific user. * - * † The Schedule ID and User ID are obsolete field names, use YearDayIndex and UserIndex instead, - * respectively. - * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.19 */ clearYearDaySchedule: Command( 0x10, @@ -3995,9 +3529,9 @@ export namespace DoorLock { /** * Indicates the number of holiday schedules supported for the entire door lock device. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.15 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.13 */ - numberOfHolidaySchedulesSupported: FixedAttribute(0x16, TlvUInt8, { default: 0 }) + numberOfHolidaySchedulesSupported: FixedAttribute(0x16, TlvUInt8.bound({ max: 253 }), { default: 0 }) }, commands: { @@ -4005,10 +3539,9 @@ export namespace DoorLock { * Set the holiday Schedule by specifying local start time and local end time with respect to any Lock * Operating Mode. * - * † The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. Return status shall be - * one of the following values: + * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.22 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.20 */ setHolidaySchedule: Command( 0x11, @@ -4021,9 +3554,7 @@ export namespace DoorLock { /** * Get the holiday schedule for the specified index. * - * † The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.21 */ getHolidaySchedule: Command( 0x12, @@ -4036,9 +3567,7 @@ export namespace DoorLock { /** * Clears the holiday schedule or all holiday schedules. * - * † The Holiday Schedule ID is an obsolete field name, use HolidayIndex instead. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.23 */ clearHolidaySchedule: Command( 0x13, @@ -4067,7 +3596,7 @@ export namespace DoorLock { * logic, environmental events, or other reasons. The lock shall reset the counter if a valid credential is * presented. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.35 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.32 */ wrongCodeEntryLimit: WritableAttribute( 0x30, @@ -4081,7 +3610,7 @@ export namespace DoorLock { * to try and guess a PIN for the device.) If the attribute accepts writes and an attempt to write the * attribute to 0 is made, the device shall respond with CONSTRAINT_ERROR. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.36 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.33 */ userCodeTemporaryDisableTime: WritableAttribute( 0x31, @@ -4102,12 +3631,13 @@ export namespace DoorLock { * door lock server to send PINs over the air. This attribute determines the behavior of the server’s TX * operation. If it is false, then it is not ok for the device to send PIN in any messages over the air. * - * The PIN field within any door lock cluster message shall keep the first octet unchanged and masks the - * actual code by replacing with 0xFF. For example (PIN "1234" ): If the attribute value is True, 0x04 0x31 - * 0x32 0x33 0x34 shall be used in the PIN field in any door lock cluster message payload. If the attribute - * value is False, 0x04 0xFF 0xFF 0xFF 0xFF shall be used. + * The PIN field within any door lock cluster message shall keep the first octet unchanged and * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.37 + * masks the actual code by replacing with 0xFF. For example (PIN "1234" ): If the attribute value is True, + * 0x04 0x31 0x32 0x33 0x34 shall be used in the PIN field in any door lock cluster message payload. If the + * attribute value is False, 0x04 0xFF 0xFF 0xFF 0xFF shall be used. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.34 */ sendPinOverTheAir: OptionalWritableAttribute( 0x32, @@ -4123,7 +3653,7 @@ export namespace DoorLock { * Return status is a global status code or a cluster-specific status code from the Status Codes table and * shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.4 */ setPinCode: Command( 0x5, @@ -4136,7 +3666,7 @@ export namespace DoorLock { /** * Retrieve a PIN Code. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.5 */ getPinCode: Command( 0x6, @@ -4149,13 +3679,11 @@ export namespace DoorLock { /** * Clear a PIN code or all PIN codes. * - * † The User ID is an obsolete field name, use PINSlotIndex instead. - * * For each PIN Code cleared whose user doesn’t have a RFID Code or other credential type, then * corresponding user record’s UserStatus value shall be set to Available, and UserType value shall be set * to UnrestrictedUser and all schedules shall be cleared. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.7 */ clearPinCode: Command( 0x7, @@ -4173,7 +3701,7 @@ export namespace DoorLock { * On the server, the clear all PIN codes command SHOULD have the same effect as the ClearPINCode command * with respect to the setting of user status, user type and schedules. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.10 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.8 */ clearAllPinCodes: Command( 0x8, @@ -4195,7 +3723,7 @@ export namespace DoorLock { * server requires that an optional PINs be included in the payload of remote lock operation events like * Lock, Unlock, Unlock with Timeout and Toggle in order to function. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.38 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.35 */ requirePinForRemoteOperation: WritableAttribute( 0x33, @@ -4206,145 +3734,159 @@ export namespace DoorLock { }); /** - * A DoorLockCluster supports these elements if it supports features Notification and PinCredential. + * A DoorLockCluster supports these elements if it supports feature AliroProvisioning. */ - export const NotificationAndPinCredentialComponent = MutableCluster.Component({ + export const AliroProvisioningComponent = MutableCluster.Component({ attributes: { /** - * Event mask used to turn on and off the transmission of keypad operation events. This mask DOES NOT apply - * to the storing of events in the event log. This mask only applies to the Operation Event Notification - * Command. + * Indicates the verification key component of the Reader’s key pair as defined in [Aliro]. The value, if + * not null, shall be an uncompressed elliptic curve public key as defined in section 2.3.3 of SEC 1. * - * This mask DOES NOT apply to the Events mechanism of this cluster. + * Null if no Reader key pair has been configured on the lock. See SetAliroReaderConfig. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.41 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.38 */ - keypadOperationEventMask: OptionalWritableAttribute( - 0x41, - TlvBitmap(TlvUInt16, EventMask), - { - default: BitsFromPartial(EventMask, { bit0: true, bit1: true, bit2: true, bit3: true, bit4: true, bit5: true, bit6: true, bit7: true, bit8: true, bit9: true, bit10: true, bit11: true, bit12: true, bit13: true, bit14: true, bit15: true }), - writeAcl: AccessLevel.Administer - } + aliroReaderVerificationKey: Attribute( + 0x80, + TlvNullable(TlvByteString.bound({ length: 65 })), + { default: null, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } ), /** - * Event mask used to turn on and off keypad programming events. This mask DOES NOT apply to the storing of - * events in the event log. This mask only applies to the Programming Event Notification Command. + * Indicates the reader_group_identifier as defined in [Aliro]. * - * This mask DOES NOT apply to the Events mechanism of this cluster. + * Null if no reader_group_identifier has been configured on the lock. See SetAliroReaderConfig. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.45 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.39 */ - keypadProgrammingEventMask: OptionalWritableAttribute( - 0x45, - TlvBitmap(TlvUInt16, KeypadProgrammingEventMask), - { - default: BitsFromPartial(KeypadProgrammingEventMask, { unknown: true, pinCodeChanged: true, pinAdded: true, pinCleared: true, pinChanged: true, bit5: true, bit6: true, bit7: true, bit8: true, bit9: true, bit10: true, bit11: true, bit12: true, bit13: true, bit14: true, bit15: true }), - writeAcl: AccessLevel.Administer - } - ) - } - }); + aliroReaderGroupIdentifier: Attribute( + 0x81, + TlvNullable(TlvByteString.bound({ length: 16 })), + { default: null, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), - /** - * A DoorLockCluster supports these elements if it supports feature Notification. - */ - export const NotificationComponent = MutableCluster.Component({ - attributes: { /** - * Event mask used to turn on and off the transmission of remote operation events. This mask DOES NOT apply - * to the storing of events in the event log. This mask only applies to the Operation Event Notification - * Command. + * Indicates the reader_group_sub_identifier as defined in [Aliro]. * - * This mask DOES NOT apply to the Events mechanism of this cluster. + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.40 + */ + aliroReaderGroupSubIdentifier: FixedAttribute( + 0x82, + TlvByteString.bound({ length: 16 }), + { readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * Indicates the list of protocol versions supported for expedited transactions as defined in [Aliro]. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.42 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.41 */ - remoteOperationEventMask: OptionalWritableAttribute( - 0x42, - TlvBitmap(TlvUInt16, EventMask), - { - default: BitsFromPartial(EventMask, { bit0: true, bit1: true, bit2: true, bit3: true, bit4: true, bit5: true, bit6: true, bit7: true, bit8: true, bit9: true, bit10: true, bit11: true, bit12: true, bit13: true, bit14: true, bit15: true }), - writeAcl: AccessLevel.Administer - } + aliroExpeditedTransactionSupportedProtocolVersions: FixedAttribute( + 0x83, + TlvArray(TlvByteString, { maxLength: 16 }), + { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } ), /** - * Event mask used to turn on and off manual operation events. This mask DOES NOT apply to the storing of - * events in the event log. This mask only applies to the Operation Event Notification Command. + * Indicates the maximum number of AliroCredentialIssuerKey credentials that can be stored on the lock. * - * This mask DOES NOT apply to the Events mechanism of this cluster. + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.45 + */ + numberOfAliroCredentialIssuerKeysSupported: FixedAttribute(0x87, TlvUInt16, { default: 0 }), + + /** + * Indicates the maximum number of endpoint key credentials that can be stored on the lock. This limit + * applies to the sum of the number of AliroEvictableEndpointKey credentials and the number of + * AliroNonEvictableEndpointKey credentials. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.43 + * NOTE + * + * The credential indices used for these two credential types are independent of each other, similar to all + * other credential types. As long as NumberOfAliroEndpointKeysSupported is at least 2 a client could add a + * credential of type AliroEvictableEndpointKey at any index from 1 to NumberOfAliroEndpointKeysSupported + * and also add a credential of type AliroNonEvictableEndpointKey at the same index, and both credentials + * would exist on the server. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.46 */ - manualOperationEventMask: OptionalWritableAttribute( - 0x43, - TlvBitmap(TlvUInt16, EventMask), - { - default: BitsFromPartial(EventMask, { bit0: true, bit1: true, bit2: true, bit3: true, bit4: true, bit5: true, bit6: true, bit7: true, bit8: true, bit9: true, bit10: true, bit11: true, bit12: true, bit13: true, bit14: true, bit15: true }), - writeAcl: AccessLevel.Administer - } + numberOfAliroEndpointKeysSupported: FixedAttribute(0x88, TlvUInt16, { default: 0 }) + }, + + commands: { + /** + * This command allows communicating an Aliro Reader configuration, as defined in [Aliro], to the lock. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.42 + */ + setAliroReaderConfig: Command( + 0x28, + TlvSetAliroReaderConfigRequest, + 0x28, + TlvNoResponse, + { invokeAcl: AccessLevel.Administer, timed: true } ), /** - * Event mask used to turn on and off remote programming events. This mask DOES NOT apply to the storing of - * events in the event log. This mask only applies to the Programming Event Notification Command. + * This command allows clearing an existing Aliro Reader configuration for the lock. Administrators shall + * NOT clear an Aliro Reader configuration without explicit user permission. * - * This mask DOES NOT apply to the Events mechanism of this cluster. + * NOTE * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.46 + * Using this command will revoke the ability of all existing Aliro user devices that have the old + * verification key to interact with the lock. This effect is not restricted to a single fabric or + * otherwise scoped in any way. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.43 */ - remoteProgrammingEventMask: OptionalWritableAttribute( - 0x46, - TlvBitmap(TlvUInt16, RemoteProgrammingEventMask), - { - default: BitsFromPartial(RemoteProgrammingEventMask, { unknown: true, bit1: true, pinAdded: true, pinCleared: true, pinChanged: true, rfidCodeAdded: true, rfidCodeCleared: true, bit7: true, bit8: true, bit9: true, bit10: true, bit11: true, bit12: true, bit13: true, bit14: true, bit15: true }), - writeAcl: AccessLevel.Administer - } + clearAliroReaderConfig: Command( + 0x29, + TlvNoArguments, + 0x29, + TlvNoResponse, + { invokeAcl: AccessLevel.Administer, timed: true } ) } }); /** - * A DoorLockCluster supports these elements if it supports features Notification and RfidCredential. + * A DoorLockCluster supports these elements if it supports feature AliroBleuwb. */ - export const NotificationAndRfidCredentialComponent = MutableCluster.Component({ + export const AliroBleuwbComponent = MutableCluster.Component({ attributes: { /** - * Event mask used to turn on and off RFID operation events. This mask DOES NOT apply to the storing of - * events in the event log. This mask only applies to the Operation Event Notification Command. + * Indicates the Group Resolving Key as defined in [Aliro]. * - * This mask DOES NOT apply to the Events mechanism of this cluster. + * Null if no group resolving key has been configured on the lock. See SetAliroReaderConfig. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.44 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.42 */ - rfidOperationEventMask: OptionalWritableAttribute( - 0x44, - TlvBitmap(TlvUInt16, EventMask), - { - default: BitsFromPartial(EventMask, { bit0: true, bit1: true, bit2: true, bit3: true, bit4: true, bit5: true, bit6: true, bit7: true, bit8: true, bit9: true, bit10: true, bit11: true, bit12: true, bit13: true, bit14: true, bit15: true }), - writeAcl: AccessLevel.Administer - } + aliroGroupResolvingKey: Attribute( + 0x84, + TlvNullable(TlvByteString.bound({ length: 16 })), + { default: null, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } ), /** - * Event mask used to turn on and off RFID programming events. This mask DOES NOT apply to the storing of - * events in the event log. This mask only applies to the Programming Event Notification Command. - * - * This mask DOES NOT apply to the Events mechanism of this cluster. + * Indicates the list of protocol versions supported for the Bluetooth LE + UWB Access Control Flow as + * defined in [Aliro]. * - * This mask DOES NOT apply to the Events mechanism of this cluster. + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.43 + */ + aliroSupportedBleuwbProtocolVersions: FixedAttribute( + 0x85, + TlvArray(TlvByteString, { maxLength: 16 }), + { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * Indicates the version of the Bluetooth LE advertisement as defined in [Aliro]. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.47 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.44 */ - rfidProgrammingEventMask: OptionalWritableAttribute( - 0x47, - TlvBitmap(TlvUInt16, RfidProgrammingEventMask), - { - default: BitsFromPartial(RfidProgrammingEventMask, { unknown: true, bit1: true, bit2: true, bit3: true, bit4: true, idAdded: true, idCleared: true, bit7: true, bit8: true, bit9: true, bit10: true, bit11: true, bit12: true, bit13: true, bit14: true, bit15: true }), - writeAcl: AccessLevel.Administer - } + aliroBleAdvertisingVersion: FixedAttribute( + 0x86, + TlvUInt8, + { default: 0, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } ) } }); @@ -4358,7 +3900,7 @@ export namespace DoorLock { /** * Set the status of a user ID. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.11 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.9 */ setUserStatus: OptionalCommand( 0x9, @@ -4371,7 +3913,7 @@ export namespace DoorLock { /** * Get the status of a user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.12 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.10 */ getUserStatus: OptionalCommand( 0xa, @@ -4388,7 +3930,7 @@ export namespace DoorLock { * * Return status shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.26 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.24 */ setUserType: OptionalCommand( 0x14, @@ -4401,7 +3943,7 @@ export namespace DoorLock { /** * Retrieve the user type for a specific user. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.25 */ getUserType: OptionalCommand( 0x15, @@ -4430,7 +3972,7 @@ export namespace DoorLock { * Return status is a global status code or a cluster-specific status code from the Status Codes table and * shall be one of the following values: * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.29 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.27 */ setRfidCode: Command( 0x16, @@ -4443,7 +3985,7 @@ export namespace DoorLock { /** * Retrieve an RFID code. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.28 */ getRfidCode: Command( 0x17, @@ -4456,13 +3998,11 @@ export namespace DoorLock { /** * Clear an RFID code or all RFID codes. * - * † The User ID is an obsolete field name, use RFIDSlotIndex instead. - * * For each RFID Code cleared whose user doesn’t have a PIN Code or other credential type, then the * corresponding user record’s UserStatus value shall be set to Available, and UserType value shall be set * to UnrestrictedUser and all schedules shall be cleared. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.32 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.30 */ clearRfidCode: Command( 0x18, @@ -4477,7 +4017,7 @@ export namespace DoorLock { * user status has to be set to "0 Available", the user type has to be set to the default value, and all * schedules which are supported have to be set to the default values. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.33 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.31 */ clearAllRfidCodes: Command( 0x19, @@ -4504,7 +4044,7 @@ export namespace DoorLock { * If the attribute AutoRelockTime is supported, the lock will transition to the locked state when the auto * relock time has expired. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.45 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.41 */ unboltDoor: Command(0x27, TlvUnboltDoorRequest, 0x27, TlvNoResponse, { timed: true }) } @@ -4516,7 +4056,7 @@ export namespace DoorLock { export const Base = MutableCluster.Component({ id: 0x101, name: "DoorLock", - revision: 7, + revision: 8, features: { /** @@ -4541,7 +4081,6 @@ export namespace DoorLock { * * A lock may support multiple credential types so if the User feature is supported the UserType, * UserStatus and Schedules are all associated with a User index and not directly with a RFID index. A User - * * Index may have several credentials associated with it. * * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.2 @@ -4564,27 +4103,20 @@ export namespace DoorLock { */ fingerCredentials: BitFlag(2), - /** - * Logging - * - * If Events are not supported the logging feature shall replace the Event reporting structure. If Events - * are supported the logging feature shall NOT be supported. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.4 - */ - logging: BitFlag(3), - /** * WeekDayAccessSchedules * * If the User feature is supported then Week Day Schedules are applied to a User and not a credential. * * Week Day Schedules are used to restrict access to a specified time window on certain days of the week. - * The schedule is repeated each week. When a schedule is cleared this clears the access restrictions and - * grants unrestricted access to the user. The lock may automatically adjust the UserType when a schedule - * is created or cleared. + * The schedule is repeated each week. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.5 + * The lock may automatically adjust the UserType when a schedule is created or cleared. + * + * Support for WeekDayAccessSchedules requires that the lock has the capability of keeping track of local + * time. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.4 */ weekDayAccessSchedules: BitFlag(4), @@ -4594,7 +4126,7 @@ export namespace DoorLock { * If this feature is supported this indicates that the lock has the ability to determine the position of * the door which is separate from the state of the lock. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.5 */ doorPositionSensor: BitFlag(5), @@ -4610,7 +4142,7 @@ export namespace DoorLock { * A lock may support multiple credential types so if the User feature is supported the UserType, * UserStatus and Schedules are all associated with a User and not directly with a credential. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.6 */ faceCredentials: BitFlag(6), @@ -4618,10 +4150,11 @@ export namespace DoorLock { * CredentialOverTheAirAccess * * If this feature is supported then the lock supports the ability to verify a credential provided in a + * * lock/unlock command. Currently the cluster only supports providing the PIN credential to the lock/unlock * commands. If this feature is supported then the PIN Credential feature shall also be supported. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.8 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.7 */ credentialOverTheAirAccess: BitFlag(7), @@ -4632,30 +4165,22 @@ export namespace DoorLock { * used to associate credentials and schedules to single user record within the lock. This also means the * UserType and UserStatus fields are associated with a User and not a credential. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.9 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.8 */ user: BitFlag(8), - /** - * Notification - * - * This is a feature used before support of events. This feature supports notification commands and masks - * used to filter these notifications. - * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.10 - */ - notification: BitFlag(9), - /** * YearDayAccessSchedules * * If the User feature is supported then Year Day Schedules are applied to a User and not a credential. + * Year Day Schedules are used to restrict access to a specified date and time window. * - * Year Day Schedules are used to restrict access to a specified date and time window. When a schedule is - * cleared this clears the access restrictions and grants unrestricted access to the user. The lock may - * automatically adjust the UserType when a schedule is created or cleared. + * The lock may automatically adjust the UserType when a schedule is created or cleared. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.11 + * Support for YearDayAccessSchedules requires that the lock has the capability of keeping track of local + * time. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.9 */ yearDayAccessSchedules: BitFlag(10), @@ -4665,7 +4190,9 @@ export namespace DoorLock { * This feature is used to setup Holiday Schedule in the lock device. A Holiday Schedule sets a start and * stop end date/time for the lock to use the specified operating mode set by the Holiday Schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.12 + * Support for HolidaySchedules requires that the lock has the capability of keeping track of local time. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.10 */ holidaySchedules: BitFlag(11), @@ -4678,9 +4205,29 @@ export namespace DoorLock { * Unlatched. Locks without unbolting support don’t differentiate between unbolting and unlocking and * perform the same operation for both commands. * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.11 + */ + unbolting: BitFlag(12), + + /** + * AliroProvisioning + * + * Locks that support this feature implement the Aliro specification as defined in [Aliro] and support + * Matter as a method for provisioning Aliro credentials. + * + * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.12 + */ + aliroProvisioning: BitFlag(13), + + /** + * AliroBleuwb + * + * Locks that support this feature implement the Bluetooth LE + UWB Access Control Flow as defined in + * [Aliro]. + * * @see {@link MatterSpecification.v13.Cluster} § 5.2.4.13 */ - unbolting: BitFlag(12) + aliroBleuwb: BitFlag(14) }, attributes: { @@ -4693,14 +4240,14 @@ export namespace DoorLock { * Locked and Unlocked so it is only partially secured. For example, a deadbolt could be partially extended * and not in a dead latched state. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.1 */ - lockState: Attribute(0x0, TlvNullable(TlvEnum()), { scene: true }), + lockState: Attribute(0x0, TlvNullable(TlvEnum())), /** * Indicates the type of door lock as defined in LockTypeEnum. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.2 */ lockType: Attribute(0x1, TlvEnum()), @@ -4708,7 +4255,7 @@ export namespace DoorLock { * Indicates if the lock is currently able to (Enabled) or not able to (Disabled) process remote Lock, * Unlock, or Unlock with Timeout commands. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.3 */ actuatorEnabled: Attribute(0x2, TlvBoolean), @@ -4716,7 +4263,7 @@ export namespace DoorLock { * Indicates the language for the on-screen or audible user interface using a 2- byte language code from * ISO-639-1. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.23 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.20 */ language: OptionalWritableAttribute( 0x21, @@ -4727,7 +4274,7 @@ export namespace DoorLock { /** * Indicates the settings for the LED support, as defined by LEDSettingEnum. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.24 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.21 */ ledSettings: OptionalWritableAttribute( 0x22, @@ -4740,14 +4287,14 @@ export namespace DoorLock { * 0=disabled. If set, unlock operations from any source will be timed. For one time unlock with timeout * use the specific command. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.25 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.22 */ autoRelockTime: OptionalWritableAttribute(0x23, TlvUInt32, { writeAcl: AccessLevel.Manage }), /** * Indicates the sound volume on a door lock as defined by SoundVolumeEnum. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.26 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.23 */ soundVolume: OptionalWritableAttribute( 0x24, @@ -4758,7 +4305,7 @@ export namespace DoorLock { /** * Indicates the current operating mode of the lock as defined in OperatingModeEnum. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.27 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.24 */ operatingMode: WritableAttribute( 0x25, @@ -4771,7 +4318,7 @@ export namespace DoorLock { * by the lock. All operating modes NOT supported by a lock shall be set to one. The value of the * OperatingMode enumeration defines the related bit to be set. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.28 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.25 */ supportedOperatingModes: FixedAttribute( 0x26, @@ -4781,8 +4328,10 @@ export namespace DoorLock { /** * Indicates the default configurations as they are physically set on the device (example: hardware dip - * switch setting, etc…) and represents the default setting for some of the attributes within this cluster - * (for example: LED, Auto Lock, Sound Volume, and Operating Mode attributes). + * switch setting, etc…) and represents the default setting for some of the + * + * attributes within this cluster (for example: LED, Auto Lock, Sound Volume, and Operating Mode + * attributes). * * This is a read-only attribute and is intended to allow clients to determine what changes may need to be * made without having to query all the included attributes. It may be beneficial for the clients to know @@ -4796,7 +4345,7 @@ export namespace DoorLock { * current Sound Volume is High Volume. Therefore, if the client wants to query/modify the current Sound * Volume setting on the server, the client SHOULD read/write to the Sound Volume attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.29 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.26 */ defaultConfigurationRegister: OptionalAttribute(0x27, TlvBitmap(TlvUInt16, ConfigurationRegister)), @@ -4807,7 +4356,7 @@ export namespace DoorLock { * lock for those features whose bit is set to 0 in the LocalProgrammingFeatures attribute. Local * programming shall be enabled by default. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.30 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.27 */ enableLocalProgramming: OptionalWritableAttribute( 0x28, @@ -4819,7 +4368,7 @@ export namespace DoorLock { * This attribute shall enable/disable the ability to lock the door lock with a single touch on the door * lock. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.31 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.28 */ enableOneTouchLocking: OptionalWritableAttribute( 0x29, @@ -4831,7 +4380,7 @@ export namespace DoorLock { * This attribute shall enable/disable an inside LED that allows the user to see at a glance if the door is * locked. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.32 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.29 */ enableInsideStatusLed: OptionalWritableAttribute( 0x2a, @@ -4843,7 +4392,7 @@ export namespace DoorLock { * This attribute shall enable/disable a button inside the door that is used to put the lock into privacy * mode. When the lock is in privacy mode it cannot be manipulated from the outside. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.33 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.30 */ enablePrivacyModeButton: OptionalWritableAttribute( 0x2b, @@ -4860,7 +4409,7 @@ export namespace DoorLock { * * The features that can be disabled from local programming are defined in LocalProgrammingFeaturesBitmap. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.34 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.31 */ localProgrammingFeatures: OptionalWritableAttribute( 0x2c, @@ -4876,13 +4425,13 @@ export namespace DoorLock { * * This mask DOES NOT apply to the Events mechanism of this cluster. * - * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.40 + * @see {@link MatterSpecification.v13.Cluster} § 5.2.9.37 */ alarmMask: OptionalWritableAttribute( 0x40, TlvBitmap(TlvUInt16, AlarmMask), { - default: BitsFromPartial(AlarmMask, { lockJammed: true, lockFactoryReset: true, na: true, lockRadioPowerCycled: true, wrongCodeEntryLimit: true, frontEscutcheonRemoved: true, doorForcedOpen: true }), + default: BitsFromPartial(AlarmMask, { lockJammed: true, lockFactoryReset: true, lockRadioPowerCycled: true, wrongCodeEntryLimit: true, frontEscutcheonRemoved: true, doorForcedOpen: true }), writeAcl: AccessLevel.Administer } ) @@ -4894,8 +4443,6 @@ export namespace DoorLock { * lock. The door lock may require a PIN depending on the value of the RequirePINForRemoteOperation * attribute. * - * † The PIN/RFID Code is an obsolete field name, use PINCode instead. - * * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.1 */ lockDoor: Command(0x0, TlvLockDoorRequest, 0x0, TlvNoResponse, { timed: true }), @@ -4910,8 +4457,6 @@ export namespace DoorLock { * If the attribute AutoRelockTime is supported the lock will transition to the locked state when the auto * relock time has expired. * - * † The PIN/RFID Code is an obsolete field name, use PINCode instead. - * * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.2 */ unlockDoor: Command(0x1, TlvUnlockDoorRequest, 0x1, TlvNoResponse, { timed: true }), @@ -4919,12 +4464,9 @@ export namespace DoorLock { /** * This command causes the lock device to unlock the door with a timeout parameter. After the time in * seconds specified in the timeout field, the lock device will relock itself automatically. This timeout - * parameter is only temporary for this message transition and overrides the default relock time - * - * as specified in the AutoRelockTime attribute. If the door lock device is not capable of or does not want - * to support temporary Relock Timeout, it SHOULD NOT support this optional command. - * - * † The PIN/RFID Code is an obsolete field name, use PINCode instead. + * parameter is only temporary for this message transition and overrides the default relock time as + * specified in the AutoRelockTime attribute. If the door lock device is not capable of or does not want to + * support temporary Relock Timeout, it SHOULD NOT support this optional command. * * @see {@link MatterSpecification.v13.Cluster} § 5.2.10.3 */ @@ -4964,8 +4506,9 @@ export namespace DoorLock { * ◦ shall generate a LockOperation event of LockOperationType Unlatch when it is actuated from the * outside. * - * ◦ may generate a LockOperation event of LockOperationType Unlatch when it is actuated from the - * inside. + * ◦ may generate a LockOperation event of LockOperationType Unlatch when it is actuated + * + * from the inside. * * @see {@link MatterSpecification.v13.Cluster} § 5.2.11.3 */ @@ -4985,7 +4528,6 @@ export namespace DoorLock { */ extensions: MutableCluster.Extensions( { flags: { doorPositionSensor: true }, component: DoorPositionSensorComponent }, - { flags: { logging: true }, component: LoggingComponent }, { flags: { user: true }, component: UserComponent }, { flags: { pinCredential: true }, component: PinCredentialComponent }, { flags: { rfidCredential: true }, component: RfidCredentialComponent }, @@ -4999,9 +4541,8 @@ export namespace DoorLock { flags: { credentialOverTheAirAccess: true, pinCredential: true }, component: CredentialOverTheAirAccessAndPinCredentialComponent }, - { flags: { notification: true, pinCredential: true }, component: NotificationAndPinCredentialComponent }, - { flags: { notification: true }, component: NotificationComponent }, - { flags: { notification: true, rfidCredential: true }, component: NotificationAndRfidCredentialComponent }, + { flags: { aliroProvisioning: true }, component: AliroProvisioningComponent }, + { flags: { aliroBleuwb: true }, component: AliroBleuwbComponent }, { flags: { pinCredential: true, rfidCredential: true, fingerCredentials: true, user: false }, component: PinCredentialAndRfidCredentialAndFingerCredentialsNotUserComponent @@ -5009,6 +4550,7 @@ export namespace DoorLock { { flags: { user: false }, component: NotUserComponent }, { flags: { rfidCredential: true, user: false }, component: RfidCredentialNotUserComponent }, { flags: { unbolting: true }, component: UnboltingComponent }, + { flags: { aliroProvisioning: true, user: false }, component: false }, { flags: { @@ -5020,7 +4562,9 @@ export namespace DoorLock { }, component: false - } + }, + + { flags: { aliroBleuwb: true, aliroProvisioning: false }, component: false } ) }); @@ -5034,6 +4578,8 @@ export namespace DoorLock { * the locking functionality is abstracted from the cluster. The cluster has a small list of mandatory attributes * and functions and a list of optional features. * + * Figure 16. Typical Usage of the Door Lock Cluster + * * DoorLockCluster supports optional features that you can enable with the DoorLockCluster.with() factory method. * * @see {@link MatterSpecification.v13.Cluster} § 5.2 @@ -5042,7 +4588,6 @@ export namespace DoorLock { export const Cluster: Cluster = ClusterInstance; const DPS = { doorPositionSensor: true }; - const LOG = { logging: true }; const USR = { user: true }; const PIN = { pinCredential: true }; const RID = { rfidCredential: true }; @@ -5051,9 +4596,8 @@ export namespace DoorLock { const HDSCH = { holidaySchedules: true }; const PIN_NOT_USR = { pinCredential: true, user: false }; const COTA_PIN = { credentialOverTheAirAccess: true, pinCredential: true }; - const NOT_PIN = { notification: true, pinCredential: true }; - const NOT = { notification: true }; - const NOT_RID = { notification: true, rfidCredential: true }; + const ALIRO = { aliroProvisioning: true }; + const ALBU = { aliroBleuwb: true }; const PIN_RID_FGP_NOT_USR = { pinCredential: true, rfidCredential: true, fingerCredentials: true, user: false }; const RID_NOT_USR = { rfidCredential: true, user: false }; const UBOLT = { unbolting: true }; @@ -5085,10 +4629,6 @@ export namespace DoorLock { DoorPositionSensorComponent.attributes.openPeriod, { optionalIf: [DPS] } ), - numberOfLogRecordsSupported: MutableCluster.AsConditional( - LoggingComponent.attributes.numberOfLogRecordsSupported, - { mandatoryIf: [LOG] } - ), numberOfTotalUsersSupported: MutableCluster.AsConditional( UserComponent.attributes.numberOfTotalUsersSupported, { mandatoryIf: [USR] } @@ -5137,10 +4677,6 @@ export namespace DoorLock { UserComponent.attributes.numberOfCredentialsSupportedPerUser, { mandatoryIf: [USR] } ), - enableLogging: MutableCluster.AsConditional( - LoggingComponent.attributes.enableLogging, - { mandatoryIf: [LOG] } - ), wrongCodeEntryLimit: MutableCluster.AsConditional( PinCredentialOrRfidCredentialComponent.attributes.wrongCodeEntryLimit, { mandatoryIf: [PIN, RID] } @@ -5161,39 +4697,46 @@ export namespace DoorLock { UserComponent.attributes.expiringUserTimeout, { optionalIf: [USR] } ), - keypadOperationEventMask: MutableCluster.AsConditional( - NotificationAndPinCredentialComponent.attributes.keypadOperationEventMask, - { optionalIf: [NOT_PIN] } + aliroReaderVerificationKey: MutableCluster.AsConditional( + AliroProvisioningComponent.attributes.aliroReaderVerificationKey, + { mandatoryIf: [ALIRO] } ), - remoteOperationEventMask: MutableCluster.AsConditional( - NotificationComponent.attributes.remoteOperationEventMask, - { optionalIf: [NOT] } + aliroReaderGroupIdentifier: MutableCluster.AsConditional( + AliroProvisioningComponent.attributes.aliroReaderGroupIdentifier, + { mandatoryIf: [ALIRO] } ), - manualOperationEventMask: MutableCluster.AsConditional( - NotificationComponent.attributes.manualOperationEventMask, - { optionalIf: [NOT] } + aliroReaderGroupSubIdentifier: MutableCluster.AsConditional( + AliroProvisioningComponent.attributes.aliroReaderGroupSubIdentifier, + { mandatoryIf: [ALIRO] } ), - rfidOperationEventMask: MutableCluster.AsConditional( - NotificationAndRfidCredentialComponent.attributes.rfidOperationEventMask, - { optionalIf: [NOT_RID] } + aliroExpeditedTransactionSupportedProtocolVersions: MutableCluster.AsConditional( + AliroProvisioningComponent.attributes.aliroExpeditedTransactionSupportedProtocolVersions, + { mandatoryIf: [ALIRO] } ), - keypadProgrammingEventMask: MutableCluster.AsConditional( - NotificationAndPinCredentialComponent.attributes.keypadProgrammingEventMask, - { optionalIf: [NOT_PIN] } + aliroGroupResolvingKey: MutableCluster.AsConditional( + AliroBleuwbComponent.attributes.aliroGroupResolvingKey, + { mandatoryIf: [ALBU] } ), - remoteProgrammingEventMask: MutableCluster.AsConditional( - NotificationComponent.attributes.remoteProgrammingEventMask, - { optionalIf: [NOT] } + aliroSupportedBleuwbProtocolVersions: MutableCluster.AsConditional( + AliroBleuwbComponent.attributes.aliroSupportedBleuwbProtocolVersions, + { mandatoryIf: [ALBU] } ), - rfidProgrammingEventMask: MutableCluster.AsConditional( - NotificationAndRfidCredentialComponent.attributes.rfidProgrammingEventMask, - { optionalIf: [NOT_RID] } + aliroBleAdvertisingVersion: MutableCluster.AsConditional( + AliroBleuwbComponent.attributes.aliroBleAdvertisingVersion, + { mandatoryIf: [ALBU] } + ), + numberOfAliroCredentialIssuerKeysSupported: MutableCluster.AsConditional( + AliroProvisioningComponent.attributes.numberOfAliroCredentialIssuerKeysSupported, + { mandatoryIf: [ALIRO] } + ), + numberOfAliroEndpointKeysSupported: MutableCluster.AsConditional( + AliroProvisioningComponent.attributes.numberOfAliroEndpointKeysSupported, + { mandatoryIf: [ALIRO] } ) }, commands: { ...Cluster.commands, - getLogRecord: MutableCluster.AsConditional(LoggingComponent.commands.getLogRecord, { mandatoryIf: [LOG] }), setPinCode: MutableCluster.AsConditional( PinCredentialNotUserComponent.commands.setPinCode, { mandatoryIf: [PIN_NOT_USR] } @@ -5290,7 +4833,15 @@ export namespace DoorLock { UserComponent.commands.clearCredential, { mandatoryIf: [USR] } ), - unboltDoor: MutableCluster.AsConditional(UnboltingComponent.commands.unboltDoor, { mandatoryIf: [UBOLT] }) + unboltDoor: MutableCluster.AsConditional(UnboltingComponent.commands.unboltDoor, { mandatoryIf: [UBOLT] }), + setAliroReaderConfig: MutableCluster.AsConditional( + AliroProvisioningComponent.commands.setAliroReaderConfig, + { mandatoryIf: [ALIRO] } + ), + clearAliroReaderConfig: MutableCluster.AsConditional( + AliroProvisioningComponent.commands.clearAliroReaderConfig, + { mandatoryIf: [ALIRO] } + ) }, events: { diff --git a/packages/types/src/clusters/ecosystem-information.ts b/packages/types/src/clusters/ecosystem-information.ts new file mode 100644 index 0000000000..7587b85353 --- /dev/null +++ b/packages/types/src/clusters/ecosystem-information.ts @@ -0,0 +1,200 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { TlvOptionalField, TlvField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvString } from "../tlv/TlvString.js"; +import { TlvEpochUs } from "../tlv/TlvNumber.js"; +import { TlvEndpointNumber } from "../datatype/EndpointNumber.js"; +import { TlvArray } from "../tlv/TlvArray.js"; +import { Descriptor } from "./descriptor.js"; +import { TlvFabricIndex } from "../datatype/FabricIndex.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { TlvLocationdesc } from "../globals/Locationdesc.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace EcosystemInformation { + /** + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1 + */ + export const TlvEcosystemDevice = TlvObject({ + /** + * This field shall indicate the device’s name, which is provided externally if the user consents. (For + * example, provided by the user in an ecosystem specific interface.) + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1.1 + */ + deviceName: TlvOptionalField(0, TlvString.bound({ maxLength: 64 })), + + /** + * This field shall be present and set if the DeviceName field is present. + * + * This field shall indicate the timestamp of when the DeviceName was last modified. + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1.2 + */ + deviceNameLastEdit: TlvOptionalField(1, TlvEpochUs), + + /** + * This field shall indicate the endpoint this EcosystemDeviceStruct is associated with on this Bridge. + * + * This field shall be present and set to a valid endpoint if the device is accessible through the bridge. + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1.3 + */ + bridgedEndpoint: TlvOptionalField(2, TlvEndpointNumber), + + /** + * This field shall indicate the endpoint this EcosystemDeviceStruct is associated with on the original device + * represented by this bridge’s Bridged Node. If this bridge is receiving the device from another bridge, then + * the OriginalEndpoint field value would be the same on both bridges. This field shall be present and set to a + * valid endpoint on the original device if that device is a Matter device. + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1.4 + */ + originalEndpoint: TlvOptionalField(3, TlvEndpointNumber), + + /** + * This field shall indicate all of the DeviceTypes within the DeviceTypeList in the Descriptor Cluster + * associated with this EcosystemDeviceStruct entry. + * + * This field shall contain a list of valid device type ids. + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1.5 + */ + deviceTypes: TlvField(4, TlvArray(Descriptor.TlvDeviceType)), + + /** + * This field shall specify the EcosystemLocationStruct entries in the LocationDirectory attribute associated + * with this EcosystemDeviceStruct. + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1.6 + */ + uniqueLocationIDs: TlvField(5, TlvArray(TlvString, { maxLength: 64 })), + + /** + * This field shall indicate the timestamp of when the UniqueLocationIDs was last modified. + * + * NOTE + * + * If multiple server instances update the UniqueLocationIDs field at the same time, it is possible one of the + * updates will be missed. This is considered an acceptable limitation to reduce the complexity of the design. + * Since this is meant to be provided from user input, it is unlikely these signals would be happening at one + * time. + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1.7 + */ + uniqueLocationIDsLastEdit: TlvField(6, TlvEpochUs), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 9.18.4.1 + */ + export interface EcosystemDevice extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 9.18.4.2 + */ + export const TlvEcosystemLocation = TlvObject({ + /** + * This field shall indicate a unique identifier for a specific Ecosystem Information Cluster server instance + * representing the location independent of its LocationDescriptor field. + * + * UniqueLocationID can be used by the client to determine if the change is a relocation of the device or just + * a renaming of the location. + * + * No guarantees are given for consistency of the ID between server instances. The same location may be + * represented by different IDs on different Ecosystem Information Cluster server instances, so only the + * history from a single server instance should be considered when evaluating a change. + * + * UniqueLocationID shall be changed when the LocationDescriptor changes from one existing location to another + * location as a result of an external interaction. (For example, the user changes the location assignment.) + * + * UniqueLocationID shall NOT be changed when the LocationDescriptor changes name, but still represents the + * same location. (For example, the user renames a room.) + * + * UniqueLocationID shall be changed when LocationDescriptor changes as a result of another Ecosystem + * Information Cluster server instance changing and the UniqueLocationID on the remote server instance also + * changes. + * + * UniqueLocationID shall NOT be changed when LocationDescriptor changes as a result of another Ecosystem + * Information Cluster server instance changing and the UniqueLocationID on the remote server instance does not + * change. + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.2.1 + */ + uniqueLocationId: TlvField(0, TlvString.bound({ maxLength: 64 })), + + /** + * This field shall indicate the location (e.g. living room, driveway) and associated metadata that is provided + * externally if the user consents. (For example, provided by the user in an ecosystem specific interface.) + * + * "Location" in this context is typically used by the user’s grouping into rooms, areas or other logical + * groupings of how devices are used. So a device might be part of multiple such "Locations"s. + * + * @see {@link MatterSpecification.v13.Core} § 9.18.4.2.2 + */ + locationDescriptor: TlvField(1, TlvLocationdesc), + + locationDescriptorLastEdit: TlvField(2, TlvEpochUs), + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 9.18.4.2 + */ + export interface EcosystemLocation extends TypeFromSchema {} + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster({ id: 0x750, name: "EcosystemInformation", revision: 1 }); + + /** + * The Ecosystem Information Cluster provides extended device information for all the logical devices represented + * by a Bridged Node. The Ecosystem Information Cluster presents the view of device name and location metadata for + * presentation by a client of the cluster to a user. This cluster is intended to support Fabric Synchronization + * and be present on an endpoint with the BridgedNode device type listed in the DeviceTypeList of the endpoint’s + * Descriptor cluster. + * + * This augments the Bridged Device Basic Information Cluster in the following ways: + * + * • The Ecosystem Information Cluster adds support for providing a name and location for individual endpoints. + * (The endpoints do not need to be present on the Bridge for their name and location information to be + * present.) + * + * • The Ecosystem Information Cluster adds metadata to support conflict resolution between multiple sources of + * the name and location data. + * + * • The Ecosystem Information Cluster supports user control for the presence of the name and location + * information by specifying more restricted access. + * + * A client SHOULD use the information provided by the Ecosystem Information Cluster to help the user organize and + * interact with their devices. Some examples may include: + * + * • Directly organizing and labeling the devices in a client’s user interface. + * + * • Providing hints in the user interface, which can assist the user in organizing and labeling their devices. + * + * For the purposes of the Ecosystem Information Cluster section, an instance of the Ecosystem Information Cluster + * will be referred to as an "instance". + * + * @see {@link MatterSpecification.v13.Core} § 9.18 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + export const Complete = Cluster; +} + +export type EcosystemInformationCluster = EcosystemInformation.Cluster; +export const EcosystemInformationCluster = EcosystemInformation.Cluster; +ClusterRegistry.register(EcosystemInformation.Complete); diff --git a/packages/types/src/clusters/electrical-energy-measurement.ts b/packages/types/src/clusters/electrical-energy-measurement.ts index 5ea4d2f004..dbc5e73b84 100644 --- a/packages/types/src/clusters/electrical-energy-measurement.ts +++ b/packages/types/src/clusters/electrical-energy-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -125,31 +125,31 @@ export namespace ElectricalEnergyMeasurement { endTimestamp: TlvOptionalField(2, TlvEpochS), /** - * This field shall indicate the seconds since boot at the beginning of the period during which the value of - * the Energy field was measured. + * This field shall indicate the time elapsed since boot at the beginning of the period during which the value + * of the Energy field was measured. * - * If this EnergyMeasurementStruct represents cumulative energy, this field shall be omitted. + * If this EnergyMeasurementStruct represents cumulative energy, this field shall be omitted. Otherwise, if the + * server had not yet determined the time in UTC at the start of the measurement * - * Otherwise, if the server had not yet determined the time in UTC at the start of the measurement period, or - * does not have the capability of determining the time in UTC, this field shall be indicated. + * period, or does not have the capability of determining the time in UTC, this field shall be indicated. * * Otherwise, if the server had determined the time in UTC at or before the beginning of the measurement - * period, this field may be omitted; if it is indicated, its value shall be the seconds since boot at the UTC - * time indicated in StartTimestamp. + * period, this field may be omitted; if it is indicated, its value shall be the time elapsed since boot at the + * UTC time indicated in StartTimestamp. * * @see {@link MatterSpecification.v13.Cluster} § 2.12.5.1.4 */ startSystime: TlvOptionalField(3, TlvSysTimeMS), /** - * This field shall indicate the seconds since boot at the end of the period during which the value of the + * This field shall indicate the time elapsed since boot at the end of the period during which the value of the * Energy field was measured. * * If the server had not yet determined the time in UTC by the end of the measurement period, or does not have * the capability of determining the time in UTC, this field shall be indicated. * * Otherwise, if the server had determined the time in UTC by the end of the measurement period, this field may - * be omitted; if it is indicated, its value shall be the seconds since boot at the UTC time indicated in + * be omitted; if it is indicated, its value shall be the time elapsed since boot at the UTC time indicated in * EndTimestamp. * * @see {@link MatterSpecification.v13.Cluster} § 2.12.5.1.5 @@ -200,9 +200,8 @@ export namespace ElectricalEnergyMeasurement { * This field shall indicate the timestamp in UTC when the value of the Energy field on the * CumulativeEnergyExported attribute was most recently zero. * - * If the server had determined the time in UTC when the value of the Energy field on the Cumula - * - * tiveEnergyExported attribute was most recently zero, this field shall be indicated. + * If the server had determined the time in UTC when the value of the Energy field on the + * CumulativeEnergyExported attribute was most recently zero, this field shall be indicated. * * Otherwise, if the server had not yet determined the time in UTC when the value of the Energy field on the * CumulativeEnergyExported attribute was most recently zero, or does not have the capability of determining @@ -216,7 +215,7 @@ export namespace ElectricalEnergyMeasurement { exportedResetTimestamp: TlvOptionalField(1, TlvNullable(TlvEpochS)), /** - * This field shall indicate the seconds since boot when the value of the Energy field on the + * This field shall indicate the time elapsed since boot when the value of the Energy field on the * CumulativeEnergyImported attribute was most recently zero. * * If the server had not yet determined the time in UTC when the value of the Energy field on the @@ -225,14 +224,14 @@ export namespace ElectricalEnergyMeasurement { * * Otherwise, if the server had determined the time in UTC when the value of the Energy field on the * CumulativeEnergyImported attribute was most recently zero, this field may be omitted; if it is indicated, - * its value shall be the seconds since boot at the UTC time indicated in ImportedResetTimestamp. + * its value shall be the time elapsed since boot at the UTC time indicated in ImportedResetTimestamp. * * @see {@link MatterSpecification.v13.Cluster} § 2.12.5.2.3 */ importedResetSystime: TlvOptionalField(2, TlvNullable(TlvSysTimeMS)), /** - * This field shall indicate the seconds since boot when the value of the Energy field on the + * This field shall indicate the time elapsed since boot when the value of the Energy field on the * CumulativeEnergyExported attribute was most recently zero. * * If the server had not yet determined the time in UTC when the value of the Energy field on the @@ -241,7 +240,7 @@ export namespace ElectricalEnergyMeasurement { * * Otherwise, if the server had determined the time in UTC when the value of the Energy field on the * CumulativeEnergyExported attribute was most recently zero, this field may be omitted; if it is indicated, - * its value shall be the seconds since boot at the UTC time indicated in ImportedResetTimestamp. + * its value shall be the time elapsed since boot at the UTC time indicated in ImportedResetTimestamp. * * @see {@link MatterSpecification.v13.Cluster} § 2.12.5.2.4 */ diff --git a/packages/types/src/clusters/electrical-power-measurement.ts b/packages/types/src/clusters/electrical-power-measurement.ts index 9f339271e1..09c5a76c7a 100644 --- a/packages/types/src/clusters/electrical-power-measurement.ts +++ b/packages/types/src/clusters/electrical-power-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/energy-evse-mode.ts b/packages/types/src/clusters/energy-evse-mode.ts index 7c1f66341a..c6d4cd8eea 100644 --- a/packages/types/src/clusters/energy-evse-mode.ts +++ b/packages/types/src/clusters/energy-evse-mode.ts @@ -1,29 +1,21 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; -import { - WritableAttribute, - FixedAttribute, - Attribute, - OptionalWritableAttribute, - Command, - TlvNoResponse -} from "../cluster/Cluster.js"; -import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; -import { TlvNullable } from "../tlv/TlvNullable.js"; import { BitFlag } from "../schema/BitmapSchema.js"; +import { FixedAttribute, Attribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; +import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -31,114 +23,108 @@ export namespace EnergyEvseMode { /** * These are optional features supported by EnergyEvseModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } export enum ModeTag { /** - * While in this mode, the EVSE needs to be sent an EnableEvseCharging or EnableEvseDischarging command to make - * the EVSE start charging or discharging. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.4.4.1.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - Manual = 16384, + Auto = 0, /** - * While in this mode, the EVSE will attempt to automatically start charging based on the user’s charging - * targets and a Time of Use tariff to charge at the cheapest times of the day. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.4.4.1.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - TimeOfUse = 16385, + Quick = 1, /** - * While in this mode, the EVSE will attempt to automatically start charging based on available excess solar PV - * generation, limiting the charging power to avoid imported energy from the grid. - * - * @see {@link MatterSpecification.v13.Cluster} § 9.4.4.1.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - SolarCharging = 16386, + Quiet = 2, /** - * The device decides which options, features and setting values to use. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - Auto = 0, + LowNoise = 3, /** - * The mode of the device is optimizing for faster completion. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - Quick = 1, + LowEnergy = 4, /** - * The device is silent or barely audible while in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - Quiet = 2, + Vacation = 5, /** - * Either the mode is inherently low noise or the device optimizes for that. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - LowNoise = 3, + Min = 6, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - LowEnergy = 4, + Max = 7, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 */ - Vacation = 5, + Night = 8, /** - * The mode uses the lowest available setting value. + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1 + */ + Day = 9, + + /** + * While in modes with this tag, and once enabled with the EnableCharging command, the EVSE will permit + * charging based on demand from the EV. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1.1 */ - Min = 6, + Manual = 16384, /** - * The mode uses the highest available setting value. + * While in modes with this tag, and once enabled with the EnableCharging command, the EVSE will attempt to + * automatically start charging based on the user’s charging targets (for example, set based on a Time of Use + * tariff to charge at the cheapest times of the day). * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1.2 */ - Max = 7, + TimeOfUse = 16385, /** - * The mode is recommended or suitable for use during night time. + * While in modes with this tag, and once enabled with the EnableCharging, the EVSE will attempt to + * + * automatically start charging based on available excess solar PV generation, limiting the charging power to + * avoid importing energy from the grid. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1.3 */ - Night = 8, + SolarCharging = 16386, /** - * The mode is recommended or suitable for use during day time. + * While in modes with this tag, and once enabled with the EnableDischarging command, the EVSE will permit + * discharging based on the current charge state of the EV, and its control from an associated Device Energy + * Management cluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * NOTE + * + * being in a mode with this tag set or not does not affect the handling of the EnableDischarging command by + * the Energy EVSE cluster, but once enabled, only modes with this tag enable the discharging to actually occur. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.4.7.1.4 */ - Day = 9 + V2X = 16387 } /** @@ -168,7 +154,7 @@ export namespace EnergyEvseMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -179,9 +165,10 @@ export namespace EnergyEvseMode { export interface ModeTagStruct extends TypeFromSchema {} /** - * This is a struct representing a possible mode of the server. + * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. + * A blank field indicates no change. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.5.1 */ export const TlvModeOption = TlvObject({ /** @@ -240,94 +227,55 @@ export namespace EnergyEvseMode { }); /** - * This is a struct representing a possible mode of the server. + * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. + * A blank field indicates no change. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.5.1 */ export interface ModeOption extends TypeFromSchema {} - /** - * A EnergyEvseModeCluster supports these elements if it supports feature OnOff. - */ - export const OnOffComponent = MutableCluster.Component({ - attributes: { - /** - * Indicates whether the value of CurrentMode depends on the state of the On/Off cluster on the same - * endpoint. If this attribute is not present or is set to null, there is no dependency, otherwise the - * CurrentMode attribute shall depend on the OnOff attribute in the On/Off cluster - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.5 - */ - onMode: WritableAttribute(0x3, TlvNullable(TlvUInt8), { persistent: true, default: null }) - } - }); - /** * These elements and properties are present in all EnergyEvseMode clusters. */ export const Base = MutableCluster.Component({ id: 0x9d, name: "EnergyEvseMode", - revision: 1, + revision: 2, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * This attribute shall contain the list of supported modes that may be selected for the CurrentMode - * attribute. Each item in this list represents a unique mode as indicated by the Mode field of the - * ModeOptionStruct. + * At least one entry in the SupportedModes attribute shall include the Manual mode tag in the ModeTags + * field list. * - * Each entry in this list shall have a unique value for the Mode field. Each entry in this list shall have - * a unique value for the Label field. + * Modes with entries in the SupportedModes attribute which contain multiple mode tags permitting * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.2 - */ - supportedModes: FixedAttribute(0x0, TlvArray(TlvModeOption, { minLength: 2, maxLength: 255 })), - - /** - * Indicates the current mode of the server. - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. + * charging or discharging under different conditions shall permit the charging or discharging to occur if + * any of the conditions are satisfied. * - * The value of this attribute may change at any time via an out-of-band interaction outside of the server, - * such as interactions with a user interface, via internal mode changes due to autonomously progressing - * through a sequence of operations, on system time-outs or idle delays, or via interactions coming from a - * fabric other than the one which last executed a ChangeToMode. + * Modes shall NOT have both the Manual tag and the TimeOfUse or SolarCharging tags defined in the + * SupportedModes attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.6.1 */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }), + supportedModes: FixedAttribute( + 0x0, + TlvArray(TlvModeOption, { minLength: 2, maxLength: 255 }), + { default: [] } + ), /** - * Indicates the desired startup mode for the server when it is supplied with power. - * - * If this attribute is not null, the CurrentMode attribute shall be set to the StartUpMode value, when the - * server is powered up, except in the case when the OnMode attribute overrides the StartUpMode attribute - * (see OnModeWithPowerUp). - * - * This behavior does not apply to reboots associated with OTA. After an OTA restart, the CurrentMode - * attribute shall return to its value prior to the restart. - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. - * - * If this attribute is not implemented, or is set to the null value, it shall have no effect. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.4.6 */ - startUpMode: OptionalWritableAttribute(0x2, TlvNullable(TlvUInt8), { persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, commands: { @@ -345,7 +293,7 @@ export namespace EnergyEvseMode { * This metadata controls which EnergyEvseModeCluster elements matter.js activates for specific feature * combinations. */ - extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: OnOffComponent }) + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -354,8 +302,8 @@ export namespace EnergyEvseMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster which also defines a namespace for the operation of EVSE - * devices. + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated + * values for EVSE devices. * * EnergyEvseModeCluster supports optional features that you can enable with the EnergyEvseModeCluster.with() * factory method. @@ -365,32 +313,7 @@ export namespace EnergyEvseMode { export interface Cluster extends Identity {} export const Cluster: Cluster = ClusterInstance; - const DEPONOFF = { onOff: true }; - - /** - * @see {@link Complete} - */ - export const CompleteInstance = MutableCluster({ - id: Cluster.id, - name: Cluster.name, - revision: Cluster.revision, - features: Cluster.features, - attributes: { - ...Cluster.attributes, - onMode: MutableCluster.AsConditional(OnOffComponent.attributes.onMode, { mandatoryIf: [DEPONOFF] }) - }, - commands: Cluster.commands - }); - - /** - * This cluster supports all EnergyEvseMode features. It may support illegal feature combinations. - * - * If you use this cluster you must manually specify which features are active and ensure the set of active - * features is legal per the Matter specification. - */ - export interface Complete extends Identity {} - - export const Complete: Complete = CompleteInstance; + export const Complete = Cluster; } export type EnergyEvseModeCluster = EnergyEvseMode.Cluster; diff --git a/packages/types/src/clusters/energy-evse.ts b/packages/types/src/clusters/energy-evse.ts index 98859349b7..3c28cea2cc 100644 --- a/packages/types/src/clusters/energy-evse.ts +++ b/packages/types/src/clusters/energy-evse.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -53,19 +53,19 @@ export namespace EnergyEvse { * specify how many miles or km of additional range they need for their typical daily commute. This range * requirement can be converted into a daily energy demand with a target charging completion time. * - * The EVSE itself may use this information (or may allow a controller such as an EMS) to compute an + * The EVSE itself can use this information (or may allow a controller such as an EMS) to compute an optimized + * charging schedule. * - * optimized charging schedule. - * - * An EVSE device may implement the Device Energy Management cluster PFR (Power Forecast Reporting) and FA - * (Forecast Adjustment) features. This can help a controller (such as an EMS) to optimize the EVSE against - * other ESAs. For example, a solar PV ESA may share its Forecast and allow the EVSE to know the best time to - * charge so that any excess solar generation is used to charge the EV. + * An EVSE device which includes a Device Energy Management device with the Device Energy Management cluster + * PFR (Power Forecast Reporting) feature can use the charging preferences information to produce its power + * forecast. * * EVSE devices that support the Device Energy Management cluster’s FA feature can have their charging profiles * set by a controller device such as an EMS. For example, if the EVSE advertises a simple power forecast which * allows the EMS to adjust over a wide range of power and time durations, then the EVSE may allow the EMS to - * propose a revised optimized forecast (which is the charging profile). + * propose a revised optimized forecast (which is the charging profile). For example, a solar PV ESA may also + * share its Forecast, so enabling an EMS to adjust the EVSE forecast to the best time to charge so that any + * excess solar generation is used to charge the EV. * * See the Device Energy Management Cluster for more details. * @@ -124,6 +124,12 @@ export namespace EnergyEvse { * If the EVSE can support bi-directional charging, it may be possible to request that the vehicle can * discharge to the home or grid. * + * The charging and discharging may be controlled by a home Energy Management System (EMS) using the Device + * Energy Management cluster of the associated Device Energy Management device. For example, an EMS may use the + * PA (Power Adjustment) feature to continually adjust the charge/discharge current to/from the EV so as to + * minimise the energy flow from/to the grid as the demand in the home and the solar supply to the home both + * fluctuate. + * * @see {@link MatterSpecification.v13.Cluster} § 9.3.4.5 */ V2X = "V2X" @@ -138,7 +144,8 @@ export namespace EnergyEvse { /** * This field shall indicate the expiry time, in UTC, when discharging will be automatically disabled. * - * A value in the past in this field shall disable the EVSE whereas a null value shall enable it permanently. + * A value in the past in this field shall disable the EVSE discharging whereas a null value shall enable EVSE + * discharging permanently. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.9.3.1 */ @@ -147,9 +154,7 @@ export namespace EnergyEvse { /** * This field shall indicate the maximum current that can be received by the EVSE from the EV. The EVSE current * limit can be advertised to an EV in 0.6A steps. The value of the MaximumDischargeCurrent attribute shall be - * stored and persisted across reboots by the EVSE to the value of this - * - * field. + * stored and persisted across reboots by the EVSE to the value of this field. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.9.3.2 */ @@ -164,7 +169,7 @@ export namespace EnergyEvse { export interface EnableDischargingRequest extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.5 + * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.1 */ export const TargetDayOfWeek = { /** @@ -251,7 +256,7 @@ export namespace EnergyEvse { * This field represents the target SoC that the vehicle should be charged to before the * TargetTimeMinutesPastMidnight. * - * If the EVSE can obtain the SoC of the vehicle: + * If the EVSE supports the SOC feature and can obtain the SoC of the vehicle: * * • the TargetSoC field shall take precedence over the AddedEnergy field. * @@ -261,13 +266,14 @@ export namespace EnergyEvse { * • if the TargetSoC value is set to 100% then the EVSE SHOULD continue to charge the vehicle until the * vehicle decides to stop charging. * - * If the EVSE cannot obtain the SoC of the vehicle: + * If the EVSE does not support the SOC feature or cannot obtain the SoC of the vehicle: + * + * • the AddedEnergy field shall take precedence over the TargetSoC field, and if the EVSE does not support + * the SOC feature then the TargetSoC field may only take the values null or 100%. * - * • in this case, the AddedEnergy field shall take precedence over the TargetSoC field, and the TargetSoC - * field may only take the values null or 100%. + * • if the AddedEnergy field has not been provided, the EVSE SHOULD assume the vehicle is empty * - * • if the AddedEnergy field has not been provided, the EVSE SHOULD assume the vehicle is empty and charge - * until the vehicle stops demanding a charge. + * and charge until the vehicle stops demanding a charge. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.6.2 */ @@ -289,7 +295,7 @@ export namespace EnergyEvse { * * NOTE * - * If the EVSE can obtain the Battery Capacity of the vehicle, it SHOULD not limit this AddedEnergy value to + * If the EVSE can obtain the Battery Capacity of the vehicle, it SHOULD NOT limit this AddedEnergy value to * the Battery Capacity of the vehicle, since the EV may also require energy for heating and cooling of the * battery during charging, or for heating or cooling the cabin. * @@ -322,8 +328,20 @@ export namespace EnergyEvse { * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.7 */ export const TlvChargingTargetSchedule = TlvObject({ - dayOfWeekForSequence: TlvOptionalField(0, TlvBitmap(TlvUInt8, TargetDayOfWeek)), - chargingTargets: TlvOptionalField(1, TlvArray(TlvChargingTarget, { maxLength: 10 })) + /** + * This field shall indicate the days of the week that the charging targets SHOULD be associated to. This field + * is a bitmap and therefore the associated targets could be applied to multiple days. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.8 + */ + dayOfWeekForSequence: TlvField(0, TlvBitmap(TlvUInt8, TargetDayOfWeek)), + + /** + * This field shall indicate a list of up to 10 charging targets for each of the associated days of the week. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.9 + */ + chargingTargets: TlvField(1, TlvArray(TlvChargingTarget, { maxLength: 10 })) }); /** @@ -400,7 +418,7 @@ export namespace EnergyEvse { export interface RfidEvent extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.2 */ export enum State { /** @@ -440,7 +458,7 @@ export namespace EnergyEvse { } /** - * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.3 */ export enum SupplyState { /** @@ -465,13 +483,18 @@ export namespace EnergyEvse { DisabledError = 3, /** - * The EV is not currently allowed to charge or discharge due to Diagnostics Mode. + * The EV is not currently allowed to charge or discharge due to self- diagnostics mode. */ - DisabledDiagnostics = 4 + DisabledDiagnostics = 4, + + /** + * The EV is currently allowed to charge and discharge + */ + Enabled = 5 } /** - * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.4 */ export enum FaultState { /** @@ -592,10 +615,9 @@ export namespace EnergyEvse { * limit can be advertised to an EV in 0.6A steps. * * The value of the this field shall be stored by the EVSE to determine the value of MaximumChargeCurrent - * attribute. For example, if the UserMaximumChargeCurrent attribute is adjusted below then - * - * this value, and then later adjusted above this value, the resulting MaximumChargeCurrent attribute will be - * limited to this value. + * attribute. For example, if the UserMaximumChargeCurrent attribute is adjusted below then this value, and + * then later adjusted above this value, the resulting MaximumChargeCurrent attribute will be limited to this + * value. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.9.2.3 */ @@ -660,7 +682,6 @@ export namespace EnergyEvse { /** * This field shall indicate the total amount of energy transferred from the EVSE to the EV during the session. - * This value shall always be positive. * * Note that if bi-directional charging occurs during the session, then this value shall only include the sum * of energy transferred from the EVSE to the EV, and shall NOT be a net value of charging and discharging @@ -672,7 +693,6 @@ export namespace EnergyEvse { /** * This field shall indicate the total amount of energy transferred from the EV to the EVSE during the session. - * This value shall always be positive. * * Note that if bi-directional discharging occurs during the session, then this value shall only include the * sum of energy transferred from the EV to the EVSE, and shall NOT be a net value of charging and discharging @@ -711,19 +731,25 @@ export namespace EnergyEvse { state: TlvField(1, TlvEnum()), /** - * This field shall indicate the value of the maximum charging or discharging current at the time the event was - * generated. + * This field shall indicate the value of the maximum charging current at the time the event was generated. * - * This field is signed. A positive value indicates the EV has been enabled for charging and the value is taken - * directly from the MaximumChargeCurrent attribute. - * - * A negative value indicates that the EV has been enabled for discharging and the value can be taken from the - * MaximumDischargeCurrent attribute with its sign inverted. i.e. if the MaximumDischargeCurrent was 32000mA, - * this would be represented here as -32000mA. + * A non-zero value indicates that the EV has been enabled for charging and the value is taken directly from + * the MaximumChargeCurrent attribute. A zero value indicates that the EV has not been enabled for charging. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.10.3.3 */ - maximumCurrent: TlvField(2, TlvInt64.bound({ min: 0 })) + maximumCurrent: TlvField(2, TlvInt64.bound({ min: 0 })), + + /** + * This field shall indicate the value of the maximum discharging current at the time the event was generated. + * + * A non-zero value indicates that the EV has been enabled for discharging and the value is taken directly from + * the MaximumDischargeCurrent attribute. A zero value indicates that the EV has not been enabled for + * discharging. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.3.10.3.4 + */ + maximumDischargeCurrent: TlvOptionalField(3, TlvInt64.bound({ min: 0 })) }); /** @@ -734,7 +760,7 @@ export namespace EnergyEvse { export interface EnergyTransferStartedEvent extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.3.7.5 */ export enum EnergyTransferStoppedReason { /** @@ -780,7 +806,21 @@ export namespace EnergyEvse { */ reason: TlvField(2, TlvEnum()), - energyTransferred: TlvField(4, TlvInt64.bound({ min: 0 })) + /** + * This field shall indicate the amount of energy transferred from the EVSE to the EV since the previous + * EnergyTransferStarted event, in mWh. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.3.10.4.4 + */ + energyTransferred: TlvField(4, TlvInt64.bound({ min: 0 })), + + /** + * This field shall indicate the amount of energy transferred from the EV to the EVSE since the previous + * EnergyTransferStarted event, in mWh. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.3.10.4.5 + */ + energyDischarged: TlvOptionalField(5, TlvInt64.bound({ min: 0 })) }); /** @@ -881,7 +921,8 @@ export namespace EnergyEvse { commands: { /** - * Allows a client to enable the EVSE to discharge an EV. + * Upon receipt, this shall allow a client to enable the discharge of an EV, and to provide or update the + * maximum discharge current. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.9.3 */ @@ -898,7 +939,9 @@ export namespace EnergyEvse { * Indicates the time, in UTC, when the EVSE plans to start the next scheduled charge based on the charging * preferences. * - * If this is null it indicates that there is no scheduled charging, or that the vehicle is not plugged in. + * A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to use + * Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that charging is + * enabled. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.8.12 */ @@ -908,7 +951,9 @@ export namespace EnergyEvse { * Indicates the time, in UTC, when the EVSE SHOULD complete the next scheduled charge based on the * charging preferences. * - * If this is null it indicates that there is no scheduled charging, or that the vehicle is not plugged in. + * A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to use + * Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that charging is + * enabled. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.8.13 */ @@ -918,8 +963,9 @@ export namespace EnergyEvse { * Indicates the amount of energy that the EVSE is going to attempt to add to the vehicle in the next * charging target. * - * If this is null it indicates that there is no scheduled charging, or that the EVSE is using the - * TargetSoC method to charge the vehicle. + * A null value indicates that there is no scheduled charging (for example, the EVSE Mode is set to use + * Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that charging is + * enabled, or that the next ChargingTargetStruct is using the TargetSoC value to charge the vehicle. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.8.14 */ @@ -928,8 +974,10 @@ export namespace EnergyEvse { /** * Indicates the target SoC the EVSE is going to attempt to reach when the vehicle is next charged. * - * If this is null it indicates that there is no scheduled charging, or that the EVSE cannot obtain the - * current State of Charge from the vehicle. + * A null value indicates that there is no scheduled charging + * + * Manual mode tag), or that the vehicle is not plugged in with the SupplyState indicating that charging is + * enabled, or that the next ChargingTargetStruct is using the AddedEnergy value to charge the vehicle. * * If the SOC feature is not supported, only the values null and 100% are supported. * @@ -961,7 +1009,9 @@ export namespace EnergyEvse { * * AddedRange (km) = 10,000 x 4800 / 1,000,000 = 48 km * - * AddedRange (Miles) = AddedEnergy (Wh) x ApproxEVEfficiency (km/kWh x 1000) x 0.6213 + * AddedRange (Miles) = AddedEnergy (Wh) x ApproxEVEfficiency (km/kWh x 1000) x + * + * 0.6213 * * = 29.82 Miles * @@ -1061,7 +1111,7 @@ export namespace EnergyEvse { export const Base = MutableCluster.Component({ id: 0x99, name: "EnergyEvse", - revision: 2, + revision: 3, features: { /** @@ -1073,19 +1123,19 @@ export namespace EnergyEvse { * This range requirement can be converted into a daily energy demand with a target charging completion * time. * - * The EVSE itself may use this information (or may allow a controller such as an EMS) to compute an - * + * The EVSE itself can use this information (or may allow a controller such as an EMS) to compute an * optimized charging schedule. * - * An EVSE device may implement the Device Energy Management cluster PFR (Power Forecast Reporting) and FA - * (Forecast Adjustment) features. This can help a controller (such as an EMS) to optimize the EVSE against - * other ESAs. For example, a solar PV ESA may share its Forecast and allow the EVSE to know the best time - * to charge so that any excess solar generation is used to charge the EV. + * An EVSE device which includes a Device Energy Management device with the Device Energy Management + * cluster PFR (Power Forecast Reporting) feature can use the charging preferences information to produce + * its power forecast. * * EVSE devices that support the Device Energy Management cluster’s FA feature can have their charging * profiles set by a controller device such as an EMS. For example, if the EVSE advertises a simple power * forecast which allows the EMS to adjust over a wide range of power and time durations, then the EVSE may - * allow the EMS to propose a revised optimized forecast (which is the charging profile). + * allow the EMS to propose a revised optimized forecast (which is the charging profile). For example, a + * solar PV ESA may also share its Forecast, so enabling an EMS to adjust the EVSE forecast to the best + * time to charge so that any excess solar generation is used to charge the EV. * * See the Device Energy Management Cluster for more details. * @@ -1144,6 +1194,12 @@ export namespace EnergyEvse { * If the EVSE can support bi-directional charging, it may be possible to request that the vehicle can * discharge to the home or grid. * + * The charging and discharging may be controlled by a home Energy Management System (EMS) using the Device + * Energy Management cluster of the associated Device Energy Management device. For example, an EMS may use + * the PA (Power Adjustment) feature to continually adjust the charge/discharge current to/from the EV so + * as to minimise the energy flow from/to the grid as the demand in the home and the solar supply to the + * home both fluctuate. + * * @see {@link MatterSpecification.v13.Cluster} § 9.3.4.5 */ v2X: BitFlag(4) @@ -1159,10 +1215,12 @@ export namespace EnergyEvse { * * NOTE * - * SessionEnding is not really a state but a transition. However, the transition period + * SessionEnding is not really a state but a transition. However, the transition period may take a few + * seconds and is useful for some clean up purposes. + * + * The Fault state is used to indicate that the FaultState attribute is not NoError. * - * may take a few seconds and is useful for some clean up purposes. The Fault state is used to indicate - * that the FaultState attribute is not NoError. + * A null value shall indicate that the state cannot be determined. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.8.1 */ @@ -1211,8 +1269,9 @@ export namespace EnergyEvse { circuitCapacity: Attribute(0x5, TlvInt64.bound({ min: 0 }), { persistent: true, default: 0 }), /** - * Indicates the minimum current that can be delivered by the EVSE to the EV. The attribute can be set - * using the EnableCharging command. + * Indicates the minimum current that can be delivered by the EVSE to the EV. + * + * The attribute can be set using the EnableCharging command. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.8.7 */ @@ -1281,7 +1340,7 @@ export namespace EnergyEvse { */ randomizationDelayWindow: OptionalWritableAttribute( 0xa, - TlvUInt32.bound({ min: 0, max: 86400 }), + TlvUInt32.bound({ max: 86400 }), { persistent: true, default: 600, writeAcl: AccessLevel.Manage } ), @@ -1314,7 +1373,8 @@ export namespace EnergyEvse { disable: Command(0x1, TlvNoArguments, 0x1, TlvNoResponse, { timed: true }), /** - * Allows a client to enable the EVSE to charge an EV. + * This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum + * and minimum charge current. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.9.2 */ @@ -1345,14 +1405,18 @@ export namespace EnergyEvse { evNotDetected: Event(0x1, EventPriority.Info, TlvEvNotDetectedEvent), /** - * This event shall be generated when the EV starts charging or discharging. + * This event shall be generated whenever the EV starts charging or discharging, except when an EV has + * switched between charging and discharging under the control of the PowerAdjustment feature of the Device + * Energy Management cluster of the associated Device Energy Management device. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.10.3 */ energyTransferStarted: Event(0x2, EventPriority.Info, TlvEnergyTransferStartedEvent), /** - * This event shall be generated when the EV stops charging or discharging. + * This event shall be generated whenever the EV stops charging or discharging, except when an EV has + * switched between charging and discharging under the control of the PowerAdjustment feature of the Device + * Energy Management cluster of the associated Device Energy Management device. * * @see {@link MatterSpecification.v13.Cluster} § 9.3.10.4 */ @@ -1383,7 +1447,8 @@ export namespace EnergyEvse { { flags: { chargingPreferences: true }, component: ChargingPreferencesComponent }, { flags: { soCReporting: true }, component: SoCReportingComponent }, { flags: { plugAndCharge: true }, component: PlugAndChargeComponent }, - { flags: { rfid: true }, component: RfidComponent } + { flags: { rfid: true }, component: RfidComponent }, + { flags: { chargingPreferences: false }, component: false } ) }); @@ -1403,8 +1468,9 @@ export namespace EnergyEvse { * IEC61841 define Pilot signal as a modulated DC voltage on a single wire. * * Power Line Communication (PLC) is supported by some EVSEs (e.g. for support of ISO 15118 in Europe and SAE - * J2931/4 in NA) and may enable features such as Vehicle to Grid (V2G) or Vehicle to Home (V2H) that allows for - * bi-directional charging/discharging of electric vehicles. + * J2931/4 in NA) and may enable features such as Vehicle to Grid (V2G) or Vehicle to + * + * Home (V2H) that allows for bi-directional charging/discharging of electric vehicles. * * More modern EVSE devices may optionally support ISO 15118-20 in Europe and SAE J2836/3 for NA to support * bi-directional charging (Vehicle to Grid - V2G) and Plug and Charge capabilities. diff --git a/packages/types/src/clusters/energy-preference.ts b/packages/types/src/clusters/energy-preference.ts index 1cce550c8e..1f567ada5a 100644 --- a/packages/types/src/clusters/energy-preference.ts +++ b/packages/types/src/clusters/energy-preference.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -21,7 +21,7 @@ export namespace EnergyPreference { /** * These are optional features supported by EnergyPreferenceCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.4 */ export enum Feature { /** @@ -30,7 +30,7 @@ export namespace EnergyPreference { * This feature allows a user to select from a list of energy balances with associated descriptions of which * strategies a device will use to target the specified balance. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.4.1 */ EnergyBalance = "EnergyBalance", @@ -41,7 +41,7 @@ export namespace EnergyPreference { * switch to a mode using less power. For example, a device might provide a scale of durations that must elapse * without user interaction before it goes to sleep. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.4.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.4.2 */ LowPowerModeSensitivity = "LowPowerModeSensitivity" } @@ -49,13 +49,13 @@ export namespace EnergyPreference { /** * This represents a step along a scale of preferences. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.5.2 */ export const TlvBalance = TlvObject({ /** * This field shall indicate the relative value of this step. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.5.2.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.5.2.1 */ step: TlvField(0, TlvPercent), @@ -63,7 +63,7 @@ export namespace EnergyPreference { * This field shall indicate an optional string explaining which actions a device might take at the given step * value. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.5.2.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.5.2.2 */ label: TlvOptionalField(1, TlvString.bound({ maxLength: 64 })) }); @@ -71,36 +71,45 @@ export namespace EnergyPreference { /** * This represents a step along a scale of preferences. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.5.2 */ export interface Balance extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Cluster} § 9.5.5.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.5.1 */ export enum EnergyPriority { /** + * User comfort + * * This value shall emphasize user comfort; e.g. local temperature for a thermostat. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.5.1.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.5.1.1 */ Comfort = 0, /** + * Speed of operation + * * This value shall emphasize how quickly a device accomplishes its targeted use; e.g. how quickly a robot * vacuum completes a cleaning cycle. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.5.1.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.5.1.2 */ Speed = 1, /** + * Amount of Energy consumed by the device + * * This value shall emphasize how much energy a device uses; e.g. electricity usage for a Pump. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.5.1.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.5.1.3 */ Efficiency = 2, + /** + * Amount of water consumed by the device + */ WaterConsumption = 3 } @@ -110,12 +119,11 @@ export namespace EnergyPreference { export const EnergyBalanceComponent = MutableCluster.Component({ attributes: { /** - * Indicates a list of BalanceStructs, each representing a step along a linear scale - * - * of relative priorities. A Step field with a value of zero shall indicate that the device SHOULD entirely - * favor the priority specified by the first element in EnergyPriorities; whereas a Step field with a value - * of 100 shall indicate that the device SHOULD entirely favor the priority specified by the second element - * in EnergyPriorities. The midpoint value of 50 shall indicate an even split between the two priorities. + * Indicates a list of BalanceStructs, each representing a step along a linear scale of relative + * priorities. A Step field with a value of zero shall indicate that the device SHOULD entirely favor the + * priority specified by the first element in EnergyPriorities; whereas a Step field with a value of 100 + * shall indicate that the device SHOULD entirely favor the priority specified by the second element in + * EnergyPriorities. The midpoint value of 50 shall indicate an even split between the two priorities. * * This shall contain at least two BalanceStructs. * @@ -125,7 +133,7 @@ export namespace EnergyPreference { * The first BalanceStruct shall have a Step value of zero, and the last BalanceStruct shall have a Step * value of 100. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.6.1 */ energyBalances: FixedAttribute(0x0, TlvArray(TlvBalance, { minLength: 2, maxLength: 10 })), @@ -150,7 +158,7 @@ export namespace EnergyPreference { * last element in EnergyPriorities, the new value of CurrentEnergyBalance shall be the index of the * last element in the updated value of EnergyBalances. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.6.2 */ currentEnergyBalance: WritableAttribute(0x1, TlvUInt8, { persistent: true }), @@ -161,7 +169,7 @@ export namespace EnergyPreference { * If the value of EnergyPriorities changes after an update to represent a new balance between priorities, * the value of the CurrentEnergyBalance attribute shall be set to its default. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.6.3 */ energyPriorities: FixedAttribute(0x2, TlvArray(TlvEnum(), { length: 2 })) } @@ -174,14 +182,12 @@ export namespace EnergyPreference { attributes: { /** * Indicates a list of BalanceStructs, each representing a condition or set of conditions for the device to - * enter a low power mode. - * - * This shall contain at least two BalanceStructs. + * enter a low power mode. This shall contain at least two BalanceStructs. * * Each BalanceStruct shall have a Step field larger than the Step field on the previous BalanceStruct in * the list. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.4 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.6.4 */ lowPowerModeSensitivities: FixedAttribute(0x3, TlvArray(TlvBalance, { minLength: 2, maxLength: 10 })), @@ -197,7 +203,7 @@ export namespace EnergyPreference { * the LowPowerModeSensitivity attribute to the index which the manufacturer specifies most closely matches * the previous value. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.5 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.6.5 */ currentLowPowerModeSensitivity: WritableAttribute(0x4, TlvUInt8, { persistent: true }) } @@ -218,7 +224,7 @@ export namespace EnergyPreference { * This feature allows a user to select from a list of energy balances with associated descriptions of * which strategies a device will use to target the specified balance. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.4.1 */ energyBalance: BitFlag(0), @@ -229,7 +235,7 @@ export namespace EnergyPreference { * switch to a mode using less power. For example, a device might provide a scale of durations that must * elapse without user interaction before it goes to sleep. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5.4.2 + * @see {@link MatterSpecification.v13.Cluster} § 9.7.4.2 */ lowPowerModeSensitivity: BitFlag(1) }, @@ -258,7 +264,7 @@ export namespace EnergyPreference { * Per the Matter specification you cannot use {@link EnergyPreferenceCluster} without enabling certain feature * combinations. You must use the {@link with} factory method to obtain a working cluster. * - * @see {@link MatterSpecification.v13.Cluster} § 9.5 + * @see {@link MatterSpecification.v13.Cluster} § 9.7 */ export interface Cluster extends Identity {} diff --git a/packages/types/src/clusters/ethernet-network-diagnostics.ts b/packages/types/src/clusters/ethernet-network-diagnostics.ts index 489693c611..e01788d2a1 100644 --- a/packages/types/src/clusters/ethernet-network-diagnostics.ts +++ b/packages/types/src/clusters/ethernet-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -126,9 +126,7 @@ export namespace EthernetNetworkDiagnostics { attributes: { /** * The TxErrCount attribute shall indicate the number of failed packet transmissions that have occurred on - * the ethernet network interface. The TxErrCount attribute shall be reset to 0 upon a - * - * reboot of the Node. + * the ethernet network interface. The TxErrCount attribute shall be reset to 0 upon a reboot of the Node. * * @see {@link MatterSpecification.v13.Core} § 11.16.6.5 */ diff --git a/packages/types/src/clusters/fan-control.ts b/packages/types/src/clusters/fan-control.ts index 5e4f87f021..1caaac71a9 100644 --- a/packages/types/src/clusters/fan-control.ts +++ b/packages/types/src/clusters/fan-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -35,7 +35,7 @@ export namespace FanControl { * The MultiSpeed feature includes new attributes that support a running fan speed value from 0 to SpeedMax, * which has a maximum of 100. * - * See Speed Rules for more details. + * See Section 4.4.6.6.1 for more details. * * @see {@link MatterSpecification.v13.Cluster} § 4.4.4.1 */ @@ -286,7 +286,7 @@ export namespace FanControl { * changed to the requested value. * * If this is successfully written to 0, the server shall set the FanMode attribute value to Off. Please - * see the Speed Rules for details on other values. + * see the Section 4.4.6.6.1 for details on other values. * * @see {@link MatterSpecification.v13.Cluster} § 4.4.6.6 */ @@ -423,7 +423,7 @@ export namespace FanControl { * The MultiSpeed feature includes new attributes that support a running fan speed value from 0 to * SpeedMax, which has a maximum of 100. * - * See Speed Rules for more details. + * See Section 4.4.6.6.1 for more details. * * @see {@link MatterSpecification.v13.Cluster} § 4.4.4.1 */ @@ -477,7 +477,7 @@ export namespace FanControl { * This attribute shall be set to one of the values in FanModeEnum. * * When the FanMode attribute is successfully written to, the PercentSetting and SpeedSetting (if present) - * attributes shall be set to appropriate values, as defined by the Percent Rules and Speed Rules + * attributes shall be set to appropriate values, as defined by the Section 4.4.6.3.1 and Section 4.4.6.6.1 * respectively, unless otherwise specified below. * * When the FanMode attribute is set to any given mode, the PercentCurrent and SpeedCurrent (if present) @@ -510,7 +510,7 @@ export namespace FanControl { * Indicates the actual currently operating fan speed, or zero to indicate that the fan is off. There may * be a temporary mismatch between the value of this attribute and the value of the PercentSetting * attribute due to other system requirements that would not allow the fan to operate at the requested - * setting. See Percent Rules for more details. + * setting. See Section 4.4.6.3.1 for more details. * * @see {@link MatterSpecification.v13.Cluster} § 4.4.6.4 */ diff --git a/packages/types/src/clusters/fixed-label.ts b/packages/types/src/clusters/fixed-label.ts index 6510d2bc2a..b78f7b25d1 100644 --- a/packages/types/src/clusters/fixed-label.ts +++ b/packages/types/src/clusters/fixed-label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -31,7 +31,10 @@ export namespace FixedLabel { }); /** - * This cluster provides a feature for the device to tag an endpoint with zero or more read only labels. Examples: + * This cluster is derived from the Label cluster and provides a feature for the device to tag an endpoint with + * zero or more read-only labels. + * + * Examples: * * • A bridge can use this to indicate grouping of bridged devices. For example: All bridged devices whose * endpoints have an entry in their LabelList "room":"bedroom 2" are in the same (bed)room. @@ -39,7 +42,9 @@ export namespace FixedLabel { * • A manufacturer can use this to identify a characteristic of an endpoint. For example to identify the * endpoints of a luminaire, one pointing up, the other pointing down, one of the endpoints would have a * LabelList entry "orientation":"up" while the other would have "orientation":"down". Using such indication, - * the user interface of a Node controlling this luminaire knows which of the endpoints is which of the lights. + * the user interface of a Node controlling this luminaire + * + * knows which of the endpoints is which of the lights. * * Note that the TagList in the Descriptor cluster provides an alternative mechanism for such self- description * using standardized tags rather than manufacturer-selected strings, yielding a standardized mechanism for diff --git a/packages/types/src/clusters/flow-measurement.ts b/packages/types/src/clusters/flow-measurement.ts index 9a7c43d203..588185303b 100644 --- a/packages/types/src/clusters/flow-measurement.ts +++ b/packages/types/src/clusters/flow-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -24,7 +24,7 @@ export namespace FlowMeasurement { attributes: { /** - * MeasuredValue represents the flow in m/h as follows: + * Indicates the flow in m/h as follows: * * MeasuredValue = 10 x Flow * @@ -36,24 +36,24 @@ export namespace FlowMeasurement { measuredValue: Attribute(0x0, TlvNullable(TlvUInt16), { default: null }), /** - * The MinMeasuredValue attribute indicates the minimum value of MeasuredValue that can be measured. See - * Measured Value for more details. + * Indicates the minimum value of MeasuredValue that can be measured. See Measured Value for more details. * * The null value indicates that the value is not available. * * @see {@link MatterSpecification.v13.Cluster} § 2.5.4.2 */ - minMeasuredValue: Attribute(0x1, TlvNullable(TlvUInt16)), + minMeasuredValue: Attribute(0x1, TlvNullable(TlvUInt16.bound({ max: 65533 }))), /** - * The MaxMeasuredValue attribute indicates the maximum value of MeasuredValue that can be measured. See + * Indicates the maximum value of MeasuredValue that can be measured. See + * * Measured Value for more details. * * The null value indicates that the value is not available. * * @see {@link MatterSpecification.v13.Cluster} § 2.5.4.3 */ - maxMeasuredValue: Attribute(0x2, TlvNullable(TlvUInt16.bound({ max: 65534 }))), + maxMeasuredValue: Attribute(0x2, TlvNullable(TlvUInt16)), /** * See Measured Value. diff --git a/packages/types/src/clusters/formaldehyde-concentration-measurement.ts b/packages/types/src/clusters/formaldehyde-concentration-measurement.ts index c10abb3a87..9fa53d56fc 100644 --- a/packages/types/src/clusters/formaldehyde-concentration-measurement.ts +++ b/packages/types/src/clusters/formaldehyde-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/general-commissioning.ts b/packages/types/src/clusters/general-commissioning.ts index 25764cba9d..03e870cbc2 100644 --- a/packages/types/src/clusters/general-commissioning.ts +++ b/packages/types/src/clusters/general-commissioning.ts @@ -1,28 +1,164 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; -import { WritableAttribute, FixedAttribute, Attribute, Command } from "../cluster/Cluster.js"; -import { TlvUInt64, TlvUInt16, TlvEnum } from "../tlv/TlvNumber.js"; +import { Attribute, Command, WritableAttribute, FixedAttribute } from "../cluster/Cluster.js"; +import { TlvUInt16, TlvUInt32, TlvEnum, TlvUInt64 } from "../tlv/TlvNumber.js"; import { AccessLevel } from "#model"; +import { TlvBoolean } from "../tlv/TlvBoolean.js"; +import { TlvNullable } from "../tlv/TlvNullable.js"; import { TlvField, TlvObject } from "../tlv/TlvObject.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; -import { TlvBoolean } from "../tlv/TlvBoolean.js"; +import { BitFlag } from "../schema/BitmapSchema.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; export namespace GeneralCommissioning { + /** + * These are optional features supported by GeneralCommissioningCluster. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.4 + */ + export enum Feature { + /** + * TermsAndConditions (TC) + * + * Supports Terms & Conditions acknowledgement + */ + TermsAndConditions = "TermsAndConditions" + } + + /** + * Input to the GeneralCommissioning setTcAcknowledgements command + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.8 + */ + export const TlvSetTcAcknowledgementsRequest = TlvObject({ + /** + * This field shall contain the version of the Enhanced Setup Flow Terms & Conditions that were presented to + * the user. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.8.1 + */ + tcVersion: TlvField(0, TlvUInt16), + + /** + * This field shall contain the user responses to the Enhanced Setup Flow Terms & Conditions as a map where + * each bit set in the bitmap corresponds to an accepted term in the file located at EnhancedSetupFlowTCUrl. + * + * ### Effect on Receipt + * + * This command shall copy the user responses and accepted version to the presented Enhanced Setup Flow Terms & + * Conditions from the values provided in the TCUserResponse and TCVersion fields to the TCAcknowledgements + * Attribute and the TCAcceptedVersion Attribute fields respectively. + * + * This command shall result in success with an ErrorCode value of OK in the SetTCAcknowledgementsResponse if + * all required terms were accepted by the user. Specifically, all bits have a value of 1 in TCAcknowledgements + * whose ordinal is marked as required in the file located at EnhancedSe + * + * tupFlowTCUrl. + * + * If the TCVersion field is less than the TCMinRequiredVersion, then the ErrorCode of TCMinVersionNotMet shall + * be returned and TCAcknowledgements shall remain unchanged. + * + * If TCVersion is greater than or equal to TCMinRequiredVersion, but the TCUserResponse value indicates that + * not all required terms were accepted by the user, then the ErrorCode of RequiredTCNotAccepted shall be + * returned and TCAcknowledgements shall remain unchanged. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.8.2 + */ + tcUserResponse: TlvField(1, TlvUInt16) + }); + + /** + * Input to the GeneralCommissioning setTcAcknowledgements command + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.8 + */ + export interface SetTcAcknowledgementsRequest extends TypeFromSchema {} + + /** + * This enumeration is used by several response commands in this cluster to indicate particular errors. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.5.1 + */ + export enum CommissioningError { + /** + * No error + */ + Ok = 0, + + /** + * Attempting to set regulatory configuration to a region or indoor/outdoor mode for which the server does not + * have proper configuration. + */ + ValueOutsideRange = 1, + + /** + * Executed CommissioningComplete outside CASE session. + */ + InvalidAuthentication = 2, + + /** + * Executed CommissioningComplete when there was no active Fail-Safe context. + */ + NoFailSafe = 3, + + /** + * Attempting to arm fail- safe or execute CommissioningComplete from a fabric different than the one + * associated with the current fail- safe context. + */ + BusyWithOtherAdmin = 4, + + /** + * One or more required TC features from the Enhanced Setup Flow were not accepted. + */ + RequiredTcNotAccepted = 5, + + /** + * No acknowledgements from the user for the TC features were received. + */ + TcAcknowledgementsNotReceived = 6, + + /** + * The version of the TC features acknowledged by the user did not meet the minimum required version. + */ + TcMinVersionNotMet = 7 + } + + /** + * This command is used to convey the result from SetTCAcknowledgements. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.9 + */ + export const TlvSetTcAcknowledgementsResponse = TlvObject({ + /** + * This field shall contain the result of the operation, based on the behavior specified in the functional + * description of the SetTCAcknowledgements command. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.9.1 + */ + errorCode: TlvField(0, TlvEnum()) + }); + + /** + * This command is used to convey the result from SetTCAcknowledgements. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.9 + */ + export interface SetTcAcknowledgementsResponse extends TypeFromSchema {} + /** * This structure provides some constant values that may be of use to all commissioners. * - * @see {@link MatterSpecification.v13.Core} § 11.10.4.3 + * @see {@link MatterSpecification.v13.Core} § 11.10.5.3 */ export const TlvBasicCommissioningInfo = TlvObject({ /** @@ -31,19 +167,19 @@ export namespace GeneralCommissioning { * Commissionee. This value, if used in the ArmFailSafe command’s ExpiryLengthSeconds field SHOULD allow a * Commissioner to proceed with a nominal commissioning without having to-rearm the fail-safe, with some margin. * - * @see {@link MatterSpecification.v13.Core} § 11.10.4.3.1 + * @see {@link MatterSpecification.v13.Core} § 11.10.5.3.1 */ failSafeExpiryLengthSeconds: TlvField(0, TlvUInt16), /** * This field shall contain a conservative value in seconds denoting the maximum total duration for which a - * fail safe timer can be re-armed. See Section 11.10.6.2.1, “Fail Safe Context”. + * fail safe timer can be re-armed. See Section 11.10.7.2.1, “Fail Safe Context”. * * The value of this field shall be greater than or equal to the FailSafeExpiryLengthSeconds. Absent additional * guidelines, it is recommended that the value of this field be aligned with the initial Announcement Duration * and default to 900 seconds. * - * @see {@link MatterSpecification.v13.Core} § 11.10.4.3.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.5.3.2 */ maxCumulativeFailsafeSeconds: TlvField(1, TlvUInt16) }); @@ -51,7 +187,7 @@ export namespace GeneralCommissioning { /** * This structure provides some constant values that may be of use to all commissioners. * - * @see {@link MatterSpecification.v13.Core} § 11.10.4.3 + * @see {@link MatterSpecification.v13.Core} § 11.10.5.3 */ export interface BasicCommissioningInfo extends TypeFromSchema {} @@ -59,7 +195,7 @@ export namespace GeneralCommissioning { * This enumeration is used by the RegulatoryConfig and LocationCapability attributes to indicate possible radio * usage. * - * @see {@link MatterSpecification.v13.Core} § 11.10.4.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.5.2 */ export enum RegulatoryLocationType { /** @@ -81,7 +217,7 @@ export namespace GeneralCommissioning { /** * Input to the GeneralCommissioning armFailSafe command * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.2 */ export const TlvArmFailSafeRequest = TlvObject({ expiryLengthSeconds: TlvField(0, TlvUInt16), @@ -91,73 +227,39 @@ export namespace GeneralCommissioning { /** * Input to the GeneralCommissioning armFailSafe command * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.2 */ export interface ArmFailSafeRequest extends TypeFromSchema {} /** - * This enumeration is used by several response commands in this cluster to indicate particular errors. - * - * @see {@link MatterSpecification.v13.Core} § 11.10.4.1 - */ - export enum CommissioningError { - /** - * No error - */ - Ok = 0, - - /** - * Attempting to set regulatory configuration to a region or indoor/outdoor mode for which the server does not - * have proper configuration. - */ - ValueOutsideRange = 1, - - /** - * Executed CommissioningComplete outside CASE session. - */ - InvalidAuthentication = 2, - - /** - * Executed CommissioningComplete when there was no active Fail-Safe context. - */ - NoFailSafe = 3, - - /** - * Attempting to arm fail- safe or execute CommissioningComplete from a fabric different than the one - * associated with the current fail- safe context. - */ - BusyWithOtherAdmin = 4 - } - - /** - * @see {@link MatterSpecification.v13.Core} § 11.10.6.3 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.3 */ export const TlvArmFailSafeResponse = TlvObject({ /** * This field shall contain the result of the operation, based on the behavior specified in the functional * description of the ArmFailSafe command. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.3.1 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.3.1 */ errorCode: TlvField(0, TlvEnum()), /** - * See Section 11.10.6.1, “Common fields in General Commissioning cluster responses”. + * See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.3.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.3.2 */ debugText: TlvField(1, TlvString.bound({ maxLength: 128 })) }); /** - * @see {@link MatterSpecification.v13.Core} § 11.10.6.3 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.3 */ export interface ArmFailSafeResponse extends TypeFromSchema {} /** * Input to the GeneralCommissioning setRegulatoryConfig command * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.4 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.4 */ export const TlvSetRegulatoryConfigRequest = TlvObject({ newRegulatoryConfig: TlvField(0, TlvEnum()), @@ -168,67 +270,192 @@ export namespace GeneralCommissioning { /** * Input to the GeneralCommissioning setRegulatoryConfig command * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.4 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.4 */ export interface SetRegulatoryConfigRequest extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Core} § 11.10.6.5 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.5 */ export const TlvSetRegulatoryConfigResponse = TlvObject({ /** * This field shall contain the result of the operation, based on the behavior specified in the functional * description of the SetRegulatoryConfig command. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.5.1 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.5.1 */ errorCode: TlvField(0, TlvEnum()), /** - * See Section 11.10.6.1, “Common fields in General Commissioning cluster responses”. + * See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.5.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.5.2 */ debugText: TlvField(1, TlvString) }); /** - * @see {@link MatterSpecification.v13.Core} § 11.10.6.5 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.5 */ export interface SetRegulatoryConfigResponse extends TypeFromSchema {} /** - * @see {@link MatterSpecification.v13.Core} § 11.10.6.7 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.7 */ export const TlvCommissioningCompleteResponse = TlvObject({ /** * This field shall contain the result of the operation, based on the behavior specified in the functional * description of the CommissioningComplete command. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.7.1 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.7.1 */ errorCode: TlvField(0, TlvEnum()), /** - * See Section 11.10.6.1, “Common fields in General Commissioning cluster responses”. + * See Section 11.10.7.1, “Common fields in General Commissioning cluster responses”. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.7.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.7.2 */ debugText: TlvField(1, TlvString) }); /** - * @see {@link MatterSpecification.v13.Core} § 11.10.6.7 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.7 */ export interface CommissioningCompleteResponse extends TypeFromSchema {} /** - * @see {@link Cluster} + * A GeneralCommissioningCluster supports these elements if it supports feature TermsAndConditions. */ - export const ClusterInstance = MutableCluster({ + export const TermsAndConditionsComponent = MutableCluster.Component({ + attributes: { + /** + * Indicates the last version of the T&Cs for which the device received user acknowledgements. On factory + * reset this field shall be reset to 0. + * + * When Custom Commissioning Flow is used to obtain user consent (e. g. because the Commissioner does not + * support the TC feature), the manufacturer-provided means for obtaining user consent shall ensure that + * this attribute is set to a value which is greater than or equal to TCMinRequiredVersion before returning + * the user back to the originating Commissioner (see Enhanced Setup Flow). + * + * @see {@link MatterSpecification.v13.Core} § 11.10.6.6 + */ + tcAcceptedVersion: Attribute( + 0x5, + TlvUInt16, + { persistent: true, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * Indicates the minimum version of the texts presented by the Enhanced Setup Flow that need to be accepted + * by the user for this device. This attribute may change as the result of an OTA update. + * + * If an event such as a software update causes TCAcceptedVersion to become less than TCMinRequiredVersion, + * then the device shall update TCAcknowledgementsRequired to True so that an administrator can detect that + * a newer version of the texts needs to be presented to the user. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.6.7 + */ + tcMinRequiredVersion: Attribute( + 0x6, + TlvUInt16, + { persistent: true, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * Indicates the user’s response to the presented terms. Each bit position corresponds to a user response + * for the associated index of matching text, such that bit 0 (bit value 1) is for text index 0. Bit 15 + * (bit value 0x8000) is for text index 15. A bit value of 1 indicates acceptance and a value of 0 + * indicates non-acceptance. For example, if there are two texts that were presented where the first (bit + * 0, value 1) was declined and the second accepted (bit 1, value 2), we would expect the resulting value + * of the map to be 2. + * + * Whenever a user provides responses to newly presented terms and conditions, this attribute shall be + * updated with the latest responses. This may happen in response to updated terms that were presented to + * the user. On a factory reset this field shall be reset with all bits set to 0. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.6.8 + */ + tcAcknowledgements: Attribute( + 0x7, + TlvUInt16, + { persistent: true, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * Indicates whether SetTCAcknowledgements is currently required to be called with the inclusion of + * mandatory terms accepted. + * + * This attribute may be present and False in the case where no terms and conditions are currently + * mandatory to accept for CommissioningComplete to succeed. + * + * This attribute may appear, or become True after commissioning (e.g. due to a firmware update) to + * indicate that new Terms & Conditions are available that the user must accept. + * + * Upon Factory Data Reset, this attribute shall be set to a value of True. + * + * When Custom Commissioning Flow is used to obtain user consent (e.g. because the Commissioner does not + * support the TC feature), the manufacturer-provided means for obtaining user consent shall ensure that + * this attribute is set to False before returning the user back to the original Commissioner (see Enhanced + * Setup Flow). + * + * @see {@link MatterSpecification.v13.Core} § 11.10.6.9 + */ + tcAcknowledgementsRequired: Attribute( + 0x8, + TlvBoolean, + { persistent: true, default: true, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * Indicates the System Time in seconds when any functionality limitations will begin due to a lack of + * acceptance of updated Terms and Conditions, as described in Section 5.7.4.5, “Presenting Updated Terms + * and Conditions”. + * + * A null value indicates that there is no pending deadline for updated TC acceptance. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.6.10 + */ + tcUpdateDeadline: Attribute( + 0x9, + TlvNullable(TlvUInt32), + { persistent: true, readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ) + }, + + commands: { + /** + * This command sets the user acknowledgements received in the Enhanced Setup Flow Terms & Conditions into + * the node. + * + * @see {@link MatterSpecification.v13.Core} § 11.10.7.8 + */ + setTcAcknowledgements: Command( + 0x6, + TlvSetTcAcknowledgementsRequest, + 0x7, + TlvSetTcAcknowledgementsResponse, + { invokeAcl: AccessLevel.Administer } + ) + } + }); + + /** + * These elements and properties are present in all GeneralCommissioning clusters. + */ + export const Base = MutableCluster.Component({ id: 0x30, name: "GeneralCommissioning", - revision: 1, + revision: 2, + + features: { + /** + * TermsAndConditions + * + * Supports Terms & Conditions acknowledgement + */ + termsAndConditions: BitFlag(0) + }, attributes: { /** @@ -247,7 +474,7 @@ export namespace GeneralCommissioning { * functioning of any cluster, other than being set as a side-effect of commands where this behavior is * described. * - * @see {@link MatterSpecification.v13.Core} § 11.10.5.1 + * @see {@link MatterSpecification.v13.Core} § 11.10.6.1 */ breadcrumb: WritableAttribute(0x0, TlvUInt64, { default: 0, writeAcl: AccessLevel.Administer }), @@ -255,7 +482,7 @@ export namespace GeneralCommissioning { * This attribute shall describe critical parameters needed at the beginning of commissioning flow. See * BasicCommissioningInfo for more information. * - * @see {@link MatterSpecification.v13.Core} § 11.10.5.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.6.2 */ basicCommissioningInfo: FixedAttribute(0x1, TlvBasicCommissioningInfo), @@ -265,7 +492,7 @@ export namespace GeneralCommissioning { * Note that the country code is part of Basic Information Cluster and therefore NOT listed on the * RegulatoryConfig attribute. * - * @see {@link MatterSpecification.v13.Core} § 11.10.5.3 + * @see {@link MatterSpecification.v13.Core} § 11.10.6.3 */ regulatoryConfig: Attribute(0x2, TlvEnum()), @@ -273,8 +500,9 @@ export namespace GeneralCommissioning { * LocationCapability is statically set by the manufacturer and indicates if this Node needs to be told an * exact RegulatoryLocation. For example a Node which is "Indoor Only" would not be certified for outdoor * use at all, and thus there is no need for a commissioner to set or ask the user about whether the device - * will be used inside or outside. However a device which states its capability is "Indoor/Outdoor" means - * it would like clarification if possible. + * will be used inside or outside. However a device which states its capability is + * + * "Indoor/Outdoor" means it would like clarification if possible. * * For Nodes without radio network interfaces (e.g. Ethernet-only devices), the value IndoorOutdoor shall * always be used. @@ -283,7 +511,7 @@ export namespace GeneralCommissioning { * means devices always have a safe default value, and Commissioners which choose to implement smarter * handling can. * - * @see {@link MatterSpecification.v13.Core} § 11.10.5.4 + * @see {@link MatterSpecification.v13.Core} § 11.10.6.4 */ locationCapability: FixedAttribute( 0x3, @@ -295,7 +523,7 @@ export namespace GeneralCommissioning { * Indicates whether this device supports "concurrent connection flow" commissioning mode (see Section 5.5, * “Commissioning Flows”). If false, the device only supports "non-concurrent connection flow" mode. * - * @see {@link MatterSpecification.v13.Core} § 11.10.5.5 + * @see {@link MatterSpecification.v13.Core} § 11.10.6.5 */ supportsConcurrentConnection: FixedAttribute(0x4, TlvBoolean, { default: true }) }, @@ -315,9 +543,8 @@ export namespace GeneralCommissioning { * of ExpiryLengthSeconds, or disarm it, depending on the situation: * * • If ExpiryLengthSeconds is 0 and the fail-safe timer was already armed and the accessing fabric - * matches the Fabric currently associated with the fail-safe context, then the fail-safe timer - * - * shall be immediately expired (see further below for side-effects of expiration). + * matches the Fabric currently associated with the fail-safe context, then the fail-safe timer shall + * be immediately expired (see further below for side-effects of expiration). * * • If ExpiryLengthSeconds is 0 and the fail-safe timer was not armed, then this command invocation * shall lead to a success response with no side-effects against the fail-safe context. @@ -333,8 +560,8 @@ export namespace GeneralCommissioning { * with ArmFailSafeResponse containing an ErrorCode value of BusyWithOtherAdmin, indicating a likely * conflict between commissioners. * - * The value of the Breadcrumb field shall be written to the Breadcrumb Attribute on successful execution - * of the command. + * The value of the Breadcrumb field shall be written to the Breadcrumb on successful execution of the + * command. * * If the receiver restarts unexpectedly (e.g., power interruption, software crash, or other reset) the * receiver shall behave as if the fail-safe timer expired and perform the sequence of clean-up steps @@ -379,7 +606,7 @@ export namespace GeneralCommissioning { * timer (CFSC timer) serves to limit the lifetime of any particular Fail Safe Context; it shall NOT be * extended or modified on subsequent invocations of ArmFailSafe associated with this Fail Safe Context. * Upon expiry of the CFSC timer, the receiver shall execute cleanup behavior equivalent to that of - * fail-safe timer expiration as detailed in Section 11.10.6.2.2, “Behavior on expiry of Fail-Safe timer”. + * fail-safe timer expiration as detailed in Section 11.10.7.2.2, “Behavior on expiry of Fail-Safe timer”. * Termination of the session prior to the expiration of that timer for any reason (including a successful * end of commissioning or an expiry of a fail-safe timer) shall also delete the CFSC timer. * @@ -392,11 +619,11 @@ export namespace GeneralCommissioning { * Server. * * 2. Revoke the temporary administrative privileges granted to any open PASE session (see Section - * 6.6.2.8, “Bootstrapping of the Access Control Cluster”) at the Server. + * 6.6.2.9, “Bootstrapping of the Access Control Cluster”) at the Server. * * 3. If an AddNOC or UpdateNOC command has been successfully invoked, terminate all CASE sessions - * associated with the Fabric whose Fabric Index is recorded in the Fail-Safe context (see Section - * 11.10.6.2, “ArmFailSafe Command”) by clearing any associated Secure Session Context at the Server. + * associated with the Fabric whose Fabric Index is recorded in the Fail-Safe context (see + * ArmFailSafe) by clearing any associated Secure Session Context at the Server. * * 4. Reset the configuration of all Network Commissioning Networks attribute to their state prior to the * Fail-Safe being armed. @@ -422,11 +649,10 @@ export namespace GeneralCommissioning { * * 9. Reset the Breadcrumb attribute to zero. * - * 10. Optionally: if no factory-reset resulted from the previous steps, it is recommended that the + * 10. Optionally: if no factory-reset resulted from the previous steps, it is recommended that the Node + * rollback the state of all non fabric-scoped data present in the Fail-Safe context. * - * Node rollback the state of all non fabric-scoped data present in the Fail-Safe context. - * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.2 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.2 */ armFailSafe: Command( 0x0, @@ -452,8 +678,9 @@ export namespace GeneralCommissioning { * Location attribute reflected by the Basic Information Cluster configuration, but the * SetRegulatoryConfigResponse replied shall have the ErrorCode field set to ValueOutsideRange error. * - * If the LocationCapability attribute is not Indoor/Outdoor and the NewRegulatoryConfig value received - * does not match either the Indoor or Outdoor fixed value in LocationCapability, then the + * If the LocationCapability attribute is not Indoor/Outdoor and the NewRegulatoryConfig value + * + * received does not match either the Indoor or Outdoor fixed value in LocationCapability, then the * SetRegulatoryConfigResponse replied shall have the ErrorCode field set to ValueOutsideRange error and * the RegulatoryConfig attribute and associated internal radio configuration shall remain unchanged. * @@ -467,7 +694,7 @@ export namespace GeneralCommissioning { * command, when SetRegulatoryConfigResponse has the ErrorCode field set to OK. If the command fails, the * Breadcrumb attribute shall be left unchanged. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.4 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.4 */ setRegulatoryConfig: Command( 0x2, @@ -488,15 +715,20 @@ export namespace GeneralCommissioning { * steps needed during the Fail-Safe period, such as commissioning (see Section 5.5, “Commissioning Flows”) * or other Administrator operations requiring usage of the Fail Safe timer. It ensures that the Server is * configured in a state such that it still has all necessary elements to be fully operable within a - * Fabric, such as ACL entries (see Access Control Cluster) and operational credentials (see Section 6.4, - * “Node Operational Credentials Specification”), and that the Node is reach + * Fabric, such as ACL entries (see Section 9.10, “Access Control Cluster”) and operational credentials + * (see Section 6.4, “Node Operational Credentials Specification”), and that the Node is reachable using + * CASE * - * able using CASE (see Section 4.14.2, “Certificate Authenticated Session Establishment (CASE)”) over an - * operational network. + * (CASE)”) over an operational network. * * An ErrorCode of NoFailSafe shall be responded to the invoker if the CommissioningComplete command was * received when no Fail-Safe context exists. * + * If Terms and Conditions are required, then an ErrorCode of TCAcknowledgementsNotReceived shall be + * responded to the invoker if the user acknowledgements to the required Terms and Conditions have not been + * provided. If the TCAcceptedVersion for the provided acknowledgements is less than TCMinRequiredVersion, + * then an ErrorCode of TCMinVersionNotMet shall be responded to the invoker. + * * This command is fabric-scoped, so cannot be issued over a session that does not have an associated * fabric, i.e. over PASE session prior to an AddNOC command. In addition, this command is only permitted * over CASE and must be issued by a node associated with the ongoing Fail-Safe context. An ErrorCode of @@ -523,7 +755,7 @@ export namespace GeneralCommissioning { * 2. The commissioning window at the Server shall be closed. * * 3. Any temporary administrative privileges automatically granted to any open PASE session shall be - * revoked (see Section 6.6.2.8, “Bootstrapping of the Access Control Cluster”). + * revoked (see Section 6.6.2.9, “Bootstrapping of the Access Control Cluster”). * * 4. The Secure Session Context of any PASE session still established at the Server shall be cleared. * @@ -533,7 +765,7 @@ export namespace GeneralCommissioning { * any previously established PASE session to still be usable, due to the server having cleared such * sessions. * - * @see {@link MatterSpecification.v13.Core} § 11.10.6.6 + * @see {@link MatterSpecification.v13.Core} § 11.10.7.6 */ commissioningComplete: Command( 0x4, @@ -542,9 +774,22 @@ export namespace GeneralCommissioning { TlvCommissioningCompleteResponse, { invokeAcl: AccessLevel.Administer } ) - } + }, + + /** + * This metadata controls which GeneralCommissioningCluster elements matter.js activates for specific feature + * combinations. + */ + extensions: MutableCluster.Extensions( + { flags: { termsAndConditions: true }, component: TermsAndConditionsComponent } + ) }); + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster(Base); + /** * This cluster is used to manage basic commissioning lifecycle. * @@ -552,12 +797,67 @@ export namespace GeneralCommissioning { * clusters, like Section 11.9, “Network Commissioning Cluster”. It also hosts functionalities those other clusters * may depend on. * + * GeneralCommissioningCluster supports optional features that you can enable with the + * GeneralCommissioningCluster.with() factory method. + * * @see {@link MatterSpecification.v13.Core} § 11.10 */ export interface Cluster extends Identity {} export const Cluster: Cluster = ClusterInstance; - export const Complete = Cluster; + const TC = { termsAndConditions: true }; + + /** + * @see {@link Complete} + */ + export const CompleteInstance = MutableCluster({ + id: Cluster.id, + name: Cluster.name, + revision: Cluster.revision, + features: Cluster.features, + + attributes: { + ...Cluster.attributes, + tcAcceptedVersion: MutableCluster.AsConditional( + TermsAndConditionsComponent.attributes.tcAcceptedVersion, + { mandatoryIf: [TC] } + ), + tcMinRequiredVersion: MutableCluster.AsConditional( + TermsAndConditionsComponent.attributes.tcMinRequiredVersion, + { mandatoryIf: [TC] } + ), + tcAcknowledgements: MutableCluster.AsConditional( + TermsAndConditionsComponent.attributes.tcAcknowledgements, + { mandatoryIf: [TC] } + ), + tcAcknowledgementsRequired: MutableCluster.AsConditional( + TermsAndConditionsComponent.attributes.tcAcknowledgementsRequired, + { mandatoryIf: [TC] } + ), + tcUpdateDeadline: MutableCluster.AsConditional( + TermsAndConditionsComponent.attributes.tcUpdateDeadline, + { mandatoryIf: [TC] } + ) + }, + + commands: { + ...Cluster.commands, + setTcAcknowledgements: MutableCluster.AsConditional( + TermsAndConditionsComponent.commands.setTcAcknowledgements, + { mandatoryIf: [TC] } + ) + } + }); + + /** + * This cluster supports all GeneralCommissioning features. It may support illegal feature combinations. + * + * If you use this cluster you must manually specify which features are active and ensure the set of active + * features is legal per the Matter specification. + */ + export interface Complete extends Identity {} + + export const Complete: Complete = CompleteInstance; } export type GeneralCommissioningCluster = GeneralCommissioning.Cluster; diff --git a/packages/types/src/clusters/general-diagnostics.ts b/packages/types/src/clusters/general-diagnostics.ts index 1fbad1d43c..31cb534b5e 100644 --- a/packages/types/src/clusters/general-diagnostics.ts +++ b/packages/types/src/clusters/general-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -90,9 +90,10 @@ export namespace GeneralDiagnostics { * • If Value is 0x55 and the Count is zero, then the PayloadTestResponse would have the Payload field set to * an empty octet string. * - * • If Value is 0xA5 and the Count is 10, the PayloadTestResponse would have the Payload field set to a - * content whose hexadecimal representation would be A5A5A5A5A5A5A5A5A5A5, and base64 representation would - * be paWlpaWlpaWlpQ==. + * • If Value is 0xA5 and the Count is 10, the PayloadTestResponse would have the Payload field set + * + * to a content whose hexadecimal representation would be A5A5A5A5A5A5A5A5A5A5, and base64 representation would + * be paWlpaWlpaWlpQ==. * * @see {@link MatterSpecification.v13.Core} § 11.12.7.4.3 */ @@ -199,9 +200,11 @@ export namespace GeneralDiagnostics { offPremiseServicesReachableIPv6: TlvField(3, TlvNullable(TlvBoolean)), /** - * This field shall contain the current link-layer address for a 802.3 or IEEE 802.11-2020 network interface - * and contain the current extended MAC address for a 802.15.4 interface. The byte order of the octstr shall be - * in wire byte order. For addresses values less than 64 bits, the first two bytes shall be zero. + * This field shall contain the current link-layer address for a 802.3 or IEEE 802.11-2020 network + * + * interface and contain the current extended MAC address for a 802.15.4 interface. The byte order of the + * octstr shall be in wire byte order. For addresses values less than 64 bits, the first two bytes shall be + * zero. * * @see {@link MatterSpecification.v13.Core} § 11.12.5.6.5 */ @@ -439,8 +442,9 @@ export namespace GeneralDiagnostics { * Values of EventTrigger in the range 0xFFFF_FFFF_0000_0000 through 0xFFFF_FFFF_FFFF_FFFF are reserved for * testing use by manufacturers and will not appear in CSA certification test literature. * - * If the value of EventTrigger received is not supported by the receiving Node, this command shall fail with a - * status code of INVALID_COMMAND. + * If the value of EventTrigger received is not supported by the receiving Node, this command shall + * + * fail with a status code of INVALID_COMMAND. * * Otherwise, if the EnableKey value matches the configured internal value for a particular Node, and the * EventTrigger value matches a supported test event trigger value, the command shall succeed and execute the @@ -520,16 +524,14 @@ export namespace GeneralDiagnostics { */ export const TlvHardwareFaultChangeEvent = TlvObject({ /** - * This field shall represent the set of faults currently detected, as per Section 11.12.5.1, - * “HardwareFaultEnum Type”. + * This field shall represent the set of faults currently detected, as per HardwareFaultEnum. * * @see {@link MatterSpecification.v13.Core} § 11.12.8.1.1 */ current: TlvField(0, TlvArray(TlvEnum(), { maxLength: 11 })), /** - * This field shall represent the set of faults detected prior to this change event, as per Section 11.12.5.1, - * “HardwareFaultEnum Type”. + * This field shall represent the set of faults detected prior to this change event, as per HardwareFaultEnum. * * @see {@link MatterSpecification.v13.Core} § 11.12.8.1.2 */ @@ -550,16 +552,14 @@ export namespace GeneralDiagnostics { */ export const TlvRadioFaultChangeEvent = TlvObject({ /** - * This field shall represent the set of faults currently detected, as per Section 11.12.5.2, “RadioFaultEnum - * Type”. + * This field shall represent the set of faults currently detected, as per RadioFaultEnum. * * @see {@link MatterSpecification.v13.Core} § 11.12.8.2.1 */ current: TlvField(0, TlvArray(TlvEnum(), { maxLength: 7 })), /** - * This field shall represent the set of faults detected prior to this change event, as per Section 11.12.5.2, - * “RadioFaultEnum Type”. + * This field shall represent the set of faults detected prior to this change event, as per RadioFaultEnum. * * @see {@link MatterSpecification.v13.Core} § 11.12.8.2.2 */ @@ -580,16 +580,14 @@ export namespace GeneralDiagnostics { */ export const TlvNetworkFaultChangeEvent = TlvObject({ /** - * This field shall represent the set of faults currently detected, as per Section 11.12.5.3, “NetworkFaultEnum - * Type”. + * This field shall represent the set of faults currently detected, as per NetworkFaultEnum. * * @see {@link MatterSpecification.v13.Core} § 11.12.8.3.1 */ current: TlvField(0, TlvArray(TlvEnum(), { maxLength: 4 })), /** - * This field shall represent the set of faults detected prior to this change event, as per Section 11.12.5.3, - * “NetworkFaultEnum Type”. + * This field shall represent the set of faults detected prior to this change event, as per NetworkFaultEnum. * * @see {@link MatterSpecification.v13.Core} § 11.12.8.3.2 */ @@ -725,11 +723,12 @@ export namespace GeneralDiagnostics { * The ActiveHardwareFaults attribute shall indicate the set of faults currently detected by the Node. When * the Node detects a fault has been raised, the appropriate HardwareFaultEnum value shall be added to this * list. This list shall NOT contain more than one instance of a specific HardwareFaultEnum value. When the - * Node detects that all conditions contributing to a fault has been cleared, the corresponding - * HardwareFaultEnum value shall be removed from this list. An empty list shall indicate there are - * currently no active faults. The order of this list SHOULD have no significance. Clients interested in - * monitoring changes in active faults may subscribe to this attribute, or they may subscribe to - * HardwareFaultChange. + * Node detects that all conditions contributing to a fault has been + * + * cleared, the corresponding HardwareFaultEnum value shall be removed from this list. An empty list shall + * indicate there are currently no active faults. The order of this list SHOULD have no significance. + * Clients interested in monitoring changes in active faults may subscribe to this attribute, or they may + * subscribe to HardwareFaultChange. * * @see {@link MatterSpecification.v13.Core} § 11.12.6.6 */ @@ -776,10 +775,10 @@ export namespace GeneralDiagnostics { /** * The TestEventTriggersEnabled attribute shall indicate whether the Node has any TestEventTrigger * configured. When this attribute is true, the Node has been configured with one or more test event - * triggers by virtue of the internally programmed EnableKey value (see Section 11.12.7.1, - * “TestEventTrigger Command”) being set to a non-zero value. This attribute can be used by Administrators - * to detect if a device was inadvertently commissioned with test event trigger mode enabled, and take - * appropriate action (e.g. warn the user and/or offer to remove all fabrics on the Node). + * triggers by virtue of the internally programmed EnableKey value (see TestEventTrigger) being set to a + * non-zero value. This attribute can be used by Administrators to detect if a device was inadvertently + * commissioned with test event trigger mode enabled, and take appropriate action (e.g. warn the user + * and/or offer to remove all fabrics on the Node). * * @see {@link MatterSpecification.v13.Core} § 11.12.6.9 */ @@ -807,10 +806,9 @@ export namespace GeneralDiagnostics { /** * This command may be used by a client to obtain a correlated view of both System Time, and, if currently - * synchronized and supported, "wall clock time" of the server. This can help clients establish - * - * time correlation between their concept of time and the server’s concept of time. This is especially - * useful when processing event histories where some events only contain System Time. + * synchronized and supported, "wall clock time" of the server. This can help clients establish time + * correlation between their concept of time and the server’s concept of time. This is especially useful + * when processing event histories where some events only contain System Time. * * Upon command invocation, the server shall respond with a TimeSnapshotResponse. * diff --git a/packages/types/src/clusters/group-key-management.ts b/packages/types/src/clusters/group-key-management.ts index afd3882076..7295aba78b 100644 --- a/packages/types/src/clusters/group-key-management.ts +++ b/packages/types/src/clusters/group-key-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -57,7 +57,7 @@ export namespace GroupKeyManagement { /** * This field references the set of group keys that generate operational group keys for use with this group, as - * specified in Section 4.16.3.5.1, “Group Key Set ID”. + * specified in Section 4.17.3.5.1, “Group Key Set ID”. * * A GroupKeyMapStruct shall NOT accept GroupKeySetID of 0, which is reserved for the IPK. * @@ -151,7 +151,7 @@ export namespace GroupKeyManagement { export const TlvGroupKeySet = TlvObject({ /** * This field shall provide the fabric-unique index for the associated group key set, as specified in Section - * 4.16.3.5.1, “Group Key Set ID”. + * 4.17.3.5.1, “Group Key Set ID”. * * @see {@link MatterSpecification.v13.Core} § 11.2.5.4.1 */ @@ -176,7 +176,7 @@ export namespace GroupKeyManagement { epochKey0: TlvField(2, TlvNullable(TlvByteString.bound({ length: 16 }))), /** - * This field, if not null, shall define when EpochKey0 becomes valid as specified by Section 4.16.3, “Epoch + * This field, if not null, shall define when EpochKey0 becomes valid as specified by Section 4.17.3, “Epoch * Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation. * * @see {@link MatterSpecification.v13.Core} § 11.2.5.4.4 @@ -184,16 +184,15 @@ export namespace GroupKeyManagement { epochStartTime0: TlvField(3, TlvNullable(TlvEpochUs)), /** - * This field, if not null, shall be the root credential used in the derivation of an operational group - * - * key for epoch slot 1 of the given group key set. If EpochKey1 is not null, EpochStartTime1 shall NOT be null. + * This field, if not null, shall be the root credential used in the derivation of an operational group key for + * epoch slot 1 of the given group key set. If EpochKey1 is not null, EpochStartTime1 shall NOT be null. * * @see {@link MatterSpecification.v13.Core} § 11.2.5.4.5 */ epochKey1: TlvField(4, TlvNullable(TlvByteString.bound({ length: 16 }))), /** - * This field, if not null, shall define when EpochKey1 becomes valid as specified by Section 4.16.3, “Epoch + * This field, if not null, shall define when EpochKey1 becomes valid as specified by Section 4.17.3, “Epoch * Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation. * * @see {@link MatterSpecification.v13.Core} § 11.2.5.4.6 @@ -209,7 +208,7 @@ export namespace GroupKeyManagement { epochKey2: TlvField(6, TlvNullable(TlvByteString.bound({ length: 16 }))), /** - * This field, if not null, shall define when EpochKey2 becomes valid as specified by Section 4.16.3, “Epoch + * This field, if not null, shall define when EpochKey2 becomes valid as specified by Section 4.17.3, “Epoch * Keys”. Units are absolute UTC time in microseconds encoded using the epoch-us representation. * * @see {@link MatterSpecification.v13.Core} § 11.2.5.4.8 @@ -358,8 +357,9 @@ export namespace GroupKeyManagement { /** * This attribute is a list of GroupInfoMapStruct entries. Each entry provides read-only information about - * how a given logical Group ID maps to a particular set of endpoints, and a name for the group. The - * content of this attribute reflects data managed via the Groups cluster (see AppClusters), and is in + * how a given logical Group ID maps to a particular set of endpoints, and a name for the group. + * + * The content of this attribute reflects data managed via the Groups cluster (see AppClusters), and is in * general terms referred to as the 'node-wide Group Table'. * * The GroupTable shall NOT contain any entry whose GroupInfoMapStruct has an empty Endpoints list. If a @@ -437,18 +437,18 @@ export namespace GroupKeyManagement { * being null, then this command shall fail with an INVALID_COMMAND status code responded to the client. * * If there exists a Group Key Set associated with the accessing fabric which has the same GroupKeySetID as - * that provided in the GroupKeySet field, then the contents of that group key set shall be replaced. A - * replacement shall be done by executing the equivalent of entirely removing the previous Group Key Set - * with the given GroupKeySetID, followed by an addition of a Group Key Set with the provided + * that provided in the GroupKeySet field, then the contents of that group key set shall be + * + * replaced. A replacement shall be done by executing the equivalent of entirely removing the previous + * Group Key Set with the given GroupKeySetID, followed by an addition of a Group Key Set with the provided * configuration. Otherwise, if the GroupKeySetID did not match an existing entry, a new Group Key Set * associated with the accessing fabric shall be created with the provided data. The Group Key Set shall be * written to non-volatile storage. * * Upon completion, this command shall send a status code back to the initiator: * - * • If the Group Key Set was properly installed or updated on the Node, the status code shall be - * - * set to SUCCESS. + * • If the Group Key Set was properly installed or updated on the Node, the status code shall be set to + * SUCCESS. * * • If there are insufficient resources on the receiver to store an additional Group Key Set, the status * code shall be set to RESOURCE_EXHAUSTED (see group key limits); @@ -486,10 +486,9 @@ export namespace GroupKeyManagement { * * Effect on Receipt * - * If there exists a Group Key Set associated with the accessing fabric which has the same GroupKey - * - * SetID as that provided in the GroupKeySetID field, then the contents of that Group Key Set shall be - * removed, including all epoch keys it contains. + * If there exists a Group Key Set associated with the accessing fabric which has the same GroupKeySetID as + * that provided in the GroupKeySetID field, then the contents of that Group Key Set shall be removed, + * including all epoch keys it contains. * * If there exist any entries for the accessing fabric within the GroupKeyMap attribute that refer to the * GroupKeySetID just removed, then these entries shall be removed from that list. @@ -516,8 +515,6 @@ export namespace GroupKeyManagement { * This command is used by Administrators to query a list of all Group Key Sets associated with the * accessing fabric. * - * NOTE Field 0 for this command is reserved and shall NOT be used. - * * Effect on Receipt * * Upon receipt, this command shall iterate all stored GroupKeySetStruct associated with the accessing @@ -555,8 +552,9 @@ export namespace GroupKeyManagement { * require Administer privilege. * * Each group entry includes a membership list of zero of more endpoints that are members of the group on the node. - * Modification of this membership list is done via the Groups cluster, which is scoped to an endpoint. Please see - * the System Model specification for more information on groups. + * Modification of this membership list is done via the Groups cluster, which is + * + * scoped to an endpoint. Please see the System Model specification for more information on groups. * * GroupKeyManagementCluster supports optional features that you can enable with the * GroupKeyManagementCluster.with() factory method. diff --git a/packages/types/src/clusters/groups.ts b/packages/types/src/clusters/groups.ts index fb8162ee62..a09250e947 100644 --- a/packages/types/src/clusters/groups.ts +++ b/packages/types/src/clusters/groups.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -280,8 +280,9 @@ export namespace Groups { groupId: TlvField(0, TlvGroupId), /** - * This field may be set to a human-readable name for the group. If the client has no name for the group, the - * GroupName field shall be set to the empty string. + * This field may be set to a human-readable name for the group. If the client has no name for the + * + * group, the GroupName field shall be set to the empty string. * * Support of group names is optional and is indicated by the FeatureMap and NameSupport attribute. * diff --git a/packages/types/src/clusters/hepa-filter-monitoring.ts b/packages/types/src/clusters/hepa-filter-monitoring.ts index dc1836e8d2..343fa44657 100644 --- a/packages/types/src/clusters/hepa-filter-monitoring.ts +++ b/packages/types/src/clusters/hepa-filter-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/icd-management.ts b/packages/types/src/clusters/icd-management.ts index 5f840afa74..ce75426845 100644 --- a/packages/types/src/clusters/icd-management.ts +++ b/packages/types/src/clusters/icd-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,10 +20,10 @@ import { TlvArray } from "../tlv/TlvArray.js"; import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js"; import { TlvNodeId } from "../datatype/NodeId.js"; import { TlvSubjectId } from "../datatype/SubjectId.js"; +import { TlvEnum, TlvUInt32, TlvUInt16, TlvBitmap } from "../tlv/TlvNumber.js"; import { TlvFabricIndex } from "../datatype/FabricIndex.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { AccessLevel } from "#model"; -import { TlvUInt32, TlvUInt16, TlvBitmap, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvByteString, TlvString } from "../tlv/TlvString.js"; import { BitFlag } from "../schema/BitmapSchema.js"; import { Identity } from "#general"; @@ -60,22 +60,45 @@ export namespace IcdManagement { * * This feature is supported if and only the device is a Long Idle Time ICD. * - * NOTE In this version of the specification, the support for the feature is provisional. - * * @see {@link MatterSpecification.v13.Core} § 9.17.4.3 */ - LongIdleTimeSupport = "LongIdleTimeSupport" + LongIdleTimeSupport = "LongIdleTimeSupport", + + /** + * DynamicSitLitSupport (DSLS) + * + * This feature is supported if and only if the device can switch between SIT and LIT operating modes even if + * it has a valid registered client. See the dynamic SIT / LIT operating mode switching for more details. + * + * @see {@link MatterSpecification.v13.Core} § 9.17.4.4 + */ + DynamicSitLitSupport = "DynamicSitLitSupport" } /** - * @see {@link MatterSpecification.v13.Core} § 9.17.5.2 + * @see {@link MatterSpecification.v13.Core} § 9.17.5.1.1 + */ + export enum ClientType { + /** + * The client is typically resident, always-on, fixed infrastructure in the home. + */ + Permanent = 0, + + /** + * The client is mobile or non-resident or not always-on and may not always be available in the home. + */ + Ephemeral = 1 + } + + /** + * @see {@link MatterSpecification.v13.Core} § 9.17.5.3 */ export const TlvMonitoringRegistration = TlvObject({ /** * This field shall indicate the NodeID of the Node to which Check-In messages will be sent when the * MonitoredSubject is not subscribed. * - * @see {@link MatterSpecification.v13.Core} § 9.17.5.2.1 + * @see {@link MatterSpecification.v13.Core} § 9.17.5.3.1 */ checkInNodeId: TlvField(1, TlvNodeId), @@ -95,19 +118,28 @@ export namespace IcdManagement { * For example, if the MonitoredSubject is Node ID 0x1111_2222_3333_AAAA, and one of the subscribers to the * server on the entry’s associated fabric bears that Node ID, then the entry matches. * - * Another example is if the MonitoredSubject has the value 0xFFFF_FFFD_AA12_0002, and one of the subscribers - * to the server on the entry’s associated fabric bears the CASE Authenticated TAG value 0xAA12 and the version - * 0x0002 or higher within its NOC, then the entry matches. + * Another example is if the MonitoredSubject has the value 0xFFFF_FFFD_AA12_0002, and one of the + * + * subscribers to the server on the entry’s associated fabric bears the CASE Authenticated TAG value 0xAA12 and + * the version 0x0002 or higher within its NOC, then the entry matches. * - * @see {@link MatterSpecification.v13.Core} § 9.17.5.2.2 + * @see {@link MatterSpecification.v13.Core} § 9.17.5.3.2 */ monitoredSubject: TlvField(2, TlvSubjectId), + /** + * This field shall indicate the client’s type to inform the ICD of the availability for communication of the + * client. + * + * @see {@link MatterSpecification.v13.Core} § 9.17.5.4 + */ + clientType: TlvField(4, TlvEnum()), + fabricIndex: TlvField(254, TlvFabricIndex) }); /** - * @see {@link MatterSpecification.v13.Core} § 9.17.5.2 + * @see {@link MatterSpecification.v13.Core} § 9.17.5.3 */ export interface MonitoringRegistration extends TypeFromSchema {} @@ -149,7 +181,14 @@ export namespace IcdManagement { * * @see {@link MatterSpecification.v13.Core} § 9.17.7.1.4 */ - verificationKey: TlvOptionalField(3, TlvByteString.bound({ length: 16 })) + verificationKey: TlvOptionalField(3, TlvByteString.bound({ length: 16 })), + + /** + * This field shall provide the client type of the client registering. + * + * @see {@link MatterSpecification.v13.Core} § 9.17.7.1.5 + */ + clientType: TlvField(4, TlvEnum()) }); /** @@ -302,7 +341,7 @@ export namespace IcdManagement { }; /** - * @see {@link MatterSpecification.v13.Core} § 9.17.5.3 + * @see {@link MatterSpecification.v13.Core} § 9.17.5.2 */ export enum OperatingMode { /** @@ -402,7 +441,17 @@ export namespace IcdManagement { * * @see {@link MatterSpecification.v13.Core} § 9.17.6.6 */ - clientsSupportedPerFabric: FixedAttribute(0x5, TlvUInt16.bound({ min: 1 }), { default: 1 }) + clientsSupportedPerFabric: FixedAttribute(0x5, TlvUInt16.bound({ min: 1 }), { default: 1 }), + + /** + * Indicates the maximum time in seconds between two Check-In messages when back-off is active. The + * MaximumCheckInBackoff shall NOT be smaller than the IdleModeDuration. + * + * If the MaximumCheckInBackoff is equal to the IdleModeDuration, it means the ICD does notback- off. + * + * @see {@link MatterSpecification.v13.Core} § 9.17.6.10 + */ + maximumCheckInBackoff: FixedAttribute(0x9, TlvUInt32.bound({ max: 64800 }), { default: 1 }) }, commands: { @@ -454,8 +503,8 @@ export namespace IcdManagement { * a dependency on the UserActiveModeTriggerInstruction attribute but do not require the attribute to be * present. * - * An ICD can indicate multiple ways of being put into Active Mode by setting multiple bits in the bitmap - * at the same time. However, a device shall NOT set more than one bit which has a dependency on the + * ### An ICD can indicate multiple ways of being put into Active Mode by setting multiple bits in the + * bitmap at the same time. However, a device shall NOT set more than one bit which has a dependency on the * UserActiveModeTriggerInstruction attribute. * * @see {@link MatterSpecification.v13.Core} § 9.17.6.7 @@ -503,7 +552,7 @@ export namespace IcdManagement { export const Base = MutableCluster.Component({ id: 0x46, name: "IcdManagement", - revision: 2, + revision: 3, features: { /** @@ -530,11 +579,19 @@ export namespace IcdManagement { * * This feature is supported if and only the device is a Long Idle Time ICD. * - * NOTE In this version of the specification, the support for the feature is provisional. - * * @see {@link MatterSpecification.v13.Core} § 9.17.4.3 */ - longIdleTimeSupport: BitFlag(2) + longIdleTimeSupport: BitFlag(2), + + /** + * DynamicSitLitSupport + * + * This feature is supported if and only if the device can switch between SIT and LIT operating modes even + * if it has a valid registered client. See the dynamic SIT / LIT operating mode switching for more details. + * + * @see {@link MatterSpecification.v13.Core} § 9.17.4.4 + */ + dynamicSitLitSupport: BitFlag(3) }, attributes: { @@ -569,9 +626,8 @@ export namespace IcdManagement { * device to Active Mode. If the attribute is present, the value shall be encoded as a valid UTF-8 string * with a maximum length of 128 bytes. If the UserActiveModeTriggerHint has the ActuateSensorSeconds, * ActuateSensorTimes, ResetButtonSeconds, ResetButtonTimes, SetupButtonSeconds or SetupButtonTimes set, - * the string shall consist solely of an encoding of N as a decimal - * - * unsigned integer using the ASCII digits 0-9, and without leading zeros. + * the string shall consist solely of an encoding of N as a decimal unsigned integer using the ASCII digits + * 0-9, and without leading zeros. * * For example, given UserActiveModeTriggerHint="2048", ResetButtonTimes is set which indicates "Press * Reset Button for N seconds". Therefore, a value of UserActiveModeTriggerInstruction="10" would indicate @@ -582,13 +638,11 @@ export namespace IcdManagement { * indicated in the Device’s currently configured locale). The Custom Instruction option SHOULD NOT be used * by an ICD that does not have knowledge of the user’s language preference. * - * ### When the UserActiveModeTriggerHint key indicates a light to blink (ActuateSensorLightsBlink, + * When the UserActiveModeTriggerHint key indicates a light to blink (ActuateSensorLightsBlink, * ResetButtonLightsBlink or SetupButtonLightsBlink), information on color of light may be made available * via the UserActiveModeTriggerInstruction attribute. When using such color indication in the - * UserActiveModeTriggerInstruction attribute, only basic primary and secondary colors that could - * unambiguously be decoded by a commissioner and understood by an end-user, but without worry of - * localization, SHOULD be used, e.g. white, red, green, blue, orange, yellow, purple. The length of the - * attribute SHOULD be kept small. + * UserActiveModeTriggerInstruction attribute, the string shall consist of exactly 6 hexadecimal digits + * using the ASCII characters 0-F and encoding the RGB color value as used in HTML encodings. * * @see {@link MatterSpecification.v13.Core} § 9.17.6.8 */ @@ -623,7 +677,8 @@ export namespace IcdManagement { { flags: { userActiveModeTrigger: true }, component: UserActiveModeTriggerComponent }, { flags: { longIdleTimeSupport: true }, component: LongIdleTimeSupportComponent }, { flags: { longIdleTimeSupport: true, checkInProtocolSupport: false }, component: false }, - { flags: { longIdleTimeSupport: true, userActiveModeTrigger: false }, component: false } + { flags: { longIdleTimeSupport: true, userActiveModeTrigger: false }, component: false }, + { flags: { dynamicSitLitSupport: true, longIdleTimeSupport: false }, component: false } ) }); @@ -638,8 +693,6 @@ export namespace IcdManagement { * * The cluster implements the requirements of the Check-In Protocol that enables the ICD Check-In use case. * - * NOTE This feature is provisional. - * * IcdManagementCluster supports optional features that you can enable with the IcdManagementCluster.with() factory * method. * @@ -682,6 +735,10 @@ export namespace IcdManagement { operatingMode: MutableCluster.AsConditional( LongIdleTimeSupportComponent.attributes.operatingMode, { mandatoryIf: [LITS] } + ), + maximumCheckInBackoff: MutableCluster.AsConditional( + CheckInProtocolSupportComponent.attributes.maximumCheckInBackoff, + { mandatoryIf: [CIP] } ) }, diff --git a/packages/types/src/clusters/identify.ts b/packages/types/src/clusters/identify.ts index 708d29936d..e6e0219c1c 100644 --- a/packages/types/src/clusters/identify.ts +++ b/packages/types/src/clusters/identify.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -117,7 +117,7 @@ export namespace Identify { */ export const TlvTriggerEffectRequest = TlvObject({ /** - * This field specifies the identify effect to use and shall contain one of the non-reserved values in + * This field shall indicate the identify effect to use and shall contain one of the non-reserved values in * EffectIdentifierEnum. * * All values of the EffectIdentifierEnum shall be supported. Implementors may deviate from the example light @@ -128,8 +128,8 @@ export namespace Identify { effectIdentifier: TlvField(0, TlvEnum()), /** - * This field is used to indicate which variant of the effect, indicated in the EffectIdentifier field, SHOULD - * be triggered. If a device does not support the given variant, it shall use the default variant. This field + * This field shall indicate which variant of the effect, indicated in the EffectIdentifier field, SHOULD be + * triggered. If a device does not support the given variant, it shall use the default variant. This field * shall contain one of the values in EffectVariantEnum. * * @see {@link MatterSpecification.v13.Cluster} § 1.2.6.2.2 @@ -150,12 +150,11 @@ export namespace Identify { export const ClusterInstance = MutableCluster({ id: 0x3, name: "Identify", - revision: 4, + revision: 5, attributes: { /** - * This attribute specifies the remaining length of time, in seconds, that the endpoint will continue to - * identify itself. + * Indicates the remaining length of time, in seconds, that the endpoint will continue to identify itself. * * If this attribute is set to a value other than 0 then the device shall enter its identification state, * in order to indicate to an observer which of several nodes and/or endpoints it is. It is recommended @@ -170,11 +169,11 @@ export namespace Identify { identifyTime: WritableAttribute(0x0, TlvUInt16, { default: 0 }), /** - * This attribute specifies how the identification state is presented to the user. + * Indicates how the identification state is presented to the user. * - * This field shall contain one of the values defined in IdentifyTypeEnum. The value None shall NOT be used - * if the device is capable of presenting its identification state using one of the other methods defined - * in IdentifyTypeEnum. + * This attribute shall contain one of the values defined in IdentifyTypeEnum. The value None shall NOT be + * used if the device is capable of presenting its identification state using one of the other methods + * defined in IdentifyTypeEnum. * * @see {@link MatterSpecification.v13.Cluster} § 1.2.5.2 */ diff --git a/packages/types/src/clusters/illuminance-measurement.ts b/packages/types/src/clusters/illuminance-measurement.ts index 0fe6930b30..91bee000cf 100644 --- a/packages/types/src/clusters/illuminance-measurement.ts +++ b/packages/types/src/clusters/illuminance-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -39,7 +39,7 @@ export namespace IlluminanceMeasurement { attributes: { /** - * The MeasuredValue attribute represents the illuminance in Lux (symbol lx) as follows: + * Indicates the illuminance in Lux (symbol lx) as follows: * * • MeasuredValue = 10,000 x log10(illuminance) + 1, * @@ -59,20 +59,20 @@ export namespace IlluminanceMeasurement { measuredValue: Attribute(0x0, TlvNullable(TlvUInt16), { default: 0 }), /** - * The MinMeasuredValue attribute indicates the minimum value of MeasuredValue that can be measured. A - * value of null indicates that this attribute is not defined. See Measured Value for more details. + * Indicates the minimum value of MeasuredValue that can be measured. A value of null indicates that this + * attribute is not defined. See Measured Value for more details. * * @see {@link MatterSpecification.v13.Cluster} § 2.2.5.2 */ - minMeasuredValue: Attribute(0x1, TlvNullable(TlvUInt16.bound({ min: 1 }))), + minMeasuredValue: Attribute(0x1, TlvNullable(TlvUInt16.bound({ min: 1, max: 65533 }))), /** - * The MaxMeasuredValue attribute indicates the maximum value of MeasuredValue that can be measured. A - * value of null indicates that this attribute is not defined. See Measured Value for more details. + * Indicates the maximum value of MeasuredValue that can be measured. A value of null indicates that this + * attribute is not defined. See Measured Value for more details. * * @see {@link MatterSpecification.v13.Cluster} § 2.2.5.3 */ - maxMeasuredValue: Attribute(0x2, TlvNullable(TlvUInt16.bound({ max: 65534 }))), + maxMeasuredValue: Attribute(0x2, TlvNullable(TlvUInt16)), /** * See Measured Value. @@ -82,9 +82,8 @@ export namespace IlluminanceMeasurement { tolerance: OptionalAttribute(0x3, TlvUInt16.bound({ max: 2048 })), /** - * The LightSensorType attribute specifies the electronic type of the light sensor. This attribute shall be - * set to one of the non-reserved values listed in LightSensorTypeEnum or null in case the sensor type is - * unknown. + * Indicates the electronic type of the light sensor. This attribute shall be set to one of the + * non-reserved values listed in LightSensorTypeEnum or null in case the sensor type is unknown. * * @see {@link MatterSpecification.v13.Cluster} § 2.2.5.5 */ diff --git a/packages/types/src/clusters/index.ts b/packages/types/src/clusters/index.ts index 92d8c395cb..ccbd3bf891 100644 --- a/packages/types/src/clusters/index.ts +++ b/packages/types/src/clusters/index.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -38,6 +38,7 @@ export { } from "./carbon-monoxide-concentration-measurement.js"; export { ChannelCluster, Channel } from "./channel.js"; export { ColorControlCluster, ColorControl } from "./color-control.js"; +export { CommissionerControlCluster, CommissionerControl } from "./commissioner-control.js"; export { ConcentrationMeasurement } from "./concentration-measurement.js"; export { ContentAppObserverCluster, ContentAppObserver } from "./content-app-observer.js"; export { ContentControlCluster, ContentControl } from "./content-control.js"; @@ -49,6 +50,7 @@ export { DiagnosticLogsCluster, DiagnosticLogs } from "./diagnostic-logs.js"; export { DishwasherAlarmCluster, DishwasherAlarm } from "./dishwasher-alarm.js"; export { DishwasherModeCluster, DishwasherMode } from "./dishwasher-mode.js"; export { DoorLockCluster, DoorLock } from "./door-lock.js"; +export { EcosystemInformationCluster, EcosystemInformation } from "./ecosystem-information.js"; export { ElectricalEnergyMeasurementCluster, ElectricalEnergyMeasurement } from "./electrical-energy-measurement.js"; export { ElectricalPowerMeasurementCluster, ElectricalPowerMeasurement } from "./electrical-power-measurement.js"; export { EnergyEvseCluster, EnergyEvse } from "./energy-evse.js"; @@ -70,6 +72,8 @@ export { HepaFilterMonitoringCluster, HepaFilterMonitoring } from "./hepa-filter export { IcdManagementCluster, IcdManagement } from "./icd-management.js"; export { IdentifyCluster, Identify } from "./identify.js"; export { IlluminanceMeasurementCluster, IlluminanceMeasurement } from "./illuminance-measurement.js"; +export { JointFabricDatastoreClusterCluster, JointFabricDatastoreCluster } from "./joint-fabric-datastore-cluster.js"; +export { JointFabricPkiCluster, JointFabricPki } from "./joint-fabric-pki.js"; export { KeypadInputCluster, KeypadInput } from "./keypad-input.js"; export { Label } from "./label.js"; export { LaundryDryerControlsCluster, LaundryDryerControls } from "./laundry-dryer-controls.js"; @@ -111,7 +115,6 @@ export { PowerTopologyCluster, PowerTopology } from "./power-topology.js"; export { PressureMeasurementCluster, PressureMeasurement } from "./pressure-measurement.js"; export { ProxyConfigurationCluster, ProxyConfiguration } from "./proxy-configuration.js"; export { ProxyDiscoveryCluster, ProxyDiscovery } from "./proxy-discovery.js"; -export { PulseWidthModulationCluster, PulseWidthModulation } from "./pulse-width-modulation.js"; export { PumpConfigurationAndControlCluster, PumpConfigurationAndControl } from "./pump-configuration-and-control.js"; export { RadonConcentrationMeasurementCluster, @@ -128,6 +131,7 @@ export { RvcCleanModeCluster, RvcCleanMode } from "./rvc-clean-mode.js"; export { RvcOperationalStateCluster, RvcOperationalState } from "./rvc-operational-state.js"; export { RvcRunModeCluster, RvcRunMode } from "./rvc-run-mode.js"; export { ScenesManagementCluster, ScenesManagement } from "./scenes-management.js"; +export { ServiceAreaCluster, ServiceArea } from "./service-area.js"; export { SmokeCoAlarmCluster, SmokeCoAlarm } from "./smoke-co-alarm.js"; export { SoftwareDiagnosticsCluster, SoftwareDiagnostics } from "./software-diagnostics.js"; export { SwitchCluster, Switch } from "./switch.js"; @@ -139,7 +143,12 @@ export { ThermostatUserInterfaceConfigurationCluster, ThermostatUserInterfaceConfiguration } from "./thermostat-user-interface-configuration.js"; +export { + ThreadBorderRouterManagementCluster, + ThreadBorderRouterManagement +} from "./thread-border-router-management.js"; export { ThreadNetworkDiagnosticsCluster, ThreadNetworkDiagnostics } from "./thread-network-diagnostics.js"; +export { ThreadNetworkDirectoryCluster, ThreadNetworkDirectory } from "./thread-network-directory.js"; export { TimeFormatLocalizationCluster, TimeFormatLocalization } from "./time-format-localization.js"; export { TimeSynchronizationCluster, TimeSynchronization } from "./time-synchronization.js"; export { @@ -154,5 +163,9 @@ export { ValveConfigurationAndControl } from "./valve-configuration-and-control.js"; export { WakeOnLanCluster, WakeOnLan } from "./wake-on-lan.js"; +export { WaterHeaterManagementCluster, WaterHeaterManagement } from "./water-heater-management.js"; +export { WaterHeaterModeCluster, WaterHeaterMode } from "./water-heater-mode.js"; +export { WaterTankLevelMonitoringCluster, WaterTankLevelMonitoring } from "./water-tank-level-monitoring.js"; export { WiFiNetworkDiagnosticsCluster, WiFiNetworkDiagnostics } from "./wi-fi-network-diagnostics.js"; +export { WiFiNetworkManagementCluster, WiFiNetworkManagement } from "./wi-fi-network-management.js"; export { WindowCoveringCluster, WindowCovering } from "./window-covering.js"; diff --git a/packages/types/src/clusters/joint-fabric-datastore-cluster.ts b/packages/types/src/clusters/joint-fabric-datastore-cluster.ts new file mode 100644 index 0000000000..6963915b98 --- /dev/null +++ b/packages/types/src/clusters/joint-fabric-datastore-cluster.ts @@ -0,0 +1,657 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { FabricScopedAttribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; +import { TlvByteString, TlvString } from "../tlv/TlvString.js"; +import { AccessLevel } from "#model"; +import { TlvNodeId } from "../datatype/NodeId.js"; +import { TlvVendorId } from "../datatype/VendorId.js"; +import { TlvArray } from "../tlv/TlvArray.js"; +import { GroupKeyManagement } from "./group-key-management.js"; +import { TlvField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvUInt64, TlvUInt16, TlvEnum, TlvEpochS } from "../tlv/TlvNumber.js"; +import { AccessControl } from "./access-control.js"; +import { TlvFabricIndex } from "../datatype/FabricIndex.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { TlvEndpointNumber } from "../datatype/EndpointNumber.js"; +import { TlvGroupId } from "../datatype/GroupId.js"; +import { Binding } from "./binding.js"; +import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace JointFabricDatastoreCluster { + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4 + */ + export const TlvDatastoreGroupInformationEntry = TlvObject({ + /** + * The unique identifier for the group. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.1 + */ + groupId: TlvField(0, TlvUInt64), + + /** + * The friendly name for the group. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.2 + */ + friendlyName: TlvField(1, TlvString.bound({ maxLength: 32 })), + + /** + * The unique identifier for the group key set. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.3 + */ + groupKeySetId: TlvField(2, TlvUInt16.bound({ min: 1 })), + + /** + * CAT value for this group. This is used for control of individual members of a group (non-broadcast commands). + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.4 + */ + groupCat: TlvField(3, TlvUInt16.bound({ min: 1 })), + + /** + * Current version number for this CAT. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.5 + */ + groupCatVersion: TlvField(4, TlvUInt16.bound({ min: 1 })), + + /** + * The permission level associated with ACL entries for this group. There should be only one Administrator + * group per fabric, and at most one Manage group per Ecosystem (Vendor Entry). + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.6 + */ + groupPermission: TlvField(5, TlvEnum()), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4 + */ + export interface DatastoreGroupInformationEntry extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.1 + */ + export enum DatastoreState { + /** + * Target device operation is pending + */ + Pending = 0, + + /** + * Target device operation has been committed + */ + Committed = 1, + + /** + * Target device delete operation is pending + */ + DeletePending = 2 + } + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.2 + */ + export const TlvDatastoreStatusEntry = TlvObject({ + /** + * This field shall contain the current state of the target device operation. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.2.1 + */ + state: TlvField(0, TlvEnum()), + + /** + * This field shall contain the timestamp of the last update. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.2.2 + */ + updateTimestamp: TlvField(1, TlvEpochS), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.2 + */ + export interface DatastoreStatusEntry extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.3 + */ + export const TlvDatastoreNodeKeyEntry = TlvObject({ + groupKeySetId: TlvField(0, TlvUInt16), + + /** + * Indicates whether entry in this list is pending, committed, or delete-pending. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.3.2 + */ + statusEntry: TlvField(1, TlvDatastoreStatusEntry), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.3 + */ + export interface DatastoreNodeKeyEntry extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.7 + */ + export const TlvDatastoreAclEntry = TlvObject({ + /** + * The unique identifier for the ACL entry in the Datastore’s list of DatastoreACLEntry. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.7.1 + */ + listId: TlvField(0, TlvUInt16), + + /** + * The Access Control Entry structure. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.7.2 + */ + aclEntry: TlvField(1, AccessControl.TlvAccessControlEntry), + + /** + * Indicates whether entry in this list is pending, committed, or delete-pending. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.7.3 + */ + statusEntry: TlvField(2, TlvDatastoreStatusEntry), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.7 + */ + export interface DatastoreAclEntry extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.5 + */ + export const TlvDatastoreGroupIdEntry = TlvObject({ + /** + * The unique identifier for the group. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.5.1 + */ + groupId: TlvField(0, TlvGroupId), + + /** + * Indicates whether entry in this list is pending, committed, or delete-pending. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.5.2 + */ + statusEntry: TlvField(1, TlvDatastoreStatusEntry), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.5 + */ + export interface DatastoreGroupIdEntry extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.7 + */ + export const TlvDatastoreBindingEntry = TlvObject({ + /** + * The unique identifier for the Binding entry in the Datastore’s list of DatastoreBindingEntry. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.7.1 + */ + listId: TlvField(0, TlvUInt16), + + /** + * The binding target structure. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.7.2 + */ + binding: TlvField(1, Binding.TlvTarget), + + /** + * Indicates whether entry in this list is pending, committed, or delete-pending. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.7.3 + */ + statusEntry: TlvField(2, TlvDatastoreStatusEntry), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.4.7 + */ + export interface DatastoreBindingEntry extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.6 + */ + export const TlvDatastoreEndpointEntry = TlvObject({ + /** + * The unique identifier for the endpoint. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.6.1 + */ + endpointId: TlvField(0, TlvEndpointNumber), + + /** + * The unique identifier for the node. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.6.2 + */ + nodeId: TlvField(1, TlvNodeId), + + /** + * Friendly name for this endpoint which is propagated to nodes. Any changes to Friendly Name or Group Id List + * (add/remove entry) must follow the pending→committed workflow with current state reflected in the Status + * Entry. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.6.3 + */ + friendlyName: TlvField(2, TlvString.bound({ maxLength: 32 })), + + /** + * Indicates whether changes to Friendly Name are pending or committed. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.6.4 + */ + statusEntry: TlvField(3, TlvDatastoreStatusEntry), + + /** + * List of Group IDs that this endpoint is a member of. Any changes to Group Id List (add/remove entry) must + * follow the pending→committed workflow with current state reflected in the Status Entry. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.6.5 + */ + groupIdList: TlvField(4, TlvArray(TlvDatastoreGroupIdEntry)), + + /** + * List of Binding Targets for this endpoint. Any changes to Binding List (add/remove entry) must follow the + * pending→committed workflow with current state reflected in the Status Entry. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.6.6 + */ + bindingList: TlvField(5, TlvArray(TlvDatastoreBindingEntry)), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.6 + */ + export interface DatastoreEndpointEntry extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.8 + */ + export const TlvDatastoreNodeInformationEntry = TlvObject({ + /** + * The unique identifier for the node. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.8.1 + */ + nodeId: TlvField(1, TlvNodeId), + + /** + * Friendly name for this node which is not propagated to nodes. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.8.2 + */ + friendlyName: TlvField(2, TlvString.bound({ maxLength: 32 })), + + /** + * Set to pending prior to completing commissioning, and set to completed after commissioning complete is + * successful. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.8.3 + */ + commissioningStatusEntry: TlvField(3, TlvDatastoreStatusEntry), + + /** + * List of Key Set information for the given Node. Updates to the Group Key List must follow the + * pending→committed workflow with current state reflected in the Status Entry for the corresponding entry in + * the list. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.8.4 + */ + nodeKeySetList: TlvField(4, TlvArray(TlvDatastoreNodeKeyEntry)), + + /** + * List of ACL entries. Group membership for this node is inferred from the ACLs. Client access to a Node + * Information Entry will be determined from the ACL List. Any changes to ACL List (add/remove entry) must + * follow the pending→committed workflow with current state reflected in the Status Entry for the corresponding + * entry in the list. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.8.5 + */ + aclList: TlvField(5, TlvArray(TlvDatastoreAclEntry)), + + /** + * The list of endpoints for this node. Any changes to Endpoint List (add/remove entry) must follow the + * pending→committed workflow with current state reflected in the Status Entry for the corresponding entry in + * the list. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.8.6 + */ + endpointList: TlvField(6, TlvArray(TlvDatastoreEndpointEntry)), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.8 + */ + export interface DatastoreNodeInformationEntry extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.9 + */ + export const TlvDatastoreAdministratorInformationEntry = TlvObject({ + /** + * The unique identifier for the node. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.9.1 + */ + nodeId: TlvField(1, TlvNodeId), + + /** + * Friendly name for this node which is not propagated to nodes. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.9.2 + */ + friendlyName: TlvField(2, TlvString.bound({ maxLength: 32 })), + + /** + * The Vendor ID for the node. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.9.3 + */ + vendorId: TlvField(3, TlvVendorId), + + /** + * The ICAC used to issue the NOC. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.5.9.4 + */ + icac: TlvField(4, TlvByteString.bound({ maxLength: 400 })), + + fabricIndex: TlvField(254, TlvFabricIndex) + }); + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.5.9 + */ + export interface DatastoreAdministratorInformationEntry extends TypeFromSchema {} + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster({ + id: 0x752, + name: "JointFabricDatastoreCluster", + revision: 1, + + attributes: { + /** + * This shall indicate the Anchor Root CA used to sign all NOC Issuers in the Joint Fabric. A null value + * indicates that the Joint Fabric is not yet formed. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.1 + */ + anchorRootCa: FabricScopedAttribute( + 0x0, + TlvByteString, + { readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * This shall indicate the Node identifier of the Joint Fabric Anchor Root CA. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.2 + */ + anchorNodeId: FabricScopedAttribute( + 0x1, + TlvNodeId, + { readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * This shall indicate the Vendor identifier of the Joint Fabric Anchor Root CA. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.3 + */ + anchorVendorId: FabricScopedAttribute( + 0x2, + TlvVendorId, + { readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * Friendly name for this fabric which can be propagated to nodes. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.4 + */ + friendlyName: FabricScopedAttribute( + 0x3, + TlvString.bound({ maxLength: 32 }), + { readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * This shall indicate the list of GroupKeySetStruct used in the Joint Fabric. + * + * This attribute shall contain at least one entry, the IPK, which has GroupKeySetID of 0. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.5 + */ + groupKeySetList: FabricScopedAttribute( + 0x4, + TlvArray(GroupKeyManagement.TlvGroupKeySet), + { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * This shall indicate the list of groups in the Joint Fabric. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.6 + */ + groupList: FabricScopedAttribute( + 0x5, + TlvArray(TlvDatastoreGroupInformationEntry), + { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * This shall indicate the list of nodes in the Joint Fabric. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.7 + */ + nodeList: FabricScopedAttribute( + 0x6, + TlvArray(TlvDatastoreNodeInformationEntry), + { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * This shall indicate the list of administrators in the Joint Fabric. + * + * Only one Administrator may serve as the Anchor Root CA and Anchor Fabric Administrator and shall have + * index value 0. All other Joint Fabric Administrators shall be referenced at index 1 or greater. + * + * A null value or empty list indicates that the Joint Fabric is not yet formed. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.8 + */ + adminList: FabricScopedAttribute( + 0x7, + TlvArray(TlvDatastoreAdministratorInformationEntry), + { default: [], readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ), + + /** + * This shall indicate the current state of the Joint Fabric Datastore Cluster. + * + * The Committed status indicates the DataStore is ready for use. The Pending status indicates that the + * DataStore is not yet ready for use. The DeletePending status indicates that the DataStore is in the + * process of being transferred to another Joint Fabric Anchor Administrator. + * + * @see {@link MatterSpecification.v13.Core} § 11.24.6.9 + */ + statusEntry: FabricScopedAttribute( + 0x8, + TlvDatastoreAdministratorInformationEntry, + { readAcl: AccessLevel.Administer, writeAcl: AccessLevel.Administer } + ) + }, + + commands: { + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112471: Command(0x0, TlvNoArguments, 0x0, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112472: Command(0x1, TlvNoArguments, 0x1, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112473: Command(0x2, TlvNoArguments, 0x2, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112474: Command(0x3, TlvNoArguments, 0x3, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112475: Command(0x4, TlvNoArguments, 0x4, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112476: Command(0x5, TlvNoArguments, 0x5, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112477: Command(0x6, TlvNoArguments, 0x6, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112478: Command(0x7, TlvNoArguments, 0x7, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section112479: Command(0x8, TlvNoArguments, 0x8, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124710: Command(0x9, TlvNoArguments, 0x9, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124711: Command(0xa, TlvNoArguments, 0xa, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124712: Command(0xb, TlvNoArguments, 0xb, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124713: Command(0xc, TlvNoArguments, 0xc, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124714: Command(0xd, TlvNoArguments, 0xd, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124715: Command(0xe, TlvNoArguments, 0xe, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124716: Command(0xf, TlvNoArguments, 0xf, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124717: Command(0x10, TlvNoArguments, 0x10, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124718: Command(0x11, TlvNoArguments, 0x11, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124719: Command(0x12, TlvNoArguments, 0x12, TlvNoResponse, { invokeAcl: AccessLevel.Administer }), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.24.7 + */ + section1124720: Command(0x13, TlvNoArguments, 0x13, TlvNoResponse, { invokeAcl: AccessLevel.Administer }) + } + }); + + /** + * The Joint Fabric Datastore Cluster is a cluster that provides a mechanism for the Joint Fabric Administrators to + * manage the set of Nodes, Groups, and Group membership among Nodes in the Joint Fabric. + * + * When an Ecosystem Administrator Node is commissioned onto the Joint Fabric, the Ecosystem Administrator Node has + * no knowledge of what Nodes and Groups are present, or what set-up information related to the Joint Fabric is + * provided by the user. To address lack of knowledge, the Joint Fabric Datastore provides the information required + * for all Ecosystem Administrators to maintain a consistent view of the Joint Fabric including Nodes, Groups, + * settings and privileges. + * + * The Joint Fabric Datastore cluster server shall only be accessible on a Node which is acting as the Joint Fabric + * Anchor Administrator. When not acting as the Joint Fabric Anchor Administrator, the Joint Fabric Datastore + * cluster shall NOT be accessible. + * + * The Admin level of access to the Joint Fabric Datastore cluster server shall be limited to JF Administrator + * Nodes identified using the Administrator CAT. + * + * NOTE Support for Joint Fabric Datastore cluster is provisional. + * + * @see {@link MatterSpecification.v13.Core} § 11.24 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + export const Complete = Cluster; +} + +export type JointFabricDatastoreClusterCluster = JointFabricDatastoreCluster.Cluster; +export const JointFabricDatastoreClusterCluster = JointFabricDatastoreCluster.Cluster; +ClusterRegistry.register(JointFabricDatastoreCluster.Complete); diff --git a/packages/types/src/clusters/joint-fabric-pki.ts b/packages/types/src/clusters/joint-fabric-pki.ts new file mode 100644 index 0000000000..35a798414d --- /dev/null +++ b/packages/types/src/clusters/joint-fabric-pki.ts @@ -0,0 +1,202 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { Command, TlvNoResponse } from "../cluster/Cluster.js"; +import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js"; +import { TlvByteString } from "../tlv/TlvString.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { TlvEnum } from "../tlv/TlvNumber.js"; +import { AccessLevel } from "#model"; +import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace JointFabricPki { + /** + * Input to the JointFabricPki icacsrRequest command + * + * @see {@link MatterSpecification.v13.Core} § 11.25.5.1 + */ + export const TlvIcacsrRequest = TlvObject({ icacsr: TlvField(0, TlvByteString.bound({ maxLength: 400 })) }); + + /** + * Input to the JointFabricPki icacsrRequest command + * + * @see {@link MatterSpecification.v13.Core} § 11.25.5.1 + */ + export interface IcacsrRequest extends TypeFromSchema {} + + /** + * This enumeration is used by the ICACSRResponse command to convey the detailed outcome of this cluster’s + * ICACSRRequest command. + * + * @see {@link MatterSpecification.v13.Core} § 11.25.4.1 + */ + export enum IcacsrRequestStatus { + /** + * No error + */ + Ok = 0, + + /** + * The ICACSR in the request is not compliant to PKCS #10 rules + */ + InvalidIcaCsrFormat = 1, + + /** + * The ICACSR in the request has an incorrect signature + */ + InvalidIcaCsrSignature = 2, + + /** + * DCL Vendor ID validation failed + */ + FailedDclVendorIdValidation = 3, + + /** + * DCL returned certificate is not an ICAC + */ + NotAnIcac = 4, + + /** + * Error due to an in progress Anchor Transfer + */ + BusyAnchorTransfer = 5, + + /** + * Signing the ICA CSR failed + */ + IcaCsrSigningFailed = 6, + + /** + * No user consent + */ + IcaCsrRequestNoUserConsent = 7 + } + + /** + * This command shall be generated in response to the ICACSRRequest command. Check ICA Cross Signing for details + * about the generation and contents of ICAC. + * + * @see {@link MatterSpecification.v13.Core} § 11.25.5.2 + */ + export const TlvIcacsrResponse = TlvObject({ + /** + * This field shall contain an ICACSRRequestStatusEnum value representing the status of the Section 11.25.5.1, + * “ICACSRRequest Command” operation. + * + * @see {@link MatterSpecification.v13.Core} § 11.25.5.2.1 + */ + statusCode: TlvField(0, TlvEnum()), + + /** + * If present, it shall contain the NOC Issuer Certificate in PEM format. + * + * @see {@link MatterSpecification.v13.Core} § 11.25.5.2.2 + */ + icac: TlvOptionalField(1, TlvByteString.bound({ maxLength: 400 })) + }); + + /** + * This command shall be generated in response to the ICACSRRequest command. Check ICA Cross Signing for details + * about the generation and contents of ICAC. + * + * @see {@link MatterSpecification.v13.Core} § 11.25.5.2 + */ + export interface IcacsrResponse extends TypeFromSchema {} + + /** + * This enumeration is used by the TransferAnchorResponse command to convey the detailed outcome of this cluster’s + * TransferAnchorRequest command. + * + * @see {@link MatterSpecification.v13.Core} § 11.25.4.2 + */ + export enum TransferAnchorResponseStatus { + /** + * No error + */ + Ok = 0, + + /** + * Anchor Transfer was not started due to on- going Datastore operations + */ + TransferAnchorStatusDatastoreBusy = 1, + + /** + * User has not consented for Anchor Transfer + */ + TransferAnchorStatusNoUserConsent = 2 + } + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster({ + id: 0x753, + name: "JointFabricPki", + revision: 1, + + commands: { + /** + * This command shall be generated and executed during the Joint Commissioning Method steps and + * subsequently respond in the form of an ICACSRResponse command. + * + * Check ICA Cross Signing for details about the generation and contents of the ICACSR. + * + * @see {@link MatterSpecification.v13.Core} § 11.25.5.1 + */ + icacsrRequest: Command( + 0x0, + TlvIcacsrRequest, + 0x1, + TlvIcacsrResponse, + { invokeAcl: AccessLevel.Administer } + ), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.25.5 + */ + transferAnchorRequest: Command( + 0x2, + TlvNoArguments, + 0x3, + TlvNoArguments, + { invokeAcl: AccessLevel.Administer } + ), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.25.5 + */ + transferAnchorComplete: Command( + 0x4, + TlvNoArguments, + 0x4, + TlvNoResponse, + { invokeAcl: AccessLevel.Administer } + ) + } + }); + + /** + * An instance of the Joint Fabric PKI Cluster only applies to Joint Fabric Administrator nodes fulfilling the role + * of Anchor CA. + * + * NOTE Support for Joint Fabric PKI Cluster is provisional. + * + * @see {@link MatterSpecification.v13.Core} § 11.25 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + export const Complete = Cluster; +} + +export type JointFabricPkiCluster = JointFabricPki.Cluster; +export const JointFabricPkiCluster = JointFabricPki.Cluster; +ClusterRegistry.register(JointFabricPki.Complete); diff --git a/packages/types/src/clusters/keypad-input.ts b/packages/types/src/clusters/keypad-input.ts index ee470d1561..cf2fe06842 100644 --- a/packages/types/src/clusters/keypad-input.ts +++ b/packages/types/src/clusters/keypad-input.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -177,7 +177,7 @@ export namespace KeypadInput { } /** - * This command shall be generated in response to a SendKey command. + * This command shall be generated in response to a SendKey command. The data for this command shall be as follows: * * @see {@link MatterSpecification.v13.Cluster} § 6.8.6.2 */ @@ -191,7 +191,7 @@ export namespace KeypadInput { }); /** - * This command shall be generated in response to a SendKey command. + * This command shall be generated in response to a SendKey command. The data for this command shall be as follows: * * @see {@link MatterSpecification.v13.Cluster} § 6.8.6.2 */ diff --git a/packages/types/src/clusters/label.ts b/packages/types/src/clusters/label.ts index 7267aa5522..458b04ba1c 100644 --- a/packages/types/src/clusters/label.ts +++ b/packages/types/src/clusters/label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/laundry-dryer-controls.ts b/packages/types/src/clusters/laundry-dryer-controls.ts index e18112a5e7..ce5ddf12e0 100644 --- a/packages/types/src/clusters/laundry-dryer-controls.ts +++ b/packages/types/src/clusters/laundry-dryer-controls.ts @@ -1,13 +1,13 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; -import { WritableAttribute } from "../cluster/Cluster.js"; +import { Attribute, WritableAttribute } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvEnum } from "../tlv/TlvNumber.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; @@ -55,18 +55,14 @@ export namespace LaundryDryerControls { attributes: { /** - * Indicates the list of supported dryness levels available to the appliance in the - * - * currently selected mode. The dryness level values are determined by the manufacturer. At least one - * dryness level value shall be provided in the SupportedDrynessLevels list. The list of dryness levels may - * change depending on the currently-selected Laundry Dryer mode. + * Indicates the list of supported dryness levels available to the appliance in the currently selected + * mode. The dryness level values are determined by the manufacturer. At least one dryness level value + * shall be provided in the SupportedDrynessLevels list. The list of dryness levels may change depending on + * the currently-selected Laundry Dryer mode. * * @see {@link MatterSpecification.v13.Cluster} § 8.9.5.1 */ - supportedDrynessLevels: WritableAttribute( - 0x0, - TlvArray(TlvEnum(), { minLength: 1, maxLength: 4 }) - ), + supportedDrynessLevels: Attribute(0x0, TlvArray(TlvEnum(), { minLength: 1, maxLength: 4 })), /** * Indicates the currently-selected dryness level and it shall be the index into the SupportedDrynessLevels diff --git a/packages/types/src/clusters/laundry-washer-controls.ts b/packages/types/src/clusters/laundry-washer-controls.ts index 57e72f7a32..3af9fd1a52 100644 --- a/packages/types/src/clusters/laundry-washer-controls.ts +++ b/packages/types/src/clusters/laundry-washer-controls.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -79,24 +79,23 @@ export namespace LaundryWasherControls { export const SpinComponent = MutableCluster.Component({ attributes: { /** - * This attribute indicates the list of spin speeds available to the appliance in the currently selected - * mode. The spin speed values are determined by the manufacturer. At least one spin speed value shall be - * provided in the SpinSpeeds list. The list of spin speeds may change depending on the currently selected - * Laundry Washer mode. For example, Quick mode might have a completely different list of SpinSpeeds than - * Delicates mode. + * Indicates the list of spin speeds available to the appliance in the currently selected mode. The spin + * speed values are determined by the manufacturer. At least one spin speed value shall be provided in the + * SpinSpeeds list. The list of spin speeds may change depending on the currently selected Laundry Washer + * mode. For example, Quick mode might have a completely different list of SpinSpeeds than Delicates mode. * * @see {@link MatterSpecification.v13.Cluster} § 8.6.6.1 */ spinSpeeds: Attribute(0x0, TlvArray(TlvString, { maxLength: 16 }), { default: [] }), /** - * This attribute indicates the currently selected spin speed. It is the index into the SpinSpeeds list of - * the selected spin speed, as such, this attribute can be an integer between 0 and the number of entries - * in SpinSpeeds - 1. If a value is received that is outside of the defined constraints, a CONSTRAINT_ERROR - * shall be sent as the response. If a value is attempted to be written that doesn’t match a valid index - * (e.g. an index of 5 when the list has 4 values), a CONSTRAINT_ERROR shall be sent as the response. If - * null is written to this attribute, there will be no spin speed for the selected cycle. If the value is - * null, there will be no spin speed on the current mode. + * Indicates the currently selected spin speed. It is the index into the SpinSpeeds list of the selected + * spin speed, as such, this attribute can be an integer between 0 and the number of entries in SpinSpeeds + * - 1. If a value is received that is outside of the defined constraints, a CONSTRAINT_ERROR shall be sent + * as the response. If a value is attempted to be written that doesn’t match a valid index (e.g. an index + * of 5 when the list has 4 values), a CONSTRAINT_ERROR shall be sent as the response. If null is written + * to this attribute, there will be no spin speed for the selected cycle. If the value is null, there will + * be no spin speed on the current mode. * * @see {@link MatterSpecification.v13.Cluster} § 8.6.6.2 */ @@ -110,18 +109,19 @@ export namespace LaundryWasherControls { export const RinseComponent = MutableCluster.Component({ attributes: { /** - * This attribute represents how many times a rinse cycle shall be performed on a device for the current - * mode of operation. A value of None shall indicate that no rinse cycle will be performed. This value may - * be set by the client to adjust the number of rinses that are performed for the current mode of - * operation. If the device is not in a compatible state to accept the provided value, an INVALID_IN_STATE - * error shall be sent as the response. + * Indicates how many times a rinse cycle shall be performed on a device for the current mode of operation. + * A value of None shall indicate that no rinse cycle will be performed. This value may be set by the + * client to adjust the number of rinses that are performed for + * + * the current mode of operation. If the device is not in a compatible state to accept the provided value, + * an INVALID_IN_STATE error shall be sent as the response. * * @see {@link MatterSpecification.v13.Cluster} § 8.6.6.3 */ numberOfRinses: WritableAttribute(0x2, TlvEnum(), { default: NumberOfRinses.Normal }), /** - * This attribute represents the amount of rinses allowed for a specific mode. Each entry shall indicate a + * Indicates the amount of rinses allowed for a specific mode. Each entry shall indicate a * NumberOfRinsesEnum value that is possible in the selected mode on the device. The value of this * attribute may change at runtime based on the currently selected mode. Each entry shall be distinct. * @@ -137,7 +137,7 @@ export namespace LaundryWasherControls { export const Base = MutableCluster.Component({ id: 0x53, name: "LaundryWasherControls", - revision: 1, + revision: 2, features: { /** @@ -167,20 +167,21 @@ export namespace LaundryWasherControls { */ extensions: MutableCluster.Extensions( { flags: { spin: true }, component: SpinComponent }, - { flags: { rinse: true }, component: RinseComponent } + { flags: { rinse: true }, component: RinseComponent }, + { flags: { spin: false, rinse: false }, component: false } ) }); /** * @see {@link Cluster} */ - export const ClusterInstance = MutableCluster(Base); + export const ClusterInstance = MutableCluster.ExtensibleOnly(Base); /** * This cluster provides a way to access options associated with the operation of a laundry washer device type. * - * LaundryWasherControlsCluster supports optional features that you can enable with the - * LaundryWasherControlsCluster.with() factory method. + * Per the Matter specification you cannot use {@link LaundryWasherControlsCluster} without enabling certain + * feature combinations. You must use the {@link with} factory method to obtain a working cluster. * * @see {@link MatterSpecification.v13.Cluster} § 8.6 */ @@ -194,10 +195,10 @@ export namespace LaundryWasherControls { * @see {@link Complete} */ export const CompleteInstance = MutableCluster({ - id: Cluster.id, - name: Cluster.name, - revision: Cluster.revision, - features: Cluster.features, + id: Base.id, + name: Base.name, + revision: Base.revision, + features: Base.features, attributes: { spinSpeeds: MutableCluster.AsConditional(SpinComponent.attributes.spinSpeeds, { mandatoryIf: [SPIN] }), diff --git a/packages/types/src/clusters/laundry-washer-mode.ts b/packages/types/src/clusters/laundry-washer-mode.ts index c3fb314fe2..eb12ed487a 100644 --- a/packages/types/src/clusters/laundry-washer-mode.ts +++ b/packages/types/src/clusters/laundry-washer-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,14 +8,14 @@ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; import { BitFlag } from "../schema/BitmapSchema.js"; -import { FixedAttribute, Attribute, WritableAttribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; +import { FixedAttribute, Attribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -23,118 +23,95 @@ export namespace LaundryWasherMode { /** * These are optional features supported by LaundryWasherModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } export enum ModeTag { /** - * The normal regime of operation. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.5.6.1.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - Normal = 16384, + Auto = 0, /** - * Mode optimized for washing delicate garments. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.5.6.1.2 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - Delicate = 16385, + Quick = 1, /** - * Mode optimized for heavy washing. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.5.6.1.3 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - Heavy = 16386, + Quiet = 2, /** - * Mode optimized for stain removal on white fabrics. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.5.6.1.4 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - Whites = 16387, + LowNoise = 3, /** - * The device decides which options, features and setting values to use. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - Auto = 0, + LowEnergy = 4, /** - * The mode of the device is optimizing for faster completion. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - Quick = 1, + Vacation = 5, /** - * The device is silent or barely audible while in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - Quiet = 2, + Min = 6, /** - * Either the mode is inherently low noise or the device optimizes for that. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - LowNoise = 3, + Max = 7, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - LowEnergy = 4, + Night = 8, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1 */ - Vacation = 5, + Day = 9, /** - * The mode uses the lowest available setting value. + * The normal regime of operation. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1.1 */ - Min = 6, + Normal = 16384, /** - * The mode uses the highest available setting value. + * Mode optimized for washing delicate garments. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1.2 */ - Max = 7, + Delicate = 16385, /** - * The mode is recommended or suitable for use during night time. + * Mode optimized for heavy washing. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1.3 */ - Night = 8, + Heavy = 16386, /** - * The mode is recommended or suitable for use during day time. + * Mode optimized for stain removal on white fabrics. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.7.1.4 */ - Day = 9 + Whites = 16387 } /** @@ -164,7 +141,7 @@ export namespace LaundryWasherMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -178,9 +155,7 @@ export namespace LaundryWasherMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags field list. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.5.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.5.1 */ export const TlvModeOption = TlvObject({ /** @@ -242,9 +217,7 @@ export namespace LaundryWasherMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags field list. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.5.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.5.1 */ export interface ModeOption extends TypeFromSchema {} @@ -254,23 +227,23 @@ export namespace LaundryWasherMode { export const Base = MutableCluster.Component({ id: 0x51, name: "LaundryWasherMode", - revision: 2, + revision: 3, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * @see {@link MatterSpecification.v13.Cluster} § 8.5.5 + * At least one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags + * field list. + * + * @see {@link MatterSpecification.v13.Cluster} § 8.5.6.1 */ supportedModes: FixedAttribute( 0x0, @@ -279,23 +252,9 @@ export namespace LaundryWasherMode { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 8.5.5 - */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }), - - /** - * If this attribute is supported, the device SHOULD initially set this to one of the supported modes that - * has the Normal tag associated with it. See the Mode Base cluster specification for full details about - * the StartUpMode attribute. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.5.5.1 - */ - startUpMode: WritableAttribute(0x2, TlvUInt8, { persistent: true }), - - /** - * @see {@link MatterSpecification.v13.Cluster} § 8.5.5 + * @see {@link MatterSpecification.v13.Cluster} § 8.5.6 */ - onMode: WritableAttribute(0x3, TlvUInt8, { persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, commands: { @@ -313,7 +272,7 @@ export namespace LaundryWasherMode { * This metadata controls which LaundryWasherModeCluster elements matter.js activates for specific feature * combinations. */ - extensions: MutableCluster.Extensions() + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -322,7 +281,7 @@ export namespace LaundryWasherMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced enumerated + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated * values for laundry washer as well as laundry dryer devices. * * LaundryWasherModeCluster supports optional features that you can enable with the LaundryWasherModeCluster.with() diff --git a/packages/types/src/clusters/level-control.ts b/packages/types/src/clusters/level-control.ts index e15293da09..e634b2dfb6 100644 --- a/packages/types/src/clusters/level-control.ts +++ b/packages/types/src/clusters/level-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -153,11 +153,12 @@ export namespace LevelControl { /** * This field shall indicate the rate of movement in units per second. The actual rate of movement SHOULD be as - * close to this rate as the device is able. If the Rate field is equal to null, then the value in - * DefaultMoveRate attribute shall be used. However, if the Rate field is equal to null and the DefaultMoveRate - * attribute is not supported, or if the Rate field is equal to null and the value of the DefaultMoveRate - * attribute is equal to null, then the device SHOULD move as fast as it is able. If the device is not able to - * move at a variable rate, this field may be disregarded. + * close to this rate as the device is able. If the Rate field is null, then the value of the DefaultMoveRate + * attribute shall be used if that attribute is supported and its value is not null. If the Rate field is null + * and the DefaultMoveRate attribute is either not supported or set to null, then the device SHOULD move as + * fast as it is able. If the device is not able to move at a variable rate, this + * + * field may be disregarded. * * @see {@link MatterSpecification.v13.Cluster} § 1.6.7.2.2 */ @@ -211,8 +212,10 @@ export namespace LevelControl { /** * This field shall indicate the time that shall be taken to perform the step, in tenths of a second. A step is - * a change in the CurrentLevel of StepSize units. The actual time taken SHOULD be as close to this as the - * device is able. If the TransitionTime field is equal to null, the device SHOULD move as fast as it is able. + * a change in the CurrentLevel of StepSize units. The actual time taken SHOULD be as close to + * + * this as the device is able. If the TransitionTime field is equal to null, the device SHOULD move as fast as + * it is able. * * If the device is not able to move at a variable rate, the TransitionTime field may be disregarded. * @@ -257,6 +260,20 @@ export namespace LevelControl { * Indicates the time remaining until the current command is complete - it is specified in 1/10ths of a * second. * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • When it changes from 0 to any value higher than 10, or + * + * • When it changes, with a delta larger than 10, caused by the invoke of a command, or + * + * • When it changes to 0. + * + * For commands with a transition time or changes to the transition time less than 1 second, changes to + * this attribute shall NOT be reported. + * + * As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the + * reporting of this attribute in order to keep track of the remaining duration. + * * @see {@link MatterSpecification.v13.Cluster} § 1.6.6.3 */ remainingTime: Attribute(0x1, TlvUInt16, { default: 0 }), @@ -266,7 +283,7 @@ export namespace LevelControl { * * @see {@link MatterSpecification.v13.Cluster} § 1.6.6.4 */ - minLevel: OptionalAttribute(0x2, TlvUInt8.bound({ min: 1 }), { default: 1 }), + minLevel: OptionalAttribute(0x2, TlvUInt8.bound({ min: 1, max: 254 }), { default: 1 }), /** * Indicates the desired startup level for a device when it is supplied with power and this level shall be @@ -296,7 +313,7 @@ export namespace LevelControl { * * @see {@link MatterSpecification.v13.Cluster} § 1.6.6.4 */ - minLevel: OptionalAttribute(0x2, TlvUInt8, { default: 0 }) + minLevel: OptionalAttribute(0x2, TlvUInt8.bound({ max: 254 }), { default: 0 }) } }); @@ -308,6 +325,14 @@ export namespace LevelControl { /** * Indicates the frequency at which the device is at CurrentLevel. A CurrentFrequency of 0 is unknown. * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once per second, or + * + * • At the start of the movement/transition, or + * + * • At the end of the movement/transition. + * * @see {@link MatterSpecification.v13.Cluster} § 1.6.6.6 */ currentFrequency: Attribute(0x4, TlvUInt16, { scene: true, default: 0 }), @@ -343,7 +368,7 @@ export namespace LevelControl { export const Base = MutableCluster.Component({ id: 0x8, name: "LevelControl", - revision: 5, + revision: 6, features: { /** @@ -385,6 +410,14 @@ export namespace LevelControl { /** * Indicates the current level of this device. The meaning of 'level' is device dependent. * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once per second, or + * + * • At the end of the movement/transition, or + * + * • When it changes from null to any other value and vice versa. + * * @see {@link MatterSpecification.v13.Cluster} § 1.6.6.2 */ currentLevel: Attribute(0x0, TlvNullable(TlvUInt8), { scene: true, persistent: true, default: null }), @@ -436,7 +469,7 @@ export namespace LevelControl { * Indicates the value that the CurrentLevel attribute is set to when the OnOff attribute of an On/Off * cluster on the same endpoint is set to TRUE, as a result of processing an On/Off cluster command. If the * OnLevel attribute is not implemented, or is set to the null value, it has no effect. For more details - * see Effect of On/Off Commands on the CurrentLevel Attribute. + * see Effect of On/Off Commands on the CurrentLevel attribute. * * OnLevel represents a mandatory field that was previously not present or optional. Implementers should be * aware that older devices may not implement it. @@ -471,7 +504,7 @@ export namespace LevelControl { * * @see {@link MatterSpecification.v13.Cluster} § 1.6.6.14 */ - defaultMoveRate: OptionalWritableAttribute(0x14, TlvNullable(TlvUInt8)) + defaultMoveRate: OptionalWritableAttribute(0x14, TlvNullable(TlvUInt8.bound({ min: 1 }))) }, commands: { diff --git a/packages/types/src/clusters/localization-configuration.ts b/packages/types/src/clusters/localization-configuration.ts index ce574c9c27..dc4e914d0b 100644 --- a/packages/types/src/clusters/localization-configuration.ts +++ b/packages/types/src/clusters/localization-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -26,13 +26,12 @@ export namespace LocalizationConfiguration { attributes: { /** * The ActiveLocale attribute shall represent the locale that the Node is currently configured to use when - * conveying information. The ActiveLocale attribute shall be a Language Tag as defined by BCP47 - * [https://tools.ietf.org/rfc/bcp/bcp47.txt]. The ActiveLocale attribute shall have a default value - * assigned by the Vendor and shall be a value contained within the SupportedLocales attribute. + * conveying information. The ActiveLocale attribute shall be a Language Tag as defined by BCP47. The + * ActiveLocale attribute shall have a default value assigned by the Vendor and shall be a value contained + * within the SupportedLocales attribute. * - * An attempt to write a value to ActiveLocale that is not present in SupportedLocales shall result in - * - * a CONSTRAINT_ERROR error. + * An attempt to write a value to ActiveLocale that is not present in SupportedLocales shall result in a + * CONSTRAINT_ERROR error. * * @see {@link MatterSpecification.v13.Core} § 11.3.4.1 */ diff --git a/packages/types/src/clusters/low-power.ts b/packages/types/src/clusters/low-power.ts index 6420ba0579..5eccd8607a 100644 --- a/packages/types/src/clusters/low-power.ts +++ b/packages/types/src/clusters/low-power.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/media-input.ts b/packages/types/src/clusters/media-input.ts index aca60afcd6..75396e7154 100644 --- a/packages/types/src/clusters/media-input.ts +++ b/packages/types/src/clusters/media-input.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -186,8 +186,9 @@ export namespace MediaInput { commands: { /** - * Upon receipt, this command shall change the media input on the device to the input at a specific index - * in the Input List. + * Upon receipt, this command shall change the media input on the device to the input at a specific + * + * index in the Input List. * * @see {@link MatterSpecification.v13.Cluster} § 6.9.7.1 */ diff --git a/packages/types/src/clusters/media-playback.ts b/packages/types/src/clusters/media-playback.ts index ad73470c20..9b66757c38 100644 --- a/packages/types/src/clusters/media-playback.ts +++ b/packages/types/src/clusters/media-playback.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -75,9 +75,10 @@ export namespace MediaPlayback { /** * AudioAdvance (AA) * - * This feature is for a device or app that supports playing audio during fast and slow advance and rewind - * (e.g., while playback speed is not 1). A device that supports this feature may only support playing audio - * during certain speeds. + * This feature is for a device or app that supports playing audio during fast and slow advance and + * + * rewind (e.g., while playback speed is not 1). A device that supports this feature may only support playing + * audio during certain speeds. * * A cluster implementing AA shall implement AS. * @@ -102,7 +103,7 @@ export namespace MediaPlayback { /** * This field shall indicate the associated discrete position within the media stream, in milliseconds from the * beginning of the stream, being associated with the time indicated by the UpdatedAt field. The Position shall - * not be greater than the duration of the media if duration is specified. The Position shall not be greater + * NOT be greater than the duration of the media if duration is specified. The Position shall NOT be greater * than the time difference between current time and start time of the media when start time is specified. * * A value of null shall indicate that playback position is not applicable for the current state of the media @@ -938,9 +939,10 @@ export namespace MediaPlayback { /** * AudioAdvance * - * This feature is for a device or app that supports playing audio during fast and slow advance and rewind - * (e.g., while playback speed is not 1). A device that supports this feature may only support playing - * audio during certain speeds. + * This feature is for a device or app that supports playing audio during fast and slow advance and + * + * rewind (e.g., while playback speed is not 1). A device that supports this feature may only support + * playing audio during certain speeds. * * A cluster implementing AA shall implement AS. * diff --git a/packages/types/src/clusters/messages.ts b/packages/types/src/clusters/messages.ts index 49e78a89e5..76fb30b45c 100644 --- a/packages/types/src/clusters/messages.ts +++ b/packages/types/src/clusters/messages.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/microwave-oven-control.ts b/packages/types/src/clusters/microwave-oven-control.ts index 144b6a83d4..aa59f36eb9 100644 --- a/packages/types/src/clusters/microwave-oven-control.ts +++ b/packages/types/src/clusters/microwave-oven-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -147,17 +147,22 @@ export namespace MicrowaveOvenControl { export const PowerAsNumberComponent = MutableCluster.Component({ attributes: { /** - * Indicates the power level associated with the operation of the device. + * Indicates the power level associated with the operation of the device. If the MinPower, MaxPower, and + * PowerStep attributes are not supported: * - * If the MinPower, MaxPower, and PowerStep attributes are not supported, the minimum value of this - * attribute shall be 10, the maximum value of this attribute shall be 100, the value shall be in even - * multiples of 10, and the default value shall be 100. + * • The minimum value of this attribute shall be 10, + * + * • The maximum value of this attribute shall be 100, + * + * • The value shall be in even multiples of 10, + * + * • The default value shall be 100. * * If the MinPower, MaxPower, and PowerStep attributes are supported: * * • The value of this attribute shall be between MinPower and MaxPower inclusive. * - * • The value of this attribute shall be an integer multiple of PowerStep. + * • The value of this attribute shall be such that (PowerSetting - MinPower) % PowerStep == 0 * * @see {@link MatterSpecification.v13.Cluster} § 8.13.5.3 */ @@ -171,26 +176,24 @@ export namespace MicrowaveOvenControl { export const PowerNumberLimitsComponent = MutableCluster.Component({ attributes: { /** - * Indicates the minimum power level that can be set on the server. The value of this attribute shall be - * less than or equal to the value of MaxPower. The value of this attribute - * - * shall be an integer multiple of PowerStep. + * Indicates the minimum value to which the PowerSetting attribute that can be set on the server. * * @see {@link MatterSpecification.v13.Cluster} § 8.13.5.4 */ - minPower: FixedAttribute(0x3, TlvUInt8.bound({ min: 1 }), { default: 10 }), + minPower: FixedAttribute(0x3, TlvUInt8.bound({ min: 1, max: 99 }), { default: 10 }), /** - * Indicates the maximum power level that can be set on the server. The value of this attribute shall be - * greater than or equal to the value of MinPower. The value of this attribute shall be an integer multiple - * of PowerStep. + * Indicates the maximum value to which the PowerSetting attribute that can be set on the server. * * @see {@link MatterSpecification.v13.Cluster} § 8.13.5.5 */ maxPower: FixedAttribute(0x4, TlvUInt8.bound({ max: 100 }), { default: 100 }), /** - * Indicates the increment of power that can be set on the server. + * Indicates the increment of power that can be set on the server. The value of this attribute shall be + * between 1 and MaxPower inclusive. + * + * The value of this attribute shall be such that (MaxPower - MinPower) % PowerStep == 0 * * For example, if MinPower is 1, MaxPower is 10, and PowerSetting can be set to any integer between * MinPower and MaxPower, PowerStep would be set to 1. @@ -286,9 +289,8 @@ export namespace MicrowaveOvenControl { commands: { /** - * This command is used to set the cooking parameters associated with the operation of the device. - * - * This command supports the following fields: + * This command is used to set the cooking parameters associated with the operation of the device. This + * command supports the following fields: * * @see {@link MatterSpecification.v13.Cluster} § 8.13.6.2 */ diff --git a/packages/types/src/clusters/microwave-oven-mode.ts b/packages/types/src/clusters/microwave-oven-mode.ts index c24947c2d5..f9b1886537 100644 --- a/packages/types/src/clusters/microwave-oven-mode.ts +++ b/packages/types/src/clusters/microwave-oven-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,6 +14,7 @@ import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; +import { ModeBase } from "./mode-base.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -22,104 +23,81 @@ export namespace MicrowaveOvenMode { /** * These are optional features supported by MicrowaveOvenModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } export enum ModeTag { /** - * The normal mode of operation - * - * @see {@link MatterSpecification.v13.Cluster} § 8.12.6.1 - */ - Normal = 16384, - - /** - * A mode optimized for defrosting foods - * - * @see {@link MatterSpecification.v13.Cluster} § 8.12.6.1 - */ - Defrost = 16385, - - /** - * The device decides which options, features and setting values to use. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ Auto = 0, /** - * The mode of the device is optimizing for faster completion. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ Quick = 1, /** - * The device is silent or barely audible while in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ Quiet = 2, /** - * Either the mode is inherently low noise or the device optimizes for that. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ LowNoise = 3, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ LowEnergy = 4, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ Vacation = 5, /** - * The mode uses the lowest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ Min = 6, /** - * The mode uses the highest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ Max = 7, /** - * The mode is recommended or suitable for use during night time. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 */ Night = 8, /** - * The mode is recommended or suitable for use during day time. + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1 + */ + Day = 9, + + /** + * This is the normal mode of operation for general cooking of food. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1.1 */ - Day = 9 + Normal = 16384, + + /** + * This is a mode optimized for defrosting food. + * + * @see {@link MatterSpecification.v13.Cluster} § 8.12.7.1.2 + */ + Defrost = 16385 } /** @@ -149,7 +127,7 @@ export namespace MicrowaveOvenMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -233,23 +211,26 @@ export namespace MicrowaveOvenMode { export const Base = MutableCluster.Component({ id: 0x5e, name: "MicrowaveOvenMode", - revision: 1, + revision: 2, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * @see {@link MatterSpecification.v13.Cluster} § 8.12.4 + * Exactly one entry in the SupportedModes attribute shall include the Normal mode tag in the ModeTags + * field. + * + * The Normal and Defrost mode tags are mutually exclusive and shall NOT both be used together in a mode’s + * ModeTags. + * + * @see {@link MatterSpecification.v13.Cluster} § 8.12.5.1 */ supportedModes: FixedAttribute( 0x0, @@ -258,16 +239,16 @@ export namespace MicrowaveOvenMode { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 8.12.4 + * @see {@link MatterSpecification.v13.Cluster} § 8.12.5 */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, /** * This metadata controls which MicrowaveOvenModeCluster elements matter.js activates for specific feature * combinations. */ - extensions: MutableCluster.Extensions() + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -276,8 +257,8 @@ export namespace MicrowaveOvenMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced enumerated - * values for Microwave Oven devices. + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated + * values for microwave oven devices. * * MicrowaveOvenModeCluster supports optional features that you can enable with the MicrowaveOvenModeCluster.with() * factory method. diff --git a/packages/types/src/clusters/mode-base.ts b/packages/types/src/clusters/mode-base.ts index 89c5592659..d25483f6d9 100644 --- a/packages/types/src/clusters/mode-base.ts +++ b/packages/types/src/clusters/mode-base.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -45,71 +45,51 @@ export namespace ModeBase { export enum ModeTag { /** - * The device decides which options, features and setting values to use. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ Auto = 0, /** - * The mode of the device is optimizing for faster completion. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ Quick = 1, /** - * The device is silent or barely audible while in this mode. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ Quiet = 2, /** - * Either the mode is inherently low noise or the device optimizes for that. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ LowNoise = 3, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ LowEnergy = 4, /** - * A mode suitable for use during vacations or other extended absences. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ Vacation = 5, /** - * The mode uses the lowest available setting value. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ Min = 6, /** - * The mode uses the highest available setting value. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ Max = 7, /** - * The mode is recommended or suitable for use during night time. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ Night = 8, /** - * The mode is recommended or suitable for use during day time. - * * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 */ Day = 9 @@ -235,7 +215,7 @@ export namespace ModeBase { * able to transition as requested, the ChangeToModeResponse command shall: * * • Have the Status set to a product-specific Status value representing the error, or GenericFailure if a - * more specific error cannot be provided. See Status Field for details. + * more specific error cannot be provided. See Status field for details. * * • Provide a human readable string in the StatusText field. * @@ -245,10 +225,9 @@ export namespace ModeBase { * supplied with a human readable string or include an empty string and the CurrentMode field shall be set to * the value of the NewMode field. * - * If the NewMode field is the same as the value of the CurrentMode attribute the ChangeToModeRe - * - * sponse command shall have the Status field set to Success and the StatusText field may be supplied with a - * human readable string or include an empty string. + * If the NewMode field is the same as the value of the CurrentMode attribute the ChangeToModeResponse command + * shall have the Status field set to Success and the StatusText field may be supplied with a human readable + * string or include an empty string. * * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.1.1 */ @@ -263,7 +242,9 @@ export namespace ModeBase { export interface ChangeToModeRequest extends TypeFromSchema {} /** - * This command is sent by the device on receipt of the ChangeToMode command. + * This command is sent by the device on receipt of the ChangeToMode command. This command + * + * shall have the following data fields: * * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2 */ @@ -277,7 +258,9 @@ export namespace ModeBase { }); /** - * This command is sent by the device on receipt of the ChangeToMode command. + * This command is sent by the device on receipt of the ChangeToMode command. This command + * + * shall have the following data fields: * * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2 */ @@ -293,7 +276,7 @@ export namespace ModeBase { Success = 0, /** - * The value of the NewMode field doesn’t match any entries in the SupportedMode attribute. + * The value of the NewMode field doesn’t match any entries in the SupportedModes attribute. * * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 */ @@ -327,7 +310,7 @@ export namespace ModeBase { * * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.5 + * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.4 */ onMode: WritableAttribute(0x3, TlvNullable(TlvUInt8), { persistent: true, default: null }) } @@ -362,7 +345,7 @@ export namespace ModeBase { * Each entry in this list shall have a unique value for the Mode field. Each entry in this list shall have * a unique value for the Label field. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.2 + * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.1 */ supportedModes: FixedAttribute(0x0, TlvArray(TlvModeOption, { minLength: 2, maxLength: 255 })), @@ -376,9 +359,9 @@ export namespace ModeBase { * through a sequence of operations, on system time-outs or idle delays, or via interactions coming from a * fabric other than the one which last executed a ChangeToMode. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.3 + * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.2 */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }), + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }), /** * Indicates the desired startup mode for the server when it is supplied with power. @@ -394,7 +377,7 @@ export namespace ModeBase { * * If this attribute is not implemented, or is set to the null value, it shall have no effect. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.4 + * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.3 */ startUpMode: OptionalWritableAttribute(0x2, TlvNullable(TlvUInt8), { persistent: true }) }, diff --git a/packages/types/src/clusters/mode-select.ts b/packages/types/src/clusters/mode-select.ts index 41a3b54cdd..f82cf0b23b 100644 --- a/packages/types/src/clusters/mode-select.ts +++ b/packages/types/src/clusters/mode-select.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -149,9 +149,11 @@ export namespace ModeSelect { * If this attribute is not present or is set to null, it shall NOT have an effect, otherwise the * CurrentMode attribute shall depend on the OnOff attribute of the On/Off cluster * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. + * The value of this field shall match the Mode field of one of the entries in the SupportedModes + * + * attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.7 + * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.6 */ onMode: WritableAttribute(0x5, TlvNullable(TlvUInt8), { persistent: true, default: null }) } @@ -186,19 +188,18 @@ export namespace ModeSelect { * description Milk and the second instance can have the description Sugar. This allows the user to tell * the purpose of each of the instances. * - * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.2 + * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.1 */ description: FixedAttribute(0x0, TlvString.bound({ maxLength: 64 })), /** * This attribute, when not null, shall indicate a single standard namespace for any standard semantic tag - * value supported in this or any other cluster instance with the same value of this attribute. A - * - * null value indicates no standard namespace, and therefore, no standard semantic tags are provided in - * this cluster instance. Each standard namespace and corresponding values and value meanings shall be - * defined in another document. + * value supported in this or any other cluster instance with the same value of this attribute. A null + * value indicates no standard namespace, and therefore, no standard semantic tags are provided in this + * cluster instance. Each standard namespace and corresponding values and value meanings shall be defined + * in another document. * - * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.3 + * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.2 */ standardNamespace: FixedAttribute(0x1, TlvNullable(TlvUInt16), { default: null }), @@ -207,7 +208,7 @@ export namespace ModeSelect { * item in this list represents a unique mode as indicated by the Mode field of the ModeOptionStruct. Each * entry in this list shall have a unique value for the Mode field. * - * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.4 + * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.3 */ supportedModes: FixedAttribute(0x2, TlvArray(TlvModeOption, { maxLength: 255 }), { default: [] }), @@ -218,9 +219,9 @@ export namespace ModeSelect { * * attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.5 + * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.4 */ - currentMode: Attribute(0x3, TlvUInt8, { scene: true, persistent: true }), + currentMode: Attribute(0x3, TlvUInt8, { persistent: true }), /** * The StartUpMode attribute value indicates the desired startup mode for the server when it is supplied @@ -239,7 +240,7 @@ export namespace ModeSelect { * * If this attribute is not implemented, or is set to the null value, it shall have no effect. * - * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.6 + * @see {@link MatterSpecification.v13.Cluster} § 1.9.6.5 */ startUpMode: OptionalWritableAttribute(0x4, TlvNullable(TlvUInt8), { persistent: true }) }, @@ -273,7 +274,9 @@ export namespace ModeSelect { * wash cycle of a laundry machine. * * The server allows the client to set a mode on the server. A mode is one of a list of options that may be - * presented by a client for a user choice, or understood by the client, via the semantic tags on the mode. + * presented by a client for a user choice, or understood by the client, via the semantic tags on the + * + * mode. * * A semantic tag is either a standard tag within a standard category namespace, or a manufacturer specific tag, * within the namespace of the vendor ID of the manufacturer. If there is no semantic tag, the mode is anonymous, diff --git a/packages/types/src/clusters/network-commissioning.ts b/packages/types/src/clusters/network-commissioning.ts index cc76725ac0..d37c95718c 100644 --- a/packages/types/src/clusters/network-commissioning.ts +++ b/packages/types/src/clusters/network-commissioning.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -116,7 +116,7 @@ export namespace NetworkCommissioning { NetworkNotFound = 5, /** - * Cannot find AP: Mismatch on band/channels/regulatory domain / 2.4GHz vs 5GHz + * Cannot find AP: Mismatch on band/channels/regulatory domain/ 2.4GHz vs 5GHz */ RegulatoryError = 6, @@ -387,7 +387,7 @@ export namespace NetworkCommissioning { networkId: TlvField(0, TlvByteString.bound({ minLength: 1, maxLength: 32 })), /** - * See Section 11.9.7.1.2, “Breadcrumb Field” for usage. + * See Breadcrumb for usage. * * @see {@link MatterSpecification.v13.Core} § 11.9.7.6.2 */ @@ -423,8 +423,7 @@ export namespace NetworkCommissioning { * * • OutOfRange: Network identifier was invalid (e.g. empty, too long, etc). * - * • BoundsExceeded: Adding this network configuration would exceed the limit defined by Section 11.9.6.1, - * “MaxNetworks Attribute”. + * • BoundsExceeded: Adding this network configuration would exceed the limit defined by MaxNetworks. * * • NetworkIdNotFound: The network identifier was expected to be found, but was not found among the added * network configurations in Networks attribute. @@ -436,7 +435,7 @@ export namespace NetworkCommissioning { networkingStatus: TlvField(0, TlvEnum()), /** - * See Section 11.9.7.2.2, “DebugText Field” for usage. + * See DebugText for usage. * * @see {@link MatterSpecification.v13.Core} § 11.9.7.7.2 */ @@ -482,7 +481,7 @@ export namespace NetworkCommissioning { networkId: TlvField(0, TlvByteString.bound({ minLength: 1, maxLength: 32 })), /** - * See Section 11.9.7.1.2, “Breadcrumb Field” for usage. + * See Breadcrumb for usage. * * @see {@link MatterSpecification.v13.Core} § 11.9.7.8.2 */ @@ -528,15 +527,15 @@ export namespace NetworkCommissioning { * * • UnknownError: An internal error occurred during the operation. * - * • Association errors (see also description of errors in Section 11.9.5.4, “NetworkCommissioningStatusEnum - * Type”): AuthFailure, UnsupportedSecurity, OtherConnectionFailure, IPV6Failed, IPBindFailed + * • Association errors (see also description of errors in NetworkCommissioningStatusEnum): AuthFailure, + * UnsupportedSecurity, OtherConnectionFailure, IPV6Failed, IPBindFailed * * @see {@link MatterSpecification.v13.Core} § 11.9.7.9.1 */ networkingStatus: TlvField(0, TlvEnum()), /** - * See Section 11.9.7.2.2, “DebugText Field” for usage. + * See DebugText for usage. * * @see {@link MatterSpecification.v13.Core} § 11.9.7.9.2 */ @@ -604,7 +603,7 @@ export namespace NetworkCommissioning { networkIndex: TlvField(1, TlvUInt8), /** - * See Section 11.9.7.1.2, “Breadcrumb Field” for usage. + * See Breadcrumb for usage. * * Effect when received * @@ -632,7 +631,7 @@ export namespace NetworkCommissioning { * * On receiving ReorderNetwork with: * - * • NetworkId = Home-Guest + * • NetworkID = Home-Guest * * • NetworkIndex = 0 * @@ -643,7 +642,7 @@ export namespace NetworkCommissioning { * * On receiving ReorderNetwork with: * - * • NetworkId = FancyCat + * • NetworkID = FancyCat * * • NetworkIndex = 3 * @@ -718,7 +717,7 @@ export namespace NetworkCommissioning { credentials: TlvField(1, TlvByteString.bound({ maxLength: 64 })), /** - * See Section 11.9.7.1.2, “Breadcrumb Field” for usage. + * See Breadcrumb for usage. * * @see {@link MatterSpecification.v13.Core} § 11.9.7.3.3 */ @@ -787,7 +786,7 @@ export namespace NetworkCommissioning { operationalDataset: TlvField(0, TlvByteString.bound({ maxLength: 254 })), /** - * See Section 11.9.7.1.2, “Breadcrumb Field” for usage. + * See Breadcrumb for usage. * * @see {@link MatterSpecification.v13.Core} § 11.9.7.4.2 */ @@ -862,7 +861,7 @@ export namespace NetworkCommissioning { * Indicates the maximum duration taken, in seconds, by the network interface on this cluster server * instance to provide scan results. * - * See Section 11.9.7.1, “ScanNetworks Command” for usage. + * See ScanNetworks for usage. * * @see {@link MatterSpecification.v13.Core} § 11.9.6.3 */ @@ -871,8 +870,10 @@ export namespace NetworkCommissioning { /** * Indicates the maximum duration taken, in seconds, by the network interface on this cluster server * instance to report a successful or failed network connection indication. This maximum time shall account - * for all operations needed until a successful network connection is deemed to have occurred, including, - * for example, obtaining IP addresses, or the execution of necessary internal retries. + * for all operations needed until a successful network connection is + * + * deemed to have occurred, including, for example, obtaining IP addresses, or the execution of necessary + * internal retries. * * @see {@link MatterSpecification.v13.Core} § 11.9.6.4 */ @@ -896,8 +897,8 @@ export namespace NetworkCommissioning { * SSID) is provided in the command arguments. Directed scanning shall restrict the result set to the * specified network only. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command + * shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * The client shall NOT expect the server to be done scanning and have responded with ScanNetworksResponse * before ScanMaxTimeSeconds seconds have elapsed. Enough transport time affordances for retries SHOULD be @@ -914,7 +915,6 @@ export namespace NetworkCommissioning { * determine reachability capabilities as seen by the server’s own radios. * * For Wi-Fi-supporting servers the server shall always scan on all bands supported by the interface - * * associated with the cluster instance on which the command was invoked. * * If the command was invoked over the same link whose configuration is managed by a given server cluster @@ -938,8 +938,8 @@ export namespace NetworkCommissioning { * * attribute shall remain unchanged, except for the removal of the requested network configuration. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command + * shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If the Networks attribute does not contain a matching entry, the command shall immediately respond with * NetworkConfigResponse having NetworkingStatus status field set to NetworkIdNotFound. @@ -966,8 +966,16 @@ export namespace NetworkCommissioning { * unable to proceed with such an operation, such as if it is currently attempting to connect in the * background, or is already proceeding with a prior ConnectNetwork. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command + * shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * + * Before connecting to the new network, the Node shall disconnect the operational network connections + * managed by any other Network Commissioning cluster instances (whether under the Root Node or a Secondary + * Network Interface), where those connections are not represented by an entry in the Networks attribute of + * the corresponding cluster instance. This ensures that an Administrator or Commissioner can reliably + * reconfigure the operational network connection of a device that has one or more Secondary Network + * interfaces, for example by removing the active network configuration from one cluster instance, followed + * by adding a new configuration and calling ConnectNetwork on a different cluster instance. * * Success or failure of this command shall be communicated by the ConnectNetworkResponse command, unless * some data model validations caused a FAILURE status to be sent prior to finishing execution of the @@ -992,11 +1000,12 @@ export namespace NetworkCommissioning { * attribute. * * Even after successfully connecting to a network, the configuration shall revert to the prior state of - * configuration if the CommissioningComplete command (see Section 11.10.6.6, “CommissioningComplete - * Command”) is not successfully invoked before expiry of the Fail-Safe timer. + * configuration if the CommissioningComplete command (see CommissioningComplete) is not successfully + * invoked before expiry of the Fail-Safe timer. * - * When non-concurrent commissioning is being used by a Commissioner or Administrator, the - * ConnectNetworkResponse shall be sent with the NetworkingStatus field set to Success prior to closing the + * When non-concurrent commissioning is being used by a Commissioner or Administrator, the Con + * + * nectNetworkResponse shall be sent with the NetworkingStatus field set to Success prior to closing the * commissioning channel, even if not yet connected to the operational network, unless the device would be * incapable of joining that network, in which case the usual failure path described in the prior * paragraphs shall be followed. Once the commissioning channel is closed, the operational channel will be @@ -1004,8 +1013,8 @@ export namespace NetworkCommissioning { * discovery of the Node on the new operational network. Therefore, before invoking the ConnectNetwork * command, the client SHOULD re-invoke the Arm Fail-Safe command with a duration that meets the following: * - * 1. Sufficient time to meet the minimum required time (see Section 11.9.6.4, “ConnectMaxTimeSeconds - * Attribute”) that may be taken by the server to connect to the desired network. + * 1. Sufficient time to meet the minimum required time (see ConnectMaxTimeSeconds) that may be taken by + * the server to connect to the desired network. * * 2. Sufficient time to account for possible message-layer retries when a response is requested. * @@ -1068,8 +1077,8 @@ export namespace NetworkCommissioning { /** * This command shall be used to add or modify Wi-Fi network configurations. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command + * shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * The Credentials associated with the network are not readable after execution of this command, as they do * not appear in the Networks attribute, for security reasons. @@ -1125,8 +1134,8 @@ export namespace NetworkCommissioning { /** * This command shall be used to add or modify Thread network configurations. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command + * shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * See Section 11.9.7.5, “Common processing of AddOrUpdateWiFiNetwork and AddOrUpdateThreadNetwork” for * behavior of addition/update. @@ -1227,7 +1236,7 @@ export namespace NetworkCommissioning { * It is undefined what happens if InterfaceEnabled is written to false on the same interface as that which * is used to write the value. In that case, it is possible that the Administrator would have to await * expiry of the fail-safe, and associated recovery of network configuration to prior safe values, before - * being able to communicate with the node again (see Section 11.10.6.2, “ArmFailSafe Command”). + * being able to communicate with the node again (see ArmFailSafe). * * It may be possible to disable Ethernet interfaces but it is implementation-defined. If not supported, a * write to this attribute with a value of false shall fail with a status of INVALID_ACTION. When disabled, @@ -1284,11 +1293,9 @@ export namespace NetworkCommissioning { /** * Indicates the ErrorValue used in the last failed attempt to connect to an operational network, using - * this interface, whether by invocation of the ConnectNetwork command or by - * - * autonomous connection after loss of connectivity or during initial establishment. If no such attempt was - * made, or no network configurations exist in the Networks attribute, then this attribute shall be set to - * null. + * this interface, whether by invocation of the ConnectNetwork command or by autonomous connection after + * loss of connectivity or during initial establishment. If no such attempt was made, or no network + * configurations exist in the Networks attribute, then this attribute shall be set to null. * * If the last connection succeeded, as indicated by a value of Success in the LastNetworkingStatus * attribute, then this field shall be set to null. diff --git a/packages/types/src/clusters/nitrogen-dioxide-concentration-measurement.ts b/packages/types/src/clusters/nitrogen-dioxide-concentration-measurement.ts index 69d3c7086e..1429c9fdd9 100644 --- a/packages/types/src/clusters/nitrogen-dioxide-concentration-measurement.ts +++ b/packages/types/src/clusters/nitrogen-dioxide-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/occupancy-sensing.ts b/packages/types/src/clusters/occupancy-sensing.ts index bc723698f2..dcb9658190 100644 --- a/packages/types/src/clusters/occupancy-sensing.ts +++ b/packages/types/src/clusters/occupancy-sensing.ts @@ -1,22 +1,95 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; -import { Attribute, OptionalWritableAttribute } from "../cluster/Cluster.js"; -import { BitFlag } from "../schema/BitmapSchema.js"; -import { TlvUInt8, TlvBitmap, TlvEnum, TlvUInt16 } from "../tlv/TlvNumber.js"; +import { + OptionalWritableAttribute, + Attribute, + FixedAttribute, + OptionalFixedAttribute, + OptionalEvent, + EventPriority +} from "../cluster/Cluster.js"; +import { TlvUInt16, TlvUInt8, TlvBitmap, TlvEnum } from "../tlv/TlvNumber.js"; import { AccessLevel } from "#model"; +import { BitFlag } from "../schema/BitmapSchema.js"; +import { TlvField, TlvObject } from "../tlv/TlvObject.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; export namespace OccupancySensing { /** - * @see {@link MatterSpecification.v13.Cluster} § 2.7.4.1 + * These are optional features supported by OccupancySensingCluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.4 + */ + export enum Feature { + /** + * Other (OTHER) + * + * Supports sensing using a modality not listed in the other bits + */ + Other = "Other", + + /** + * PassiveInfrared (PIR) + * + * Supports sensing using PIR (Passive InfraRed) + */ + PassiveInfrared = "PassiveInfrared", + + /** + * Ultrasonic (US) + * + * Supports sensing using UltraSound + */ + Ultrasonic = "Ultrasonic", + + /** + * PhysicalContact (PHY) + * + * Supports sensing using a physical contact + */ + PhysicalContact = "PhysicalContact", + + /** + * ActiveInfrared (AIR) + * + * Supports sensing using Active InfraRed measurement (e.g. time-of- flight or transflective/reflective IR + * sensing) + */ + ActiveInfrared = "ActiveInfrared", + + /** + * Radar (RAD) + * + * Supports sensing using radar waves (microwave) + */ + Radar = "Radar", + + /** + * RfSensing (RFS) + * + * Supports sensing based on RF signal analysis + */ + RfSensing = "RfSensing", + + /** + * Vision (VIS) + * + * Supports sensing based on analyzing images + */ + Vision = "Vision" + } + + /** + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.1 */ export const Occupancy = { /** @@ -25,13 +98,20 @@ export namespace OccupancySensing { * If this bit is set, it shall indicate the occupied state else if the bit if not set, it shall indicate the * unoccupied state. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.4.1.1 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.1.1 */ occupied: BitFlag(0) }; /** - * @see {@link MatterSpecification.v13.Cluster} § 2.7.4.3 + * NOTE + * + * This enum is as defined in ClusterRevision 4 and its definition shall NOT be + * + * extended; the feature flags provide the sensor modality (or modalities) for later cluster revisions. See + * Backward Compatibility section. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.3 */ export enum OccupancySensorType { /** @@ -56,7 +136,12 @@ export namespace OccupancySensing { } /** - * @see {@link MatterSpecification.v13.Cluster} § 2.7.4.2 + * NOTE + * + * This enum is as defined in ClusterRevision 4 and its definition shall NOT be extended; the feature flags provide + * the sensor modality (or modalities) for later cluster revisions. See Backward Compatibility section. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.2 */ export const OccupancySensorTypeBitmap = { /** @@ -76,160 +161,436 @@ export namespace OccupancySensing { }; /** - * @see {@link Cluster} + * This structure provides information on the server’s supported values for the HoldTime attribute. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.4 */ - export const ClusterInstance = MutableCluster({ - id: 0x406, - name: "OccupancySensing", - revision: 4, + export const TlvHoldTimeLimits = TlvObject({ + /** + * This field shall specify the minimum value of the server’s supported value for the HoldTime attribute, in + * seconds. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.4.1 + */ + holdTimeMin: TlvField(0, TlvUInt16.bound({ min: 1 })), - attributes: { - /** - * This attribute indicates the sensed (processed) status of occupancy. - * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.1 - */ - occupancy: Attribute(0x0, TlvBitmap(TlvUInt8, Occupancy)), + /** + * This field shall specify the maximum value of the server’s supported value for the HoldTime attribute, in + * seconds. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.4.2 + */ + holdTimeMax: TlvField(1, TlvUInt16), - /** - * This attribute specifies the type of the occupancy sensor. - * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.2 - */ - occupancySensorType: Attribute(0x1, TlvEnum()), + /** + * This field shall specify the (manufacturer-determined) default value of the server’s HoldTime attribute, in + * seconds. This is the value that a client who wants to reset the settings to a valid default SHOULD use. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.4.3 + */ + holdTimeDefault: TlvField(2, TlvUInt16) + }); - /** - * This attribute specifies the types of the occupancy sensor. Each bit position, if set, indicates the - * corresponding sensing capability is implemented. - * - * The value of the OccupancySensorType shall be aligned to the value of the OccupancySensorTypeBitmap - * attribute as defined below. - * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.3 - */ - occupancySensorTypeBitmap: Attribute(0x2, TlvBitmap(TlvUInt8, OccupancySensorTypeBitmap)), + /** + * This structure provides information on the server’s supported values for the HoldTime attribute. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.4 + */ + export interface HoldTimeLimits extends TypeFromSchema {} + + /** + * Body of the OccupancySensing occupancyChanged event + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.7.1 + */ + export const TlvOccupancyChangedEvent = TlvObject({ + /** + * This field shall indicate the new value of the Occupancy attribute. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.7.1.1 + */ + occupancy: TlvField(0, TlvBitmap(TlvUInt8, Occupancy)) + }); + /** + * Body of the OccupancySensing occupancyChanged event + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.7.1 + */ + export interface OccupancyChangedEvent extends TypeFromSchema {} + + /** + * A OccupancySensingCluster supports these elements if it supports feature PassiveInfrared. + */ + export const PassiveInfraredComponent = MutableCluster.Component({ + attributes: { /** - * This attribute specifies the time delay, in seconds, before the PIR sensor changes to its unoccupied - * state after the last detection of movement in the sensed area. + * This attribute shall specify the time delay, in seconds, before the PIR sensor changes to its unoccupied + * state after the last detection of occupancy in the sensed area. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.4 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.6 */ pirOccupiedToUnoccupiedDelay: OptionalWritableAttribute( 0x10, TlvUInt16, - { default: 0, writeAcl: AccessLevel.Manage } + { persistent: true, default: 0, writeAcl: AccessLevel.Manage } ), /** - * This attribute specifies the time delay, in seconds, before the PIR sensor changes to its occupied state - * after the detection of movement in the sensed area. + * This attribute shall specify the time delay, in seconds, before the PIR sensor changes to its occupied + * state after the first detection of occupancy in the sensed area. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.5 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.7 */ pirUnoccupiedToOccupiedDelay: OptionalWritableAttribute( 0x11, TlvUInt16, - { default: 0, writeAcl: AccessLevel.Manage } + { persistent: true, default: 0, writeAcl: AccessLevel.Manage } ), /** - * This attribute specifies the number of movement detection events that must occur in the period + * This attribute shall specify the number of occupancy detection events that must occur in the period * PIRUnoccupiedToOccupiedDelay, before the PIR sensor changes to its occupied state. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.6 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.8 */ pirUnoccupiedToOccupiedThreshold: OptionalWritableAttribute( 0x12, TlvUInt8.bound({ min: 1, max: 254 }), - { default: 1, writeAcl: AccessLevel.Manage } - ), + { persistent: true, default: 1, writeAcl: AccessLevel.Manage } + ) + } + }); + /** + * A OccupancySensingCluster supports these elements if it supports feature Ultrasonic. + */ + export const UltrasonicComponent = MutableCluster.Component({ + attributes: { /** - * This attribute specifies the time delay, in seconds, before the Ultrasonic sensor changes to its - * unoccupied state after the last detection of movement in the sensed area. + * This attribute shall specify the time delay, in seconds, before the Ultrasonic sensor changes to its + * unoccupied state after the last detection of occupancy in the sensed area. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.7 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.9 */ ultrasonicOccupiedToUnoccupiedDelay: OptionalWritableAttribute( 0x20, TlvUInt16, - { default: 0, writeAcl: AccessLevel.Manage } + { persistent: true, default: 0, writeAcl: AccessLevel.Manage } ), /** - * This attribute specifies the time delay, in seconds, before the Ultrasonic sensor changes to its - * occupied state after the detection of movement in the sensed area. + * This attribute shall specify the time delay, in seconds, before the Ultrasonic sensor changes to its + * occupied state after the first detection of occupancy in the sensed area. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.8 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.10 */ ultrasonicUnoccupiedToOccupiedDelay: OptionalWritableAttribute( 0x21, TlvUInt16, - { default: 0, writeAcl: AccessLevel.Manage } + { persistent: true, default: 0, writeAcl: AccessLevel.Manage } ), /** - * This attribute specifies the number of movement detection events that must occur in the period + * This attribute shall specify the number of occupancy detection events that must occur in the period * UltrasonicUnoccupiedToOccupiedDelay, before the Ultrasonic sensor changes to its occupied state. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.9 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.11 */ ultrasonicUnoccupiedToOccupiedThreshold: OptionalWritableAttribute( 0x22, TlvUInt8.bound({ min: 1, max: 254 }), - { default: 1, writeAcl: AccessLevel.Manage } - ), + { persistent: true, default: 1, writeAcl: AccessLevel.Manage } + ) + } + }); + /** + * A OccupancySensingCluster supports these elements if it supports feature PhysicalContact. + */ + export const PhysicalContactComponent = MutableCluster.Component({ + attributes: { /** - * This attribute specifies the time delay, in seconds, before the physical contact occupancy sensor + * This attribute shall specify the time delay, in seconds, before the physical contact occupancy sensor * changes to its unoccupied state after detecting the unoccupied event. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.10 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.12 */ physicalContactOccupiedToUnoccupiedDelay: OptionalWritableAttribute( 0x30, TlvUInt16, - { default: 0, writeAcl: AccessLevel.Manage } + { persistent: true, default: 0, writeAcl: AccessLevel.Manage } ), /** - * This attribute specifies the time delay, in seconds, before the physical contact sensor changes to its - * occupied state after the detection of the occupied event. + * This attribute shall specify the time delay, in seconds, before the physical contact sensor changes to + * its occupied state after the first detection of the occupied event. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.11 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.13 */ physicalContactUnoccupiedToOccupiedDelay: OptionalWritableAttribute( 0x31, TlvUInt16, - { default: 0, writeAcl: AccessLevel.Manage } + { persistent: true, default: 0, writeAcl: AccessLevel.Manage } ), /** - * This attribute specifies the number of movement detection events that must occur in the period + * This attribute shall specify the number of occupancy detection events that must occur in the period * PhysicalContactUnoccupiedToOccupiedDelay, before the PhysicalContact sensor changes to its occupied * state. * - * @see {@link MatterSpecification.v13.Cluster} § 2.7.5.12 + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.14 */ physicalContactUnoccupiedToOccupiedThreshold: OptionalWritableAttribute( 0x32, TlvUInt8.bound({ min: 1, max: 254 }), - { default: 1, writeAcl: AccessLevel.Manage } + { persistent: true, default: 1, writeAcl: AccessLevel.Manage } ) } }); /** - * The server cluster provides an interface to occupancy sensing functionality, including configuration and - * provision of notifications of occupancy status. + * These elements and properties are present in all OccupancySensing clusters. + */ + export const Base = MutableCluster.Component({ + id: 0x406, + name: "OccupancySensing", + revision: 5, + + features: { + /** + * Other + * + * Supports sensing using a modality not listed in the other bits + */ + other: BitFlag(0), + + /** + * PassiveInfrared + * + * Supports sensing using PIR (Passive InfraRed) + */ + passiveInfrared: BitFlag(1), + + /** + * Ultrasonic + * + * Supports sensing using UltraSound + */ + ultrasonic: BitFlag(2), + + /** + * PhysicalContact + * + * Supports sensing using a physical contact + */ + physicalContact: BitFlag(3), + + /** + * ActiveInfrared + * + * Supports sensing using Active InfraRed measurement (e.g. time-of- flight or transflective/reflective IR + * sensing) + */ + activeInfrared: BitFlag(4), + + /** + * Radar + * + * Supports sensing using radar waves (microwave) + */ + radar: BitFlag(5), + + /** + * RfSensing + * + * Supports sensing based on RF signal analysis + */ + rfSensing: BitFlag(6), + + /** + * Vision + * + * Supports sensing based on analyzing images + */ + vision: BitFlag(7) + }, + + attributes: { + /** + * Indicates the sensed (processed) status of occupancy. For compatibility reasons this is expressed as a + * bitmap where the status is indicated in bit 0: a value of 1 means occupied, and 0 means unoccupied, with + * the other bits set to 0; this can be considered equivalent to a boolean. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.1 + */ + occupancy: Attribute(0x0, TlvBitmap(TlvUInt8, Occupancy)), + + /** + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6 + */ + occupancySensorType: FixedAttribute(0x1, TlvEnum()), + + /** + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6 + */ + occupancySensorTypeBitmap: FixedAttribute(0x2, TlvBitmap(TlvUInt8, OccupancySensorTypeBitmap)), + + /** + * This attribute shall specify the time delay, in seconds, before the sensor changes to its unoccupied + * state after the last detection of occupancy in the sensed area. This is equivalent to the legacy + * *OccupiedToUnoccupiedDelay attributes. + * + * The value of HoldTime shall be within the limits provided in the HoldTimeLimits attribute, i.e. + * HoldTimeMin <= HoldTime <= HoldTimeMax + * + * Low values of HoldTime SHOULD be avoided since they could lead to many reporting messages. A value 0 for + * HoldTime shall NOT be used. + * + * The figure below illustrates this with an example of how this attribute is used for a PIR sensor. It + * uses threshold detection to generate an "internal detection" signal, which needs post-processing to + * become usable for transmission (traffic shaping). The bit in the Occupancy attribute will be set to 1 + * when the internal detection signal goes high, and will stay at 1 for HoldTime after the (last) instance + * where the internal detection signal goes low. + * + * The top half of the figure shows the case of a single trigger: the bit in the Occupancy attribute will + * be 1 for the duration of the PIR signal exceeding the threshold plus HoldTime. The bottom half of the + * figure shows the case of multiple triggers: the second trigger starts before the HoldTime of the first + * trigger has expired; this results in a single period of the bit in the Occupancy attribute being 1. The + * bit in the Occupancy attribute will be set to 1 from the start of the first period where the PIR signal + * exceeds the threshold until HoldTime after the last moment where the PIR exceeded the threshold. + * + * Figure 13. Processing of PIR signal towards Occupancy attribute using HoldTime + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.3 + */ + holdTime: OptionalWritableAttribute(0x3, TlvUInt16, { persistent: true, writeAcl: AccessLevel.Manage }), + + /** + * Indicates the server’s limits, and default value, for the HoldTime attribute. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.6.4 + */ + holdTimeLimits: OptionalFixedAttribute(0x4, TlvHoldTimeLimits) + }, + + events: { + /** + * If this event is supported, it shall be generated when the Occupancy attribute changes. + * + * @see {@link MatterSpecification.v13.Cluster} § 2.7.7.1 + */ + occupancyChanged: OptionalEvent(0x0, EventPriority.Info, TlvOccupancyChangedEvent) + }, + + /** + * This metadata controls which OccupancySensingCluster elements matter.js activates for specific feature + * combinations. + */ + extensions: MutableCluster.Extensions( + { flags: { passiveInfrared: true }, component: PassiveInfraredComponent }, + { flags: { ultrasonic: true }, component: UltrasonicComponent }, + { flags: { physicalContact: true }, component: PhysicalContactComponent }, + + { + flags: { + other: false, + passiveInfrared: false, + ultrasonic: false, + physicalContact: false, + activeInfrared: false, + radar: false, + rfSensing: false, + vision: false + }, + + component: false + } + ) + }); + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster.ExtensibleOnly(Base); + + /** + * The server cluster provides an interface to occupancy sensing functionality based on one or more sensing + * modalities, including configuration and provision of notifications of occupancy status. + * + * Per the Matter specification you cannot use {@link OccupancySensingCluster} without enabling certain feature + * combinations. You must use the {@link with} factory method to obtain a working cluster. * * @see {@link MatterSpecification.v13.Cluster} § 2.7 */ export interface Cluster extends Identity {} export const Cluster: Cluster = ClusterInstance; - export const Complete = Cluster; + const PIR = { passiveInfrared: true }; + const US = { ultrasonic: true }; + const PHY = { physicalContact: true }; + + /** + * @see {@link Complete} + */ + export const CompleteInstance = MutableCluster({ + id: Base.id, + name: Base.name, + revision: Base.revision, + features: Base.features, + + attributes: { + ...Base.attributes, + pirOccupiedToUnoccupiedDelay: MutableCluster.AsConditional( + PassiveInfraredComponent.attributes.pirOccupiedToUnoccupiedDelay, + { optionalIf: [PIR] } + ), + pirUnoccupiedToOccupiedDelay: MutableCluster.AsConditional( + PassiveInfraredComponent.attributes.pirUnoccupiedToOccupiedDelay, + { optionalIf: [PIR] } + ), + pirUnoccupiedToOccupiedThreshold: MutableCluster.AsConditional( + PassiveInfraredComponent.attributes.pirUnoccupiedToOccupiedThreshold, + { optionalIf: [PIR] } + ), + ultrasonicOccupiedToUnoccupiedDelay: MutableCluster.AsConditional( + UltrasonicComponent.attributes.ultrasonicOccupiedToUnoccupiedDelay, + { optionalIf: [US] } + ), + ultrasonicUnoccupiedToOccupiedDelay: MutableCluster.AsConditional( + UltrasonicComponent.attributes.ultrasonicUnoccupiedToOccupiedDelay, + { optionalIf: [US] } + ), + ultrasonicUnoccupiedToOccupiedThreshold: MutableCluster.AsConditional( + UltrasonicComponent.attributes.ultrasonicUnoccupiedToOccupiedThreshold, + { optionalIf: [US] } + ), + physicalContactOccupiedToUnoccupiedDelay: MutableCluster.AsConditional( + PhysicalContactComponent.attributes.physicalContactOccupiedToUnoccupiedDelay, + { optionalIf: [PHY] } + ), + physicalContactUnoccupiedToOccupiedDelay: MutableCluster.AsConditional( + PhysicalContactComponent.attributes.physicalContactUnoccupiedToOccupiedDelay, + { optionalIf: [PHY] } + ), + physicalContactUnoccupiedToOccupiedThreshold: MutableCluster.AsConditional( + PhysicalContactComponent.attributes.physicalContactUnoccupiedToOccupiedThreshold, + { optionalIf: [PHY] } + ) + }, + + events: Base.events + }); + + /** + * This cluster supports all OccupancySensing features. It may support illegal feature combinations. + * + * If you use this cluster you must manually specify which features are active and ensure the set of active + * features is legal per the Matter specification. + */ + export interface Complete extends Identity {} + + export const Complete: Complete = CompleteInstance; } export type OccupancySensingCluster = OccupancySensing.Cluster; diff --git a/packages/types/src/clusters/on-off.ts b/packages/types/src/clusters/on-off.ts index 66cfc6a4df..e90c069aa0 100644 --- a/packages/types/src/clusters/on-off.ts +++ b/packages/types/src/clusters/on-off.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -71,10 +71,9 @@ export namespace OnOff { * * When this feature is supported, and any change of the "dead front" state leads to changes in attributes of * other clusters due to the "dead front" feature, these attribute changes shall NOT be skipped or omitted from - * the usual processing associated with attribute changes. For example, if an - * - * attribute changes from value 4 to null on "dead front" behavior due to an Off command being received, this - * change shall be processed for reporting and subscriptions. + * the usual processing associated with attribute changes. For example, if an attribute changes from value 4 to + * null on "dead front" behavior due to an Off command being received, this change shall be processed for + * reporting and subscriptions. * * @see {@link MatterSpecification.v13.Cluster} § 1.5.4.2 */ @@ -400,10 +399,9 @@ export namespace OnOff { * * When this feature is supported, and any change of the "dead front" state leads to changes in attributes * of other clusters due to the "dead front" feature, these attribute changes shall NOT be skipped or - * omitted from the usual processing associated with attribute changes. For example, if an - * - * attribute changes from value 4 to null on "dead front" behavior due to an Off command being received, - * this change shall be processed for reporting and subscriptions. + * omitted from the usual processing associated with attribute changes. For example, if an attribute + * changes from value 4 to null on "dead front" behavior due to an Off command being received, this change + * shall be processed for reporting and subscriptions. * * @see {@link MatterSpecification.v13.Cluster} § 1.5.4.2 */ diff --git a/packages/types/src/clusters/operational-credentials.ts b/packages/types/src/clusters/operational-credentials.ts index 95bbfd215f..1a1c2f46f3 100644 --- a/packages/types/src/clusters/operational-credentials.ts +++ b/packages/types/src/clusters/operational-credentials.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -86,6 +86,9 @@ export namespace OperationalCredentials { * The intent is to provide some measure of user transparency about which entities have Administer privileges * on the Node. * + * Clients shall consider the VendorID field value to be untrustworthy until the NOC chain associated with the + * fabric has passed the Vendor ID Validation Procedure against the associated RCAC. + * * @see {@link MatterSpecification.v13.Core} § 11.18.4.5.2 */ vendorId: TlvField(2, TlvVendorId), @@ -342,8 +345,8 @@ export namespace OperationalCredentials { * * ### Effect When Received * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command shall + * fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, then * this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. @@ -357,10 +360,9 @@ export namespace OperationalCredentials { * provides the root of trust certificate within the same Fail- Safe context as the rest of the new fabric’s * operational credentials, even if some other fabric already uses the exact same root of trust certificate. * - * If the NOC provided in the NOCValue encodes an Operational Identifier for a pair already present on the device, then the device shall process the error by responding with a - * StatusCode of FabricConflict as described in Section 11.18.6.7.2, “Handling Errors”. + * If the NOC provided in the NOCValue encodes an Operational Identifier for a pair + * already present on the device, then the device shall process the error by responding with a StatusCode of + * FabricConflict as described in Section 11.18.6.7.2, “Handling Errors”. * * If the device already has the CommissionedFabrics attribute equal to the SupportedFabrics attribute, then * the device’s operational credentials table is considered full and the device shall process the error by @@ -405,11 +407,14 @@ export namespace OperationalCredentials { * Administrator presented in CaseAdminSubject exist within the same entity that is currently invoking * the AddNOC command, within another of the Fabrics of which it is a member. * + * a. If the Managed Device Feature is implemented by the ACL cluster, then one or more ARL entries with + * the new FabricIndex may be added to the ARL attribute. + * * 8. The incoming IPKValue shall be stored in the Fabric-scoped slot within the Group Key Management cluster * (see KeySetWrite), for subsequent use during CASE. * - * 9. The Fabric Index associated with the armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”) shall be updated to match the Fabric Index just allocated. + * 9. The Fabric Index associated with the armed fail-safe context (see ArmFailSafe) shall be updated to + * match the Fabric Index just allocated. * * 10. If the current secure session was established with PASE, the receiver shall: * @@ -619,39 +624,40 @@ export namespace OperationalCredentials { * Effect on Receipt * * If the FabricIndex field does not match the FabricIndex of any entry within the Fabrics list, then an - * NOCResponse with a StatusCode of InvalidFabricIndex shall be returned for the command and there shall NOT be - * any permanent changes to any device data. + * NOCResponse with a StatusCode of InvalidFabricIndex shall be returned for the command and * - * Otherwise, one of the following outcomes shall occur: + * there shall NOT be any permanent changes to any device data. Otherwise, one of the following outcomes shall + * occur: * * 1. If the FabricIndex matches the last remaining entry in the Fabrics list, then the device shall delete - * all Matter related data on the node which was created since it was commissioned. This + * all Matter related data on the node which was created since it was commissioned. This includes all + * Fabric-Scoped data, including Access Control List, Access Restriction List, bindings, scenes, group + * keys, operational certificates, etc. All Trusted Roots shall also be removed. If a time synchronization + * cluster is present on the Node, the TrustedTimeSource and DefaultNtp shall be set to null. Any Matter + * related data including logs, secure sessions, exchanges and interaction model constructs shall also be + * removed. Since this operation involves the removal of the secure session data that may underpin the + * current set of exchanges, the Node invoking the command SHOULD NOT expect a response before terminating + * its secure session with the target. * - * includes all Fabric-Scoped data, including Access Control List, bindings, scenes, group keys, operational - * certificates, etc. All Trusted Roots shall also be removed. If a time synchronization cluster is present on - * the Node, the TrustedTimeSource and DefaultNtp shall be set to null. Any Matter related data including logs, - * secure sessions, exchanges and interaction model constructs shall also be removed. Since this operation - * involves the removal of the secure session data that may underpin the current set of exchanges, the Node - * invoking the command SHOULD NOT expect a response before terminating its secure session with the target. + * 2. If the FabricIndex does not equal the accessing fabric index, then the device shall begin the process + * of irrevocably deleting all associated Fabric-Scoped data, including Access Control Entries, Access + * Restriction Entries, bindings, group keys, operational certificates, etc. Any remaining Trusted Roots + * no longer referenced by any operational certificate shall also be removed. If a time synchronization + * cluster is present on the Node, and the TrustedTimeSource FabricIndex matches the given FabricIndex, + * the TrustedTimeSource shall be set to null. All secure sessions, exchanges and interaction model + * constructs related to the Operational Identity under the given Fabric shall also be removed. Following + * the removal, an NOCResponse with a StatusCode of OK shall be returned. * - * 2. If the FabricIndex does not equal the accessing fabric index, then the device shall begin the process of - * irrevocably deleting all associated Fabric-Scoped data, including Access Control List, bindings, group keys, - * operational certificates, etc. Any remaining Trusted Roots no longer referenced by any operational - * certificate shall also be removed. If a time synchronization cluster is present on the Node, and the - * TrustedTimeSource FabricIndex matches the given FabricIndex, the TrustedTimeSource shall be set to null. All - * secure sessions, exchanges and interaction model constructs related to the Operational Identity under the - * given Fabric shall also be removed. Following the removal, an NOCResponse with a StatusCode of OK shall be - * returned. - * - * 3. If the FabricIndex equals the accessing fabric index, then the device shall begin the process of - * irrevocably deleting all associated Fabric-Scoped data, including Access Control Entries, bindings, group - * keys, operational certificates, etc. Any remaining Trusted Roots no longer referenced by any operational - * certificate shall also be removed. If a time synchronization cluster is present on the Node, and the - * TrustedTimeSource FabricIndex matches the given FabricIndex, the TrustedTimeSource shall be set to null. All - * secure sessions, exchanges and interaction model constructs related to the Operational Identity under the - * given Fabric shall also be removed. Since this operation involves the removal of the secure session data - * that may underpin the current set of exchanges, the Node invoking the command SHOULD NOT expect a response - * before terminating its secure session with the target. + * 3. If the FabricIndex equals the accessing fabric index, then the device shall begin the process of + * irrevocably deleting all associated Fabric-Scoped data, including Access Control Entries, Access + * Restriction Entries, bindings, group keys, operational certificates, etc. Any remaining Trusted Roots + * no longer referenced by any operational certificate shall also be removed. If a time synchronization + * cluster is present on the Node, and the TrustedTimeSource FabricIndex matches the given FabricIndex, + * the TrustedTimeSource shall be set to null. All secure sessions, exchanges and interaction model + * constructs related to the Operational Identity under the given Fabric shall also be removed. Since this + * operation involves the removal of the secure session data that may underpin the current set of + * exchanges, the Node invoking the command SHOULD NOT expect a response before terminating its secure + * session with the target. * * @see {@link MatterSpecification.v13.Core} § 11.18.6.12.1 */ @@ -750,8 +756,8 @@ export namespace OperationalCredentials { commissionedFabrics: Attribute(0x3, TlvUInt8, { persistent: true }), /** - * This attribute shall contain a read-only list of Trusted Root CA Certificates installed on the Node, as - * octet strings containing their Matter Certificate Encoding representation. + * This attribute shall contain a read-only list of Trusted Root CA Certificates (RCAC) installed on the + * Node, as octet strings containing their Matter Certificate Encoding representation. * * These certificates are installed through the AddTrustedRootCertificate command. * @@ -831,8 +837,8 @@ export namespace OperationalCredentials { * shall be tagged as being for a subsequent UpdateNOC, otherwise the internal state of the CSR shall be * tagged as being for a subsequent AddNOC. See AddNOC and UpdateNOC for details about the processing. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command + * shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, then * this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. @@ -872,8 +878,8 @@ export namespace OperationalCredentials { * * Effect When Received * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command + * shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, then * this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. @@ -886,7 +892,6 @@ export namespace OperationalCredentials { * then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. * * If any of the following conditions arise, the Node shall process an error by responding with an - * * NOCResponse with a StatusCode of InvalidNOC as described in Section 11.18.6.7.2, “Handling Errors”: * * • The NOC provided in the NOCValue does not refer in its subject to the FabricID associated with the @@ -981,12 +986,14 @@ export namespace OperationalCredentials { * If the certificate from the RootCACertificate field is already installed, based on exact byte-for-byte * equality, then this command shall succeed with no change to the list. * - * If this command is received without an armed fail-safe context (see Section 11.10.6.2, “ArmFailSafe - * Command”), then this command shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. + * If this command is received without an armed fail-safe context (see ArmFailSafe), then this command + * shall fail with a FAILSAFE_REQUIRED status code sent back to the initiator. * * If a prior AddTrustedRootCertificate command was successfully invoked within the fail-safe timer period, - * which would cause the new invocation to add a second root certificate within a given fail- safe timer - * period, then this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. + * which would cause the new invocation to add a second root certificate within a given fail- + * + * safe timer period, then this command shall fail with a CONSTRAINT_ERROR status code sent back to the + * initiator. * * If a prior UpdateNOC or AddNOC command was successfully executed within the fail-safe timer period, then * this command shall fail with a CONSTRAINT_ERROR status code sent back to the initiator. diff --git a/packages/types/src/clusters/operational-state.ts b/packages/types/src/clusters/operational-state.ts index dedd6211dc..f729faa568 100644 --- a/packages/types/src/clusters/operational-state.ts +++ b/packages/types/src/clusters/operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ import { import { TlvArray } from "../tlv/TlvArray.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; -import { TlvUInt8, TlvUInt32 } from "../tlv/TlvNumber.js"; +import { TlvUInt8, TlvUInt32, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; @@ -26,6 +26,48 @@ import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; export namespace OperationalState { + /** + * This type defines the set of known operational state values, and is derived from enum8. The following table + * defines the applicable ranges for values that are defined within this type. All values that are undefined shall + * be treated as reserved. As shown by the table, states that may be specific to a certain Device Type or other + * modality shall be defined in a derived cluster of this cluster. + * + * The derived cluster-specific state definitions shall NOT duplicate any general state definitions. That is, a + * derived cluster specification of this cluster cannot define states with the same semantics as the general states + * defined below. + * + * A manufacturer-specific state definition shall NOT duplicate the general state definitions or derived cluster + * state definitions. That is, a manufacturer-defined state defined for this cluster or a derived cluster thereof + * cannot define a state with the same semantics as the general states defined below or states defined in a derived + * cluster. Such manufacturer-specific state definitions shall be scoped in the context of the Vendor ID present in + * the Basic Information cluster. + * + * The following table defines the generally applicable states. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.1 + */ + export enum OperationalStateEnum { + /** + * The device is stopped + */ + Stopped = 0, + + /** + * The device is operating + */ + Running = 1, + + /** + * The device is paused during an operation + */ + Paused = 2, + + /** + * The device is in an error state + */ + Error = 3 + } + /** * The OperationalStateStruct is used to indicate a possible state of the device. * @@ -37,7 +79,7 @@ export namespace OperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.2.1 */ - operationalStateId: TlvField(0, TlvUInt8), + operationalStateId: TlvField(0, TlvEnum()), /** * This field shall be present if the OperationalStateID is from the set reserved for Manufacturer Specific @@ -56,16 +98,60 @@ export namespace OperationalState { */ export interface OperationalStateStruct extends TypeFromSchema {} + /** + * This type defines the set of known operational error values, and is derived from enum8. The following table + * defines the applicable ranges for values that are defined within this type. All values that are undefined shall + * be treated as reserved. As shown by the table, errors that may be specific to a certain Device Type or other + * modality shall be defined in a derived cluster of this cluster. + * + * The derived cluster-specific error definitions shall NOT duplicate the general error definitions. + * + * That is, a derived cluster specification of this cluster cannot define errors with the same semantics as the + * general errors defined below. + * + * The manufacturer-specific error definitions shall NOT duplicate the general error definitions or derived + * cluster-specific error definitions. That is, a manufacturer-defined error defined for this cluster or a derived + * cluster thereof cannot define errors with the same semantics as the general errors defined below or errors + * defined in a derived cluster. Such manufacturer-specific error definitions shall be scoped in the context of the + * Vendor ID present in the Basic Information cluster. + * + * The set of ErrorStateID field values defined in each of the generic or derived Operational State cluster + * specifications is called ErrorState. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.3 + */ + export enum ErrorState { + /** + * The device is not in an error state + */ + NoError = 0, + + /** + * The device is unable to start or resume operation + */ + UnableToStartOrResume = 1, + + /** + * The device was unable to complete the current operation + */ + UnableToCompleteOperation = 2, + + /** + * The device cannot process the command in its current state + */ + CommandInvalidInState = 3 + } + /** * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.4 */ - export const TlvErrorState = TlvObject({ + export const TlvErrorStateStruct = TlvObject({ /** * This shall be populated with a value from the ErrorStateEnum. * * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.4.1 */ - errorStateId: TlvField(0, TlvUInt8), + errorStateId: TlvField(0, TlvEnum()), /** * This field shall be present if the ErrorStateID is from the set reserved for Manufacturer Specific Errors, @@ -90,7 +176,7 @@ export namespace OperationalState { /** * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.4 */ - export interface ErrorState extends TypeFromSchema {} + export interface ErrorStateStruct extends TypeFromSchema {} /** * This command shall be supported by an implementation if any of the other commands defined by this cluster are @@ -109,7 +195,7 @@ export namespace OperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.6.5.1 */ - commandResponseState: TlvField(0, TlvErrorState) + commandResponseState: TlvField(0, TlvErrorStateStruct) }); /** @@ -128,7 +214,7 @@ export namespace OperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.7.1 */ - export const TlvOperationalErrorEvent = TlvObject({ errorState: TlvField(0, TlvErrorState) }); + export const TlvOperationalErrorEvent = TlvObject({ errorState: TlvField(0, TlvErrorStateStruct) }); /** * Body of the OperationalState operationalError event @@ -153,9 +239,10 @@ export namespace OperationalState { /** * The total operational time, in seconds, from when the operation was started via an initial Start command or - * manual action, until the operation completed. This includes any time spent while paused. There may be cases - * whereby the total operational time exceeds the maximum value that can be conveyed by this attribute, in such - * instances, this attribute shall be populated with null. + * autonomous/manual starting action, until the operation completed. This includes any time + * + * spent while paused. There may be cases whereby the total operational time exceeds the maximum value that can + * be conveyed by this attribute, in such instances, this attribute shall be populated with null. * * @see {@link MatterSpecification.v13.Cluster} § 1.14.7.2.2 */ @@ -178,40 +265,13 @@ export namespace OperationalState { */ export interface OperationCompletionEvent extends TypeFromSchema {} - /** - * The following table defines the generally applicable ErrorState values. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.3.1 - */ - export enum GeneralErrorState { - /** - * The device is not in an error state - */ - NoError = 0, - - /** - * The device is unable to start or resume operation - */ - UnableToStartOrResume = 1, - - /** - * The device was unable to complete the current operation - */ - UnableToCompleteOperation = 2, - - /** - * The device cannot process the command in its current state - */ - CommandInvalidInState = 3 - } - /** * @see {@link Cluster} */ export const ClusterInstance = MutableCluster({ id: 0x60, name: "OperationalState", - revision: 2, + revision: 3, attributes: { /** @@ -229,9 +289,10 @@ export namespace OperationalState { /** * This attribute represents the current phase of operation being performed by the server. This shall be - * the positional index representing the value from the set provided in the PhaseList Attribute, where the - * first item in that list is an index of 0. Thus, this attribute shall have a maximum value that is - * "length(PhaseList) - 1". + * the positional index representing the value from the set provided in the PhaseList Attribute, + * + * where the first item in that list is an index of 0. Thus, this attribute shall have a maximum value that + * is "length(PhaseList) - 1". * * Null if the PhaseList attribute is null or if the PhaseList attribute is an empty list. * @@ -240,24 +301,37 @@ export namespace OperationalState { currentPhase: Attribute(0x1, TlvNullable(TlvUInt8)), /** - * Indicates the estimated time left before the operation is completed, in seconds. Changes to this value - * shall NOT be reported in a subscription (note the C Quality). A Client implementation may periodically - * poll this value to ensure alignment of any local rendering of the CountdownTime with the device provided - * value. + * Indicates the estimated time left before the operation is completed, in seconds. * - * A value of 0 means that the operation has completed. + * A value of 0 (zero) means that the operation has completed. * - * When this attribute is null, that represents that there is no time currently defined until operation - * completion. This may happen, for example, because no operation is in progress or because the completion - * time is unknown. + * A value of null represents that there is no time currently defined until operation completion. This may + * happen, for example, because no operation is in progress or because the completion time is unknown. + * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • If it has changed due to a change in the CurrentPhase or OperationalState attributes, or + * + * • When it changes from 0 to any other value and vice versa, or + * + * • When it changes from null to any other value and vice versa, or + * + * • When it increases, or + * + * • When there is any increase or decrease in the estimated time remaining that was due to progressing + * insight of the server’s control logic, or + * + * • When it changes at a rate significantly different from one unit per second. + * + * Changes to this attribute merely due to the normal passage of time with no other dynamic change of + * device state shall NOT be reported. + * + * As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the + * reporting of this attribute in order to keep track of the remaining duration. * * @see {@link MatterSpecification.v13.Cluster} § 1.14.5.3 */ - countdownTime: OptionalAttribute( - 0x2, - TlvNullable(TlvUInt32.bound({ max: 259200 })), - { omitChanges: true, default: null } - ), + countdownTime: OptionalAttribute(0x2, TlvNullable(TlvUInt32.bound({ max: 259200 })), { default: null }), /** * This attribute describes the set of possible operational states that the device exposes. An operational @@ -279,7 +353,7 @@ export namespace OperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.5.5 */ - operationalState: Attribute(0x4, TlvUInt8), + operationalState: Attribute(0x4, TlvEnum()), /** * This attribute shall specify the details of any current error condition being experienced on the device @@ -290,7 +364,7 @@ export namespace OperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.5.6 */ - operationalError: Attribute(0x5, TlvErrorState) + operationalError: Attribute(0x5, TlvErrorStateStruct) }, commands: { @@ -443,10 +517,14 @@ export namespace OperationalState { operationalError: Event(0x0, EventPriority.Critical, TlvOperationalErrorEvent), /** - * This event is generated when the overall operation ends, successfully or otherwise. For example, the - * completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a wash cycle in a + * This event SHOULD be generated when the overall operation ends, successfully or otherwise. For example, + * the completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a wash cycle in a * Washing Machine. * + * It is highly recommended that appliances device types employing the Operational State cluster support + * this event, even if it is optional. This assists clients in executing automations or issuing + * notifications at critical points in the device operation cycles. + * * This event shall contain the following fields: * * @see {@link MatterSpecification.v13.Cluster} § 1.14.7.2 diff --git a/packages/types/src/clusters/ota-software-update-provider.ts b/packages/types/src/clusters/ota-software-update-provider.ts index 92b9178eda..6ddec1ff11 100644 --- a/packages/types/src/clusters/ota-software-update-provider.ts +++ b/packages/types/src/clusters/ota-software-update-provider.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,9 +20,8 @@ import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; export namespace OtaSoftwareUpdateProvider { /** - * Note that only HTTP over TLS (HTTPS) is supported (see RFC 7230). Using HTTP without TLS shall - * - * NOT be supported, as there is no way to authenticate the involved participants. + * Note that only HTTP over TLS (HTTPS) is supported (see RFC 7230). Using HTTP without TLS shall NOT be supported, + * as there is no way to authenticate the involved participants. * * @see {@link MatterSpecification.v13.Core} § 11.20.6.4.3 */ @@ -107,9 +106,10 @@ export namespace OtaSoftwareUpdateProvider { hardwareVersion: TlvOptionalField(4, TlvUInt16), /** - * The location, if present, shall provide the same value as the Basic Information Cluster Location attribute - * for the OTA Requestor as configured. This may be used by the OTA Provider logic to allow per-region - * selection of the Software Image. + * The location, if present, shall provide the same value as the Basic Information Cluster Location + * + * attribute for the OTA Requestor as configured. This may be used by the OTA Provider logic to allow + * per-region selection of the Software Image. * * @see {@link MatterSpecification.v13.Core} § 11.20.6.5.1.6 */ @@ -244,27 +244,27 @@ export namespace OtaSoftwareUpdateProvider { * * a. The Operational Node ID in the host field shall match the NodeID of the OTA Provider responding with * the QueryImageResponse. The usage of a different Node ID than that of the provider is reserved for - * future use. This constraint reduces the number of independent - * - * CASE secure channel sessions that have to be maintained to proceed with OTA software updates, thus reducing - * energy and resource utilization for the software update process. + * future use. This constraint reduces the number of independent CASE secure channel sessions that have + * to be maintained to proceed with OTA software updates, thus reducing energy and resource utilization + * for the software update process. * - * 4. The user section of the authority field shall be absent, as there are no "users" to be considered. + * 4. The user section of the authority field shall be absent, as there are no "users" to be considered. * - * 5. The port section of the authority field shall be absent, as the port for transport shall be determined - * through Operational Discovery of the target Node. + * 5. The port section of the authority field shall be absent, as the port for transport shall be determined + * through Operational Discovery of the target Node. * - * 6. The URI shall not contain a query field. + * 6. The URI shall NOT contain a query field. * - * 7. The URI shall not contain a fragment field. + * 7. The URI shall NOT contain a fragment field. * - * 8. The path field shall employ absolute path representation and shall contain the file designator of the - * software image to download at the BDX server. When used with the BDX server, the leading / separating the - * URI authority from the path shall be omitted. When contacting the BDX server, further processing of the file - * designator shall NOT be done, including handling of URL-encoded escape sequences. Rather, the exact octets - * of the path, as received shall be the values used by both client and server in handling the file designator. + * 8. The path field shall employ absolute path representation and shall contain the file designator of the + * software image to download at the BDX server. When used with the BDX server, the leading / separating + * the URI authority from the path shall be omitted. When contacting the BDX server, further processing of + * the file designator shall NOT be done, including handling of URL-encoded escape sequences. Rather, the + * exact octets of the path, as received shall be the values used by both client and server in handling + * the file designator. * - * a. The path shall only contain valid URI characters. + * a. The path shall only contain valid URI characters. * * These rules above for BDX URIs simplify parsing for OTA Requestors receiving Image URIs. The following * example procedure shows how the format constraints simplify the extraction of the necessary data to reach @@ -450,7 +450,7 @@ export namespace OtaSoftwareUpdateProvider { /** * See Section 11.20.3.6, “Applying a software update” for the semantics of the values. This enumeration is used in - * the Action field of the ApplyUpdateResponse command. See (Section 11.20.6.5.4.1, “Action Field”). + * the Action field of the ApplyUpdateResponse command. See (Action). * * @see {@link MatterSpecification.v13.Core} § 11.20.6.4.2 */ @@ -533,7 +533,7 @@ export namespace OtaSoftwareUpdateProvider { * may never come back (e.g. device removed from Fabric altogether, or a critical malfunction), an OTA Provider * shall NOT expect every OTA Requestor to invoke this command for correct operation of the OTA Provider. * - * This command shall be considered optional and shall not result in reduced availability of the OTA Provider + * This command shall be considered optional and shall NOT result in reduced availability of the OTA Provider * functionality if OTA Requestors never invoke this command. * * Effect on Receipt diff --git a/packages/types/src/clusters/ota-software-update-requestor.ts b/packages/types/src/clusters/ota-software-update-requestor.ts index 09c7580c65..592d3f8a52 100644 --- a/packages/types/src/clusters/ota-software-update-requestor.ts +++ b/packages/types/src/clusters/ota-software-update-requestor.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -46,11 +46,9 @@ export namespace OtaSoftwareUpdateRequestor { providerNodeId: TlvField(1, TlvNodeId), /** - * This field shall contain the endpoint number which has the OTA Provider device type and OTA - * - * Software Update Provider cluster server on the ProviderNodeID. This is provided to avoid having to do - * discovery of the location of that endpoint by walking over all endpoints and checking their Descriptor - * Cluster. + * This field shall contain the endpoint number which has the OTA Provider device type and OTA Software Update + * Provider cluster server on the ProviderNodeID. This is provided to avoid having to do discovery of the + * location of that endpoint by walking over all endpoints and checking their Descriptor Cluster. * * @see {@link MatterSpecification.v13.Core} § 11.20.7.4.4.2 */ @@ -496,7 +494,7 @@ export namespace OtaSoftwareUpdateRequestor { defaultOtaProviders: WritableFabricScopedAttribute( 0x0, TlvArray(TlvProviderLocation), - { default: [], writeAcl: AccessLevel.Administer } + { persistent: true, default: [], writeAcl: AccessLevel.Administer } ), /** diff --git a/packages/types/src/clusters/oven-cavity-operational-state.ts b/packages/types/src/clusters/oven-cavity-operational-state.ts index ec98c1823a..429382226f 100644 --- a/packages/types/src/clusters/oven-cavity-operational-state.ts +++ b/packages/types/src/clusters/oven-cavity-operational-state.ts @@ -1,27 +1,18 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; -import { - Attribute, - OptionalAttribute, - OptionalCommand, - TlvNoResponse, - Event, - EventPriority, - OptionalEvent -} from "../cluster/Cluster.js"; +import { Attribute, OptionalAttribute, Event, EventPriority, OptionalEvent } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; -import { TlvUInt8, TlvUInt32 } from "../tlv/TlvNumber.js"; +import { TlvUInt8, TlvUInt32, TlvEnum } from "../tlv/TlvNumber.js"; import { OperationalState } from "./operational-state.js"; -import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -32,7 +23,7 @@ export namespace OvenCavityOperationalState { export const ClusterInstance = MutableCluster({ id: 0x48, name: "OvenCavityOperationalState", - revision: 1, + revision: 2, attributes: { /** @@ -50,9 +41,10 @@ export namespace OvenCavityOperationalState { /** * This attribute represents the current phase of operation being performed by the server. This shall be - * the positional index representing the value from the set provided in the PhaseList Attribute, where the - * first item in that list is an index of 0. Thus, this attribute shall have a maximum value that is - * "length(PhaseList) - 1". + * the positional index representing the value from the set provided in the PhaseList Attribute, + * + * where the first item in that list is an index of 0. Thus, this attribute shall have a maximum value that + * is "length(PhaseList) - 1". * * Null if the PhaseList attribute is null or if the PhaseList attribute is an empty list. * @@ -61,24 +53,37 @@ export namespace OvenCavityOperationalState { currentPhase: Attribute(0x1, TlvNullable(TlvUInt8)), /** - * Indicates the estimated time left before the operation is completed, in seconds. Changes to this value - * shall NOT be reported in a subscription (note the C Quality). A Client implementation may periodically - * poll this value to ensure alignment of any local rendering of the CountdownTime with the device provided - * value. + * Indicates the estimated time left before the operation is completed, in seconds. + * + * A value of 0 (zero) means that the operation has completed. + * + * A value of null represents that there is no time currently defined until operation completion. This may + * happen, for example, because no operation is in progress or because the completion time is unknown. + * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • If it has changed due to a change in the CurrentPhase or OperationalState attributes, or + * + * • When it changes from 0 to any other value and vice versa, or + * + * • When it changes from null to any other value and vice versa, or + * + * • When it increases, or + * + * • When there is any increase or decrease in the estimated time remaining that was due to progressing + * insight of the server’s control logic, or * - * A value of 0 means that the operation has completed. + * • When it changes at a rate significantly different from one unit per second. * - * When this attribute is null, that represents that there is no time currently defined until operation - * completion. This may happen, for example, because no operation is in progress or because the completion - * time is unknown. + * Changes to this attribute merely due to the normal passage of time with no other dynamic change of + * device state shall NOT be reported. + * + * As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the + * reporting of this attribute in order to keep track of the remaining duration. * * @see {@link MatterSpecification.v13.Cluster} § 1.14.5.3 */ - countdownTime: OptionalAttribute( - 0x2, - TlvNullable(TlvUInt32.bound({ max: 259200 })), - { omitChanges: true, default: null } - ), + countdownTime: OptionalAttribute(0x2, TlvNullable(TlvUInt32.bound({ max: 259200 })), { default: null }), /** * This attribute describes the set of possible operational states that the device exposes. An operational @@ -100,7 +105,7 @@ export namespace OvenCavityOperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.5.5 */ - operationalState: Attribute(0x4, TlvUInt8), + operationalState: Attribute(0x4, TlvEnum()), /** * This attribute shall specify the details of any current error condition being experienced on the device @@ -111,145 +116,7 @@ export namespace OvenCavityOperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.5.6 */ - operationalError: Attribute(0x5, OperationalState.TlvErrorState) - }, - - commands: { - /** - * This command shall be supported if the device supports remotely pausing the operation. If this command - * is supported, the Resume command shall also be supported. - * - * On receipt of this command, the device shall pause its operation if it is possible based on the current - * function of the server. For example, if it is at a point where it is safe to do so and/or permitted, but - * can be restarted from the point at which pause occurred. - * - * If this command is received when already in the Paused state the device shall respond with an - * OperationalCommandResponse command with an ErrorStateID of NoError but take no further action. - * - * A device that receives this command in any state which is not Pause-compatible shall respond - * - * with an OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState and shall take - * no further action. - * - * States are defined as Pause-compatible as follows: - * - * • For states defined in this cluster specification, in Table 3, “Pause Compatibility”. - * - * • For states defined by derived cluster specifications, in the corresponding specifications. - * - * • For manufacturer-specific states, by the manufacturer. - * - * A device that is unable to honor the Pause command for whatever reason shall respond with an - * OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState but take no further - * action. - * - * Otherwise, on success: - * - * • The OperationalState attribute shall be set to Paused. - * - * • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of NoError. - * - * The following table defines the compatibility of this cluster’s states with the Pause command. - * - * ### Table 3. Pause Compatibility - * - * @see {@link MatterSpecification.v13.Cluster} § 1.14.6.1 - */ - pause: OptionalCommand(0x0, TlvNoArguments, 0x0, TlvNoResponse), - - /** - * This command shall be supported if the device supports remotely stopping the operation. - * - * On receipt of this command, the device shall stop its operation if it is at a position where it is safe - * to do so and/or permitted. Restart of the device following the receipt of the Stop command shall require - * attended operation unless remote start is allowed by the device type and any jurisdiction governing - * remote operation of the device. - * - * If this command is received when already in the Stopped state the device shall respond with an - * OperationalCommandResponse command with an ErrorStateID of NoError but take no further action. - * - * A device that is unable to honor the Stop command for whatever reason shall respond with an - * OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState but take no further - * action. - * - * Otherwise, on success: - * - * • The OperationalState attribute shall be set to Stopped. - * - * • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of NoError. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.14.6.2 - */ - stop: OptionalCommand(0x1, TlvNoArguments, 0x1, TlvNoResponse), - - /** - * This command shall be supported if the device supports remotely starting the operation. If this command - * is supported, the 'Stop command shall also be supported. - * - * On receipt of this command, the device shall start its operation if it is safe to do so and the device - * is in an operational state from which it can be started. There may be either regulatory or - * manufacturer-imposed safety and security requirements that first necessitate some specific action at the - * device before a Start command can be honored. In such instances, a device shall respond with a status - * code of CommandInvalidInState if a Start command is received prior to the required on- device action. - * - * If this command is received when already in the Running state the device shall respond with an - * OperationalCommandResponse command with an ErrorStateID of NoError but take no further action. - * - * A device that is unable to honor the Start command for whatever reason shall respond with an - * OperationalCommandResponse command with an ErrorStateID of UnableToStartOrResume but take no further - * action. - * - * Otherwise, on success: - * - * • The OperationalState attribute shall be set to Running. - * - * • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of NoError. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.14.6.3 - */ - start: OptionalCommand(0x2, TlvNoArguments, 0x2, TlvNoResponse), - - /** - * This command shall be supported if the device supports remotely resuming the operation. If this command - * is supported, the Pause command shall also be supported. - * - * On receipt of this command, the device shall resume its operation from the point it was at when it - * received the Pause command, or from the point when it was paused by means outside of this cluster (for - * example by manual button press). - * - * If this command is received when already in the Running state the device shall respond with an - * OperationalCommandResponse command with an ErrorStateID of NoError but take no further action. - * - * A device that receives this command in any state which is not Resume-compatible shall respond with an - * OperationalCommandResponse command with an ErrorStateID of CommandInvalidInState and shall take no - * further action. - * - * States are defined as Resume-compatible as follows: - * - * • For states defined in this cluster specification, in Table 4, “Resume Compatibility”. - * - * • For states defined by derived cluster specifications, in the corresponding specifications. - * - * • For manufacturer-specific states, by the manufacturer. - * - * The following table defines the compatibility of this cluster’s states with the Resume command. - * - * ### Table 4. Resume Compatibility - * - * A device that is unable to honor the Resume command for any other reason shall respond with an - * OperationalCommandResponse command with an ErrorStateID of UnableToStartOrResume but take no further - * action. - * - * Otherwise, on success: - * - * • The OperationalState attribute shall be set to the most recent non-Error operational state prior to - * entering the Paused state. - * - * • The device shall respond with an OperationalCommandResponse command with an ErrorStateID of NoError. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.14.6.4 - */ - resume: OptionalCommand(0x3, TlvNoArguments, 0x3, TlvNoResponse) + operationalError: Attribute(0x5, OperationalState.TlvErrorStateStruct) }, events: { @@ -264,10 +131,14 @@ export namespace OvenCavityOperationalState { operationalError: Event(0x0, EventPriority.Critical, OperationalState.TlvOperationalErrorEvent), /** - * This event is generated when the overall operation ends, successfully or otherwise. For example, the - * completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a wash cycle in a + * This event SHOULD be generated when the overall operation ends, successfully or otherwise. For example, + * the completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a wash cycle in a * Washing Machine. * + * It is highly recommended that appliances device types employing the Operational State cluster support + * this event, even if it is optional. This assists clients in executing automations or issuing + * notifications at critical points in the device operation cycles. + * * This event shall contain the following fields: * * @see {@link MatterSpecification.v13.Cluster} § 1.14.7.2 @@ -277,7 +148,8 @@ export namespace OvenCavityOperationalState { }); /** - * This cluster provides an interface for monitoring the operational state of an oven. + * This cluster is derived from the Operational State cluster and provides an interface for monitoring the + * operational state of an oven. * * @see {@link MatterSpecification.v13.Cluster} § 8.10 */ diff --git a/packages/types/src/clusters/oven-mode.ts b/packages/types/src/clusters/oven-mode.ts index 33a5429032..dd2f8bf938 100644 --- a/packages/types/src/clusters/oven-mode.ts +++ b/packages/types/src/clusters/oven-mode.ts @@ -1,29 +1,21 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; -import { - WritableAttribute, - FixedAttribute, - Attribute, - OptionalWritableAttribute, - Command, - TlvNoResponse -} from "../cluster/Cluster.js"; -import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; -import { TlvNullable } from "../tlv/TlvNullable.js"; import { BitFlag } from "../schema/BitmapSchema.js"; +import { FixedAttribute, Attribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; +import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -31,156 +23,133 @@ export namespace OvenMode { /** * These are optional features supported by OvenModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } export enum ModeTag { /** - * This mode sets the device into baking mode for baking food items. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Bake = 16384, + Auto = 0, /** - * This mode sets the device into convection mode which creates an airflow within the device during the cooking - * duration. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1.2 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Convection = 16385, + Quick = 1, /** - * This mode sets the device into grill mode for grilling food items. This is the same as Broil for many - * regions. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1.3 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Grill = 16386, + Quiet = 2, /** - * This mode sets the device into roast mode for roasting food items. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1.4 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Roast = 16387, + LowNoise = 3, /** - * This mode sets the device into cleaning mode to clean the internal components of the appliance. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1.5 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Clean = 16388, + LowEnergy = 4, /** - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - ConvectionBake = 16389, + Vacation = 5, /** - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - ConvectionRoast = 16390, + Min = 6, /** - * This mode sets the device into a warming mode which begins warming the cavity. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Warming = 16391, + Max = 7, /** - * This mode sets the device into proofing mode which creates an environment ready for proofing. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1.9 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Proofing = 16392, + Night = 8, /** - * @see {@link MatterSpecification.v13.Cluster} § 8.11.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Steam = 16393, + Day = 9, /** - * The device decides which options, features and setting values to use. + * This mode sets the device into baking mode for baking food items. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1.1 */ - Auto = 0, + Bake = 16384, /** - * The mode of the device is optimizing for faster completion. + * This mode sets the device into convection mode which creates an airflow within the device during the cooking + * duration. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1.2 */ - Quick = 1, + Convection = 16385, /** - * The device is silent or barely audible while in this mode. + * This mode sets the device into grill mode for grilling food items. This is the same as Broil for many + * regions. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1.3 */ - Quiet = 2, + Grill = 16386, /** - * Either the mode is inherently low noise or the device optimizes for that. + * This mode sets the device into roast mode for roasting food items. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1.4 */ - LowNoise = 3, + Roast = 16387, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". + * This mode sets the device into cleaning mode to clean the internal components of the appliance. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1.5 */ - LowEnergy = 4, + Clean = 16388, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Vacation = 5, + ConvectionBake = 16389, /** - * The mode uses the lowest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Min = 6, + ConvectionRoast = 16390, /** - * The mode uses the highest available setting value. + * This mode sets the device into a warming mode which begins warming the cavity. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1.8 */ - Max = 7, + Warming = 16391, /** - * The mode is recommended or suitable for use during night time. + * This mode sets the device into proofing mode which creates an environment ready for proofing. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1.9 */ - Night = 8, + Proofing = 16392, /** - * The mode is recommended or suitable for use during day time. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.7.1 */ - Day = 9 + Steam = 16393 } /** @@ -210,7 +179,7 @@ export namespace OvenMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -221,9 +190,10 @@ export namespace OvenMode { export interface ModeTagStruct extends TypeFromSchema {} /** - * This is a struct representing a possible mode of the server. + * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. + * A blank field indicates no change. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.5.1 */ export const TlvModeOption = TlvObject({ /** @@ -282,94 +252,47 @@ export namespace OvenMode { }); /** - * This is a struct representing a possible mode of the server. + * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. + * A blank field indicates no change. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.5.1 */ export interface ModeOption extends TypeFromSchema {} - /** - * A OvenModeCluster supports these elements if it supports feature OnOff. - */ - export const OnOffComponent = MutableCluster.Component({ - attributes: { - /** - * Indicates whether the value of CurrentMode depends on the state of the On/Off cluster on the same - * endpoint. If this attribute is not present or is set to null, there is no dependency, otherwise the - * CurrentMode attribute shall depend on the OnOff attribute in the On/Off cluster - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.5 - */ - onMode: WritableAttribute(0x3, TlvNullable(TlvUInt8), { persistent: true, default: null }) - } - }); - /** * These elements and properties are present in all OvenMode clusters. */ export const Base = MutableCluster.Component({ id: 0x49, name: "OvenMode", - revision: 1, + revision: 2, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * This attribute shall contain the list of supported modes that may be selected for the CurrentMode - * attribute. Each item in this list represents a unique mode as indicated by the Mode field of the - * ModeOptionStruct. + * At least one entry in the SupportedModes attribute shall include the Bake mode tag in the ModeTags field + * list. * - * Each entry in this list shall have a unique value for the Mode field. Each entry in this list shall have - * a unique value for the Label field. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.2 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.6.1 */ - supportedModes: FixedAttribute(0x0, TlvArray(TlvModeOption, { minLength: 2, maxLength: 255 })), + supportedModes: FixedAttribute( + 0x0, + TlvArray(TlvModeOption, { minLength: 2, maxLength: 255 }), + { default: [] } + ), /** - * Indicates the current mode of the server. - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. - * - * The value of this attribute may change at any time via an out-of-band interaction outside of the server, - * such as interactions with a user interface, via internal mode changes due to autonomously progressing - * through a sequence of operations, on system time-outs or idle delays, or via interactions coming from a - * fabric other than the one which last executed a ChangeToMode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.3 + * @see {@link MatterSpecification.v13.Cluster} § 8.11.6 */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }), - - /** - * Indicates the desired startup mode for the server when it is supplied with power. - * - * If this attribute is not null, the CurrentMode attribute shall be set to the StartUpMode value, when the - * server is powered up, except in the case when the OnMode attribute overrides the StartUpMode attribute - * (see OnModeWithPowerUp). - * - * This behavior does not apply to reboots associated with OTA. After an OTA restart, the CurrentMode - * attribute shall return to its value prior to the restart. - * - * The value of this field shall match the Mode field of one of the entries in the SupportedModes attribute. - * - * If this attribute is not implemented, or is set to the null value, it shall have no effect. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.6.4 - */ - startUpMode: OptionalWritableAttribute(0x2, TlvNullable(TlvUInt8), { persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, commands: { @@ -386,7 +309,7 @@ export namespace OvenMode { /** * This metadata controls which OvenModeCluster elements matter.js activates for specific feature combinations. */ - extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: OnOffComponent }) + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -395,7 +318,7 @@ export namespace OvenMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced enumerated + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated * values for oven devices. * * OvenModeCluster supports optional features that you can enable with the OvenModeCluster.with() factory method. @@ -405,32 +328,7 @@ export namespace OvenMode { export interface Cluster extends Identity {} export const Cluster: Cluster = ClusterInstance; - const DEPONOFF = { onOff: true }; - - /** - * @see {@link Complete} - */ - export const CompleteInstance = MutableCluster({ - id: Cluster.id, - name: Cluster.name, - revision: Cluster.revision, - features: Cluster.features, - attributes: { - ...Cluster.attributes, - onMode: MutableCluster.AsConditional(OnOffComponent.attributes.onMode, { mandatoryIf: [DEPONOFF] }) - }, - commands: Cluster.commands - }); - - /** - * This cluster supports all OvenMode features. It may support illegal feature combinations. - * - * If you use this cluster you must manually specify which features are active and ensure the set of active - * features is legal per the Matter specification. - */ - export interface Complete extends Identity {} - - export const Complete: Complete = CompleteInstance; + export const Complete = Cluster; } export type OvenModeCluster = OvenMode.Cluster; diff --git a/packages/types/src/clusters/ozone-concentration-measurement.ts b/packages/types/src/clusters/ozone-concentration-measurement.ts index 58ddbd9daa..1eac8db44e 100644 --- a/packages/types/src/clusters/ozone-concentration-measurement.ts +++ b/packages/types/src/clusters/ozone-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/pm1-concentration-measurement.ts b/packages/types/src/clusters/pm1-concentration-measurement.ts index d383cdcfbe..aaea7795d2 100644 --- a/packages/types/src/clusters/pm1-concentration-measurement.ts +++ b/packages/types/src/clusters/pm1-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/pm10-concentration-measurement.ts b/packages/types/src/clusters/pm10-concentration-measurement.ts index 91f899e852..39a8170fa7 100644 --- a/packages/types/src/clusters/pm10-concentration-measurement.ts +++ b/packages/types/src/clusters/pm10-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/pm25-concentration-measurement.ts b/packages/types/src/clusters/pm25-concentration-measurement.ts index 1b5cb851b7..e073a87df1 100644 --- a/packages/types/src/clusters/pm25-concentration-measurement.ts +++ b/packages/types/src/clusters/pm25-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/power-source-configuration.ts b/packages/types/src/clusters/power-source-configuration.ts index acbb7f78bd..8bc2afa631 100644 --- a/packages/types/src/clusters/power-source-configuration.ts +++ b/packages/types/src/clusters/power-source-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/power-source.ts b/packages/types/src/clusters/power-source.ts index 586b874259..0f06c3d560 100644 --- a/packages/types/src/clusters/power-source.ts +++ b/packages/types/src/clusters/power-source.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -1053,21 +1053,33 @@ export namespace PowerSource { * value of 48 is equivalent to 24%. A value of NULL shall indicate the Node is currently unable to assess * the value. * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once every 10 seconds, or + * + * • When it changes from null to any other value and vice versa. + * + * Since reporting consumes power, devices SHOULD be careful not to over-report. + * * @see {@link MatterSpecification.v13.Core} § 11.7.7.13 */ - batPercentRemaining: OptionalAttribute( - 0xc, - TlvNullable(TlvUInt8.bound({ max: 200 })), - { omitChanges: true } - ), + batPercentRemaining: OptionalAttribute(0xc, TlvNullable(TlvUInt8.bound({ max: 200 }))), /** * Indicates the estimated time in seconds before the battery will no longer be able to provide power to * the Node. A value of NULL shall indicate the Node is currently unable to assess the value. * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once every 10 seconds, or + * + * • When it changes from null to any other value and vice versa. + * + * Since reporting consumes power, devices SHOULD be careful not to over-report. + * * @see {@link MatterSpecification.v13.Core} § 11.7.7.14 */ - batTimeRemaining: OptionalAttribute(0xd, TlvNullable(TlvUInt32), { omitChanges: true }), + batTimeRemaining: OptionalAttribute(0xd, TlvNullable(TlvUInt32)), /** * Indicates a coarse ranking of the charge level of the battery, used to indicate when intervention is @@ -1108,7 +1120,9 @@ export namespace PowerSource { * contributing to a fault have been cleared, the corresponding BatFaultEnum value shall be removed from * this list. An empty list shall indicate there are currently no active faults. The order of this list * SHOULD have no significance. Clients interested in monitoring changes in active faults may subscribe to - * this attribute, or they may subscribe to BatFaultChange. + * this attribute, or they may subscribe to Bat + * + * FaultChange. * * @see {@link MatterSpecification.v13.Core} § 11.7.7.19 */ @@ -1212,9 +1226,17 @@ export namespace PowerSource { * Indicates the estimated time in seconds before the battery source will be at full charge. A value of * NULL shall indicate the Node is currently unable to assess the value. * + * Changes to this attribute shall only be marked as reportable in the following cases: + * + * • At most once every 10 seconds, or + * + * • When it changes from null to any other value and vice versa. + * + * Since reporting consumes power, devices SHOULD be careful not to over-report. + * * @see {@link MatterSpecification.v13.Core} § 11.7.7.28 */ - batTimeToFullCharge: OptionalAttribute(0x1b, TlvNullable(TlvUInt32), { omitChanges: true }), + batTimeToFullCharge: OptionalAttribute(0x1b, TlvNullable(TlvUInt32)), /** * Indicates whether the Node can remain operational while the battery source is charging. @@ -1268,7 +1290,7 @@ export namespace PowerSource { export const Base = MutableCluster.Component({ id: 0x2f, name: "PowerSource", - revision: 2, + revision: 3, features: { /** @@ -1375,23 +1397,25 @@ export namespace PowerSource { { flags: { rechargeable: true }, component: ReplaceableOrRechargeableComponent }, { flags: { rechargeable: true }, component: RechargeableComponent }, { flags: { rechargeable: true, battery: false }, component: false }, - { flags: { replaceable: true, battery: false }, component: false } + { flags: { replaceable: true, battery: false }, component: false }, + { flags: { wired: true, battery: true }, component: false }, + { flags: { wired: false, battery: false }, component: false } ) }); /** * @see {@link Cluster} */ - export const ClusterInstance = MutableCluster(Base); + export const ClusterInstance = MutableCluster.ExtensibleOnly(Base); /** * This cluster is used to describe the configuration and capabilities of a physical power source that provides - * power to one or more endpoints on a node. In case the node has multiple power sources, each is described by its - * own cluster instance. Each instance of this cluster may be associated with one or more endpoints or the entire - * node. + * power to one or more endpoints on a node. In case the node has multiple power sources, each shall be described + * by its own cluster instance. Each instance of this cluster may be associated with one or more endpoints or the + * entire node. * - * PowerSourceCluster supports optional features that you can enable with the PowerSourceCluster.with() factory - * method. + * Per the Matter specification you cannot use {@link PowerSourceCluster} without enabling certain feature + * combinations. You must use the {@link with} factory method to obtain a working cluster. * * @see {@link MatterSpecification.v13.Core} § 11.7 */ @@ -1407,13 +1431,13 @@ export namespace PowerSource { * @see {@link Complete} */ export const CompleteInstance = MutableCluster({ - id: Cluster.id, - name: Cluster.name, - revision: Cluster.revision, - features: Cluster.features, + id: Base.id, + name: Base.name, + revision: Base.revision, + features: Base.features, attributes: { - ...Cluster.attributes, + ...Base.attributes, wiredAssessedInputVoltage: MutableCluster.AsConditional( WiredComponent.attributes.wiredAssessedInputVoltage, { optionalIf: [WIRED] } diff --git a/packages/types/src/clusters/power-topology.ts b/packages/types/src/clusters/power-topology.ts index 6c64d3f0b2..702bbca250 100644 --- a/packages/types/src/clusters/power-topology.ts +++ b/packages/types/src/clusters/power-topology.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/pressure-measurement.ts b/packages/types/src/clusters/pressure-measurement.ts index 8b8e845661..c0f33a863d 100644 --- a/packages/types/src/clusters/pressure-measurement.ts +++ b/packages/types/src/clusters/pressure-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -51,7 +51,7 @@ export namespace PressureMeasurement { * * @see {@link MatterSpecification.v13.Cluster} § 2.4.5.6 */ - minScaledValue: Attribute(0x11, TlvNullable(TlvInt16.bound({ min: -32767 })), { default: 0 }), + minScaledValue: Attribute(0x11, TlvNullable(TlvInt16.bound({ max: 32766 })), { default: 0 }), /** * Indicates the maximum value of ScaledValue that can be measured. The null value indicates that the value @@ -117,7 +117,7 @@ export namespace PressureMeasurement { * * @see {@link MatterSpecification.v13.Cluster} § 2.4.5.2 */ - minMeasuredValue: Attribute(0x1, TlvNullable(TlvInt16.bound({ min: -32767 }))), + minMeasuredValue: Attribute(0x1, TlvNullable(TlvInt16.bound({ max: 32766 }))), /** * Indicates the maximum value of MeasuredValue that can be measured. See Measured Value for more details. diff --git a/packages/types/src/clusters/proxy-configuration.ts b/packages/types/src/clusters/proxy-configuration.ts index 44c188dc82..b4d4261097 100644 --- a/packages/types/src/clusters/proxy-configuration.ts +++ b/packages/types/src/clusters/proxy-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/proxy-discovery.ts b/packages/types/src/clusters/proxy-discovery.ts index d617dd906b..022e03a407 100644 --- a/packages/types/src/clusters/proxy-discovery.ts +++ b/packages/types/src/clusters/proxy-discovery.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/pulse-width-modulation.ts b/packages/types/src/clusters/pulse-width-modulation.ts deleted file mode 100644 index 3f32e45f53..0000000000 --- a/packages/types/src/clusters/pulse-width-modulation.ts +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @license - * Copyright 2022-2024 Matter.js Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ - -import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; -import { LevelControl } from "./level-control.js"; -import { ClusterType } from "../cluster/ClusterType.js"; -import { Identity } from "#general"; -import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; - -export namespace PulseWidthModulation { - export const Base = { ...LevelControl.Base, id: 0x1c, name: "PulseWidthModulation" } as const; - - /** - * @see {@link Cluster} - */ - export const ClusterInstance = MutableCluster( - { ...Base, supportedFeatures: { onOff: true }, base: ClusterType(Base) }, - LevelControl.NotLightingComponent - ); - - /** - * This alias specializes the semantics of {@link LevelControl.Base}. - * - * PulseWidthModulationCluster supports optional features that you can enable with the - * PulseWidthModulationCluster.with() factory method. - */ - export interface Cluster extends Identity {} - - export const Cluster: Cluster = ClusterInstance; - - /** - * This cluster supports all PulseWidthModulation features. It may support illegal feature combinations. - * - * If you use this cluster you must manually specify which features are active and ensure the set of active - * features is legal per the Matter specification. - */ - export const CompleteInstance = MutableCluster({ - ...LevelControl.Complete, - id: 0x1c, - name: "PulseWidthModulation" - }); - - export interface Complete extends Identity {} - export const Complete: Complete = CompleteInstance; -} - -export type PulseWidthModulationCluster = PulseWidthModulation.Cluster; -export const PulseWidthModulationCluster = PulseWidthModulation.Cluster; -ClusterRegistry.register(PulseWidthModulation.Complete); diff --git a/packages/types/src/clusters/pump-configuration-and-control.ts b/packages/types/src/clusters/pump-configuration-and-control.ts index 404010b25f..6a9a2203d2 100644 --- a/packages/types/src/clusters/pump-configuration-and-control.ts +++ b/packages/types/src/clusters/pump-configuration-and-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -221,9 +221,10 @@ export namespace PumpConfigurationAndControl { /** * The pump will regulate its speed to maintain a constant differential pressure over its flanges. * - * The setpoint is interpreted as a percentage of the range derived of the [MinCompPressure – MaxCompPressure] - * attributes. The internal setpoint will be lowered (compensated) dependent on the flow in the pump (lower - * flow ⇒ lower internal setpoint). + * The setpoint is interpreted as a percentage of the range derived of the [MinCompPressure – Max + * + * CompPressure] attributes. The internal setpoint will be lowered (compensated) dependent on the flow in the + * pump (lower flow ⇒ lower internal setpoint). * * @see {@link MatterSpecification.v13.Cluster} § 4.2.6.3.3 */ @@ -339,8 +340,9 @@ export namespace PumpConfigurationAndControl { maxCompPressure: OptionalFixedAttribute(0x6, TlvNullable(TlvInt16), { default: null }), /** - * This attribute specifies the minimum speed the pump can achieve when it is working with the ControlMode - * attribute set to ConstantSpeed. + * This attribute specifies the minimum speed the pump can achieve when it is working with the Con + * + * trolMode attribute set to ConstantSpeed. * * Valid range is 0 to 65,534 RPM (steps of 1 RPM). Null if the value is invalid. * @@ -359,9 +361,8 @@ export namespace PumpConfigurationAndControl { maxConstSpeed: OptionalFixedAttribute(0x8, TlvNullable(TlvUInt16), { default: null }), /** - * This attribute specifies the minimum flow the pump can achieve when it is working with the Con - * - * trolMode attribute set to ConstantFlow. + * This attribute specifies the minimum flow the pump can achieve when it is working with the ControlMode + * attribute set to ConstantFlow. * * Valid range is 0 m/h to 6,553.4 m/h (steps of 0.1 m/h). Null if the value is invalid. * @@ -436,8 +437,9 @@ export namespace PumpConfigurationAndControl { export const ConstantSpeedComponent = MutableCluster.Component({ attributes: { /** - * This attribute specifies the minimum speed the pump can achieve when it is working with the ControlMode - * attribute set to ConstantSpeed. + * This attribute specifies the minimum speed the pump can achieve when it is working with the Con + * + * trolMode attribute set to ConstantSpeed. * * Valid range is 0 to 65,534 RPM (steps of 1 RPM). Null if the value is invalid. * @@ -463,9 +465,8 @@ export namespace PumpConfigurationAndControl { export const ConstantFlowComponent = MutableCluster.Component({ attributes: { /** - * This attribute specifies the minimum flow the pump can achieve when it is working with the Con - * - * trolMode attribute set to ConstantFlow. + * This attribute specifies the minimum flow the pump can achieve when it is working with the ControlMode + * attribute set to ConstantFlow. * * Valid range is 0 m/h to 6,553.4 m/h (steps of 0.1 m/h). Null if the value is invalid. * @@ -606,8 +607,9 @@ export namespace PumpConfigurationAndControl { /** * This attribute specifies the activity status of the pump functions as listed in PumpStatusBitmap. Where - * a pump controller function is active, the corresponding bit shall be set to 1. Where a pump controller - * function is not active, the corresponding bit shall be set to 0. + * a pump controller function is active, the corresponding bit shall be set to 1. Where a pump + * + * controller function is not active, the corresponding bit shall be set to 0. * * @see {@link MatterSpecification.v13.Cluster} § 4.2.7.14 */ @@ -675,7 +677,7 @@ export namespace PumpConfigurationAndControl { * If the value is not available (the measurement or estimation of the speed is done in the pump), this * attribute will indicate the null value. * - * Valid range is 0 to 65.534 RPM. + * Valid range is 0 to 65,534 RPM. * * @see {@link MatterSpecification.v13.Cluster} § 4.2.7.18 */ @@ -686,10 +688,10 @@ export namespace PumpConfigurationAndControl { * has been running. It is updated dynamically as it increases. It is preserved over power cycles of the * pump. If LifeTimeRunningHours rises above maximum value it “rolls over” and starts at 0 (zero). * - * This attribute is writeable, in order to allow setting to an appropriate value after maintenance. If + * This attribute is writeable, in order to allow setting to an appropriate value after maintenance. If the + * value is not available, this attribute will indicate the null value. * - * the value is not available, this attribute will indicate the null value. Valid range is 0 to 16,777,214 - * hrs. + * Valid range is 0 to 16,777,214 hrs. * * @see {@link MatterSpecification.v13.Cluster} § 4.2.7.19 */ @@ -770,9 +772,7 @@ export namespace PumpConfigurationAndControl { /** * This attribute specifies the control mode of the pump as defined in ControlModeEnum. * - * See the OperationMode attribute for a detailed description of the operation and control of the - * - * pump. + * See the OperationMode attribute for a detailed description of the operation and control of the pump. * * ControlMode may be changed at any time, even when the pump is running. The behavior of the pump at the * point of changing is vendor-specific. @@ -793,7 +793,7 @@ export namespace PumpConfigurationAndControl { * @see {@link MatterSpecification.v13.Cluster} § 4.2.7 * @deprecated */ - alarmMask: OptionalAttribute(0x22, TlvUInt16, { persistent: true, default: 0 }) + alarmMask: OptionalWritableAttribute(0x22, TlvUInt16) }, events: { @@ -919,6 +919,18 @@ export namespace PumpConfigurationAndControl { * the automatic reporting of pump status information. Note that control of pump speed is not included – speed is * controlled by the On/Off and Level Control clusters. * + * ### Pump controller Pump + * + * C Pump configuration and control S C Level control S + * + * C On/Off S + * + * C = Client S = Server + * + * Note: Device names are examples for illustration purposes only + * + * Figure 14. Typical Usage of Pump Configuration and Control Cluster + * * Per the Matter specification you cannot use {@link PumpConfigurationAndControlCluster} without enabling certain * feature combinations. You must use the {@link with} factory method to obtain a working cluster. * diff --git a/packages/types/src/clusters/radon-concentration-measurement.ts b/packages/types/src/clusters/radon-concentration-measurement.ts index fa7b7cbdf6..2d5c084e36 100644 --- a/packages/types/src/clusters/radon-concentration-measurement.ts +++ b/packages/types/src/clusters/radon-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/refrigerator-alarm.ts b/packages/types/src/clusters/refrigerator-alarm.ts index 73e74c6dec..b9ca773593 100644 --- a/packages/types/src/clusters/refrigerator-alarm.ts +++ b/packages/types/src/clusters/refrigerator-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -203,7 +203,8 @@ export namespace RefrigeratorAlarm { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is a derived cluster of Alarm Base cluster. + * This cluster is a derived cluster of Alarm Base cluster and provides the alarm definition related to + * refrigerator and temperature controlled cabinet devices. * * RefrigeratorAlarmCluster supports optional features that you can enable with the RefrigeratorAlarmCluster.with() * factory method. diff --git a/packages/types/src/clusters/refrigerator-and-temperature-controlled-cabinet-mode.ts b/packages/types/src/clusters/refrigerator-and-temperature-controlled-cabinet-mode.ts index 299b4801bf..73b6118309 100644 --- a/packages/types/src/clusters/refrigerator-and-temperature-controlled-cabinet-mode.ts +++ b/packages/types/src/clusters/refrigerator-and-temperature-controlled-cabinet-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -8,14 +8,14 @@ import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; import { BitFlag } from "../schema/BitmapSchema.js"; -import { FixedAttribute, Attribute, WritableAttribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; +import { FixedAttribute, Attribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -23,104 +23,81 @@ export namespace RefrigeratorAndTemperatureControlledCabinetMode { /** * These are optional features supported by RefrigeratorAndTemperatureControlledCabinetModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } export enum ModeTag { /** - * This mode reduces the temperature rapidly, typically above freezing grade. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.7.6.1.1 - */ - RapidCool = 16384, - - /** - * This mode reduces the temperature rapidly, below freezing grade. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.7.6.1.2 - */ - RapidFreeze = 16385, - - /** - * The device decides which options, features and setting values to use. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ Auto = 0, /** - * The mode of the device is optimizing for faster completion. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ Quick = 1, /** - * The device is silent or barely audible while in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ Quiet = 2, /** - * Either the mode is inherently low noise or the device optimizes for that. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ LowNoise = 3, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ LowEnergy = 4, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ Vacation = 5, /** - * The mode uses the lowest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ Min = 6, /** - * The mode uses the highest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ Max = 7, /** - * The mode is recommended or suitable for use during night time. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 */ Night = 8, /** - * The mode is recommended or suitable for use during day time. + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1 + */ + Day = 9, + + /** + * This mode reduces the temperature rapidly, typically above freezing grade. + * + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1.1 + */ + RapidCool = 16384, + + /** + * This mode reduces the temperature rapidly, below freezing grade. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.7.1.2 */ - Day = 9 + RapidFreeze = 16385 } /** @@ -150,7 +127,7 @@ export namespace RefrigeratorAndTemperatureControlledCabinetMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -164,9 +141,7 @@ export namespace RefrigeratorAndTemperatureControlledCabinetMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Auto mode tag in the ModeTags field list. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.7.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.5.1 */ export const TlvModeOption = TlvObject({ /** @@ -228,9 +203,7 @@ export namespace RefrigeratorAndTemperatureControlledCabinetMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Auto mode tag in the ModeTags field list. - * - * @see {@link MatterSpecification.v13.Cluster} § 8.7.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.5.1 */ export interface ModeOption extends TypeFromSchema {} @@ -240,23 +213,23 @@ export namespace RefrigeratorAndTemperatureControlledCabinetMode { export const Base = MutableCluster.Component({ id: 0x52, name: "RefrigeratorAndTemperatureControlledCabinetMode", - revision: 2, + revision: 3, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * @see {@link MatterSpecification.v13.Cluster} § 8.7.5 + * At least one entry in the SupportedModes attribute shall include the Auto mode tag in the ModeTags field + * list. + * + * @see {@link MatterSpecification.v13.Cluster} § 8.7.6.1 */ supportedModes: FixedAttribute( 0x0, @@ -265,19 +238,9 @@ export namespace RefrigeratorAndTemperatureControlledCabinetMode { ), /** - * @see {@link MatterSpecification.v13.Cluster} § 8.7.5 - */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }), - - /** - * @see {@link MatterSpecification.v13.Cluster} § 8.7.5 - */ - startUpMode: WritableAttribute(0x2, TlvUInt8, { persistent: true }), - - /** - * @see {@link MatterSpecification.v13.Cluster} § 8.7.5 + * @see {@link MatterSpecification.v13.Cluster} § 8.7.6 */ - onMode: WritableAttribute(0x3, TlvUInt8, { persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, commands: { @@ -295,7 +258,7 @@ export namespace RefrigeratorAndTemperatureControlledCabinetMode { * This metadata controls which RefrigeratorAndTemperatureControlledCabinetModeCluster elements matter.js * activates for specific feature combinations. */ - extensions: MutableCluster.Extensions() + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -304,7 +267,7 @@ export namespace RefrigeratorAndTemperatureControlledCabinetMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster, defining additional mode tags and namespaced enumerated + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated * values for refrigerator and temperature controlled cabinet devices. * * RefrigeratorAndTemperatureControlledCabinetModeCluster supports optional features that you can enable with the diff --git a/packages/types/src/clusters/relative-humidity-measurement.ts b/packages/types/src/clusters/relative-humidity-measurement.ts index d0a9357358..029c41f6a4 100644 --- a/packages/types/src/clusters/relative-humidity-measurement.ts +++ b/packages/types/src/clusters/relative-humidity-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -48,7 +48,7 @@ export namespace RelativeHumidityMeasurement { * * @see {@link MatterSpecification.v13.Cluster} § 2.6.4.2 */ - minMeasuredValue: Attribute(0x1, TlvNullable(TlvUInt16)), + minMeasuredValue: Attribute(0x1, TlvNullable(TlvUInt16.bound({ max: 9999 }))), /** * The MaxMeasuredValue attribute indicates the maximum value of MeasuredValue that can be measured. The diff --git a/packages/types/src/clusters/resource-monitoring.ts b/packages/types/src/clusters/resource-monitoring.ts index 0fd90ad03f..d4842c22d1 100644 --- a/packages/types/src/clusters/resource-monitoring.ts +++ b/packages/types/src/clusters/resource-monitoring.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/rvc-clean-mode.ts b/packages/types/src/clusters/rvc-clean-mode.ts index e130b3ef77..40f8d01420 100644 --- a/packages/types/src/clusters/rvc-clean-mode.ts +++ b/packages/types/src/clusters/rvc-clean-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,8 +14,8 @@ import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -23,16 +23,13 @@ export namespace RvcCleanMode { /** * These are optional features supported by RvcCleanModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } @@ -41,91 +38,71 @@ export namespace RvcCleanMode { /** * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - DeepClean = 16384, + Auto = 0, /** - * The device’s vacuuming feature is enabled in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2.2 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - Vacuum = 16385, + Quick = 1, /** - * The device’s mopping feature is enabled in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2.3 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - Mop = 16386, + Quiet = 2, /** - * The device decides which options, features and setting values to use. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - Auto = 0, + LowNoise = 3, /** - * The mode of the device is optimizing for faster completion. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - Quick = 1, + LowEnergy = 4, /** - * The device is silent or barely audible while in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - Quiet = 2, + Vacation = 5, /** - * Either the mode is inherently low noise or the device optimizes for that. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - LowNoise = 3, + Min = 6, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - LowEnergy = 4, + Max = 7, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - Vacation = 5, + Night = 8, /** - * The mode uses the lowest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - Min = 6, + Day = 9, /** - * The mode uses the highest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2 */ - Max = 7, + DeepClean = 16384, /** - * The mode is recommended or suitable for use during night time. + * The device’s vacuuming feature is enabled in this mode. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2.2 */ - Night = 8, + Vacuum = 16385, /** - * The mode is recommended or suitable for use during day time. + * The device’s mopping feature is enabled in this mode. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.2.3 */ - Day = 9 + Mop = 16386 } /** @@ -155,7 +132,7 @@ export namespace RvcCleanMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -169,9 +146,6 @@ export namespace RvcCleanMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Vacuum and/or the Mop mode tag in the - * ModeTags field list. - * * @see {@link MatterSpecification.v13.Cluster} § 7.3.5.1 */ export const TlvModeOption = TlvObject({ @@ -234,9 +208,6 @@ export namespace RvcCleanMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Vacuum and/or the Mop mode tag in the - * ModeTags field list. - * * @see {@link MatterSpecification.v13.Cluster} § 7.3.5.1 */ export interface ModeOption extends TypeFromSchema {} @@ -245,37 +216,7 @@ export namespace RvcCleanMode { /** * @see {@link MatterSpecification.v13.Cluster} § 7.3.7.1 */ - CleaningInProgress = 64, - - /** - * Switching to the mode indicated by the NewMode field is allowed and possible. The CurrentMode attribute is - * set to the value of the NewMode field. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 - */ - Success = 0, - - /** - * The value of the NewMode field doesn’t match any entries in the SupportedMode attribute. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 - */ - UnsupportedMode = 1, - - /** - * Generic failure code, indicating that switching to the mode indicated by the NewMode field is not allowed or - * not possible. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 - */ - GenericFailure = 2, - - /** - * The received request cannot be handled due to the current mode of the device - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 - */ - InvalidInMode = 3 + CleaningInProgress = 64 } /** @@ -284,23 +225,23 @@ export namespace RvcCleanMode { export const Base = MutableCluster.Component({ id: 0x55, name: "RvcCleanMode", - revision: 2, + revision: 3, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * @see {@link MatterSpecification.v13.Cluster} § 7.3.6 + * At least one entry in the SupportedModes attribute shall include the Vacuum and/or the Mop mode tag in + * the ModeTags field list. + * + * @see {@link MatterSpecification.v13.Cluster} § 7.3.6.1 */ supportedModes: FixedAttribute( 0x0, @@ -311,7 +252,7 @@ export namespace RvcCleanMode { /** * @see {@link MatterSpecification.v13.Cluster} § 7.3.6 */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, commands: { @@ -329,7 +270,7 @@ export namespace RvcCleanMode { * This metadata controls which RvcCleanModeCluster elements matter.js activates for specific feature * combinations. */ - extensions: MutableCluster.Extensions() + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -338,8 +279,8 @@ export namespace RvcCleanMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster to define specifics for Robotic Vacuum Cleaner devices. It - * also defines a namespace for the cleaning type for these devices. + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated + * values for the cleaning type of robotic vacuum cleaner devices. * * RvcCleanModeCluster supports optional features that you can enable with the RvcCleanModeCluster.with() factory * method. diff --git a/packages/types/src/clusters/rvc-operational-state.ts b/packages/types/src/clusters/rvc-operational-state.ts index 21b1627832..d543eb509e 100644 --- a/packages/types/src/clusters/rvc-operational-state.ts +++ b/packages/types/src/clusters/rvc-operational-state.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -20,9 +20,9 @@ import { TlvString } from "../tlv/TlvString.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; import { TlvUInt8, TlvUInt32, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; +import { OperationalState as OperationalStateNamespace } from "./operational-state.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; -import { OperationalState as OperationalStateNamespace } from "./operational-state.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -33,11 +33,11 @@ export namespace RvcOperationalState { * * RVC Pause Compatibility defines the compatibility of the states this cluster defines with the Pause command. * - * ### Table 39. RVC Pause Compatibility + * ### Table 13. RVC Pause Compatibility * * RVC Resume Compatibility defines the compatibility of the states this cluster defines with the Resume command. * - * ### Table 40. RVC Resume Compatibility + * ### Table 14. RVC Resume Compatibility * * While in the Charging or Docked states, the device shall NOT attempt to resume unless it transitioned to those * states while operating and can resume, such as, for example, if it is recharging while in a cleaning cycle. @@ -48,6 +48,26 @@ export namespace RvcOperationalState { * @see {@link MatterSpecification.v13.Cluster} § 7.4.4.1 */ export enum OperationalState { + /** + * The device is stopped + */ + Stopped = 0, + + /** + * The device is operating + */ + Running = 1, + + /** + * The device is paused during an operation + */ + Paused = 2, + + /** + * The device is in an error state + */ + Error = 3, + /** * The device is en route to the charging dock */ @@ -75,7 +95,7 @@ export namespace RvcOperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.2.1 */ - operationalStateId: TlvField(0, TlvEnum()), + operationalStateId: TlvField(0, TlvEnum()), /** * This field shall be present if the OperationalStateID is from the set reserved for Manufacturer Specific @@ -101,6 +121,26 @@ export namespace RvcOperationalState { * @see {@link MatterSpecification.v13.Cluster} § 7.4.4.2 */ export enum ErrorState { + /** + * The device is not in an error state + */ + NoError = 0, + + /** + * The device is unable to start or resume operation + */ + UnableToStartOrResume = 1, + + /** + * The device was unable to complete the current operation + */ + UnableToCompleteOperation = 2, + + /** + * The device cannot process the command in its current state + */ + CommandInvalidInState = 3, + /** * The device has failed to find or reach the charging dock */ @@ -151,7 +191,7 @@ export namespace RvcOperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.4.4.1 */ - errorStateId: TlvField(0, TlvEnum()), + errorStateId: TlvField(0, TlvEnum()), /** * This field shall be present if the ErrorStateID is from the set reserved for Manufacturer Specific Errors, @@ -239,9 +279,10 @@ export namespace RvcOperationalState { /** * This attribute represents the current phase of operation being performed by the server. This shall be - * the positional index representing the value from the set provided in the PhaseList Attribute, where the - * first item in that list is an index of 0. Thus, this attribute shall have a maximum value that is - * "length(PhaseList) - 1". + * the positional index representing the value from the set provided in the PhaseList Attribute, + * + * where the first item in that list is an index of 0. Thus, this attribute shall have a maximum value that + * is "length(PhaseList) - 1". * * Null if the PhaseList attribute is null or if the PhaseList attribute is an empty list. * @@ -250,24 +291,37 @@ export namespace RvcOperationalState { currentPhase: Attribute(0x1, TlvNullable(TlvUInt8)), /** - * Indicates the estimated time left before the operation is completed, in seconds. Changes to this value - * shall NOT be reported in a subscription (note the C Quality). A Client implementation may periodically - * poll this value to ensure alignment of any local rendering of the CountdownTime with the device provided - * value. + * Indicates the estimated time left before the operation is completed, in seconds. + * + * A value of 0 (zero) means that the operation has completed. + * + * A value of null represents that there is no time currently defined until operation completion. This may + * happen, for example, because no operation is in progress or because the completion time is unknown. + * + * Changes to this attribute shall only be marked as reportable in the following cases: * - * A value of 0 means that the operation has completed. + * • If it has changed due to a change in the CurrentPhase or OperationalState attributes, or * - * When this attribute is null, that represents that there is no time currently defined until operation - * completion. This may happen, for example, because no operation is in progress or because the completion - * time is unknown. + * • When it changes from 0 to any other value and vice versa, or + * + * • When it changes from null to any other value and vice versa, or + * + * • When it increases, or + * + * • When there is any increase or decrease in the estimated time remaining that was due to progressing + * insight of the server’s control logic, or + * + * • When it changes at a rate significantly different from one unit per second. + * + * Changes to this attribute merely due to the normal passage of time with no other dynamic change of + * device state shall NOT be reported. + * + * As this attribute is not being reported during a regular countdown, clients SHOULD NOT rely on the + * reporting of this attribute in order to keep track of the remaining duration. * * @see {@link MatterSpecification.v13.Cluster} § 1.14.5.3 */ - countdownTime: OptionalAttribute( - 0x2, - TlvNullable(TlvUInt32.bound({ max: 259200 })), - { omitChanges: true, default: null } - ), + countdownTime: OptionalAttribute(0x2, TlvNullable(TlvUInt32.bound({ max: 259200 })), { default: null }), /** * This attribute describes the set of possible operational states that the device exposes. An operational @@ -289,7 +343,10 @@ export namespace RvcOperationalState { * * @see {@link MatterSpecification.v13.Cluster} § 1.14.5.5 */ - operationalState: Attribute(0x4, TlvEnum()), + operationalState: Attribute( + 0x4, + TlvEnum() + ), /** * This attribute shall specify the details of any current error condition being experienced on the device @@ -339,10 +396,14 @@ export namespace RvcOperationalState { operationalError: Event(0x0, EventPriority.Critical, TlvOperationalErrorEvent), /** - * This event is generated when the overall operation ends, successfully or otherwise. For example, the - * completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a wash cycle in a + * This event SHOULD be generated when the overall operation ends, successfully or otherwise. For example, + * the completion of a cleaning operation in a Robot Vacuum Cleaner, or the completion of a wash cycle in a * Washing Machine. * + * It is highly recommended that appliances device types employing the Operational State cluster support + * this event, even if it is optional. This assists clients in executing automations or issuing + * notifications at critical points in the device operation cycles. + * * This event shall contain the following fields: * * @see {@link MatterSpecification.v13.Cluster} § 1.14.7.2 @@ -356,7 +417,8 @@ export namespace RvcOperationalState { }); /** - * This cluster provides an interface for monitoring the operational state of a Robotic Vacuum Cleaner. + * This cluster is derived from the Operational State cluster and provides an interface for monitoring the + * operational state of a robotic vacuum cleaner. * * @see {@link MatterSpecification.v13.Cluster} § 7.4 */ diff --git a/packages/types/src/clusters/rvc-run-mode.ts b/packages/types/src/clusters/rvc-run-mode.ts index 8a2e340cf5..68c9d9e808 100644 --- a/packages/types/src/clusters/rvc-run-mode.ts +++ b/packages/types/src/clusters/rvc-run-mode.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -14,8 +14,8 @@ import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; import { TlvString } from "../tlv/TlvString.js"; import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; import { TlvVendorId } from "../datatype/VendorId.js"; -import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -23,124 +23,101 @@ export namespace RvcRunMode { /** * These are optional features supported by RvcRunModeCluster. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.4 */ export enum Feature { /** * OnOff (DEPONOFF) * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the same - * endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ OnOff = "OnOff" } export enum ModeTag { /** - * The device is not performing any of the main operations of the other modes. However, auxiliary actions, such - * as seeking the charger or charging, may occur. - * - * For example, the device has completed cleaning, successfully or not, on its own or due to a command, or has - * not been asked to clean after a restart. - * - * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2.1 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - Idle = 16384, + Auto = 0, /** - * The device was asked to clean so it may be actively running, or paused due to an error, due to a pause - * command, or for recharging etc. If currently paused and the device can resume it will continue to clean. - * - * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2.2 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - Cleaning = 16385, + Quick = 1, /** - * The device was asked to create a map of the space it is located in, so it may be actively running, or paused - * due to an error, due to a pause command, or for recharging etc. If currently paused and the device can - * resume, it will continue to map. - * - * NOTE - * - * this mode is intended to be used so the current space can be mapped by the device if the robot has not - * previously done that, or if the layout has substantially changed, for an optimal subsequent cleaning - * experience. - * - * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2.3 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - Mapping = 16386, + Quiet = 2, /** - * The device decides which options, features and setting values to use. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - Auto = 0, + LowNoise = 3, /** - * The mode of the device is optimizing for faster completion. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - Quick = 1, + LowEnergy = 4, /** - * The device is silent or barely audible while in this mode. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - Quiet = 2, + Vacation = 5, /** - * Either the mode is inherently low noise or the device optimizes for that. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - LowNoise = 3, + Min = 6, /** - * The device is optimizing for lower energy usage in this mode. Sometimes called "Eco mode". - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - LowEnergy = 4, + Max = 7, /** - * A mode suitable for use during vacations or other extended absences. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - Vacation = 5, + Night = 8, /** - * The mode uses the lowest available setting value. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2 */ - Min = 6, + Day = 9, /** - * The mode uses the highest available setting value. + * The device is not performing any of the main operations of the other modes. However, auxiliary actions, such + * as seeking the charger or charging, may occur. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * For example, the device has completed cleaning, successfully or not, on its own or due to a command, or has + * not been asked to clean after a restart. + * + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2.1 */ - Max = 7, + Idle = 16384, /** - * The mode is recommended or suitable for use during night time. + * The device was asked to clean so it may be actively running, or paused due to an error, due to a pause + * command, or for recharging etc. If currently paused and the device can resume it will continue to clean. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2.2 */ - Night = 8, + Cleaning = 16385, /** - * The mode is recommended or suitable for use during day time. + * The device was asked to create a map of the space it is located in, so it may be actively running, or paused + * due to an error, due to a pause command, or for recharging etc. If currently paused and the device can + * resume, it will continue to map. + * + * NOTE + * + * this mode is intended to be used so the current space can be mapped by the device if the robot has not + * previously done that, or if the layout has substantially changed, for an optimal subsequent cleaning + * experience. * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.8 + * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.2.3 */ - Day = 9 + Mapping = 16386 } /** @@ -170,7 +147,7 @@ export namespace RvcRunMode { * * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 */ - value: TlvField(1, TlvEnum()) + value: TlvField(1, TlvEnum()) }); /** @@ -184,14 +161,6 @@ export namespace RvcRunMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Idle mode tag in the ModeTags field. - * - * At least one entry in the SupportedModes attribute (different from the one above) shall include the Cleaning - * mode tag in the ModeTags field. - * - * The Mapping, Cleaning, and Idle mode tags are mutually exclusive and shall NOT be used together in a mode’s - * ModeTags. - * * @see {@link MatterSpecification.v13.Cluster} § 7.2.5.1 */ export const TlvModeOption = TlvObject({ @@ -254,14 +223,6 @@ export namespace RvcRunMode { * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. * A blank field indicates no change. * - * At least one entry in the SupportedModes attribute shall include the Idle mode tag in the ModeTags field. - * - * At least one entry in the SupportedModes attribute (different from the one above) shall include the Cleaning - * mode tag in the ModeTags field. - * - * The Mapping, Cleaning, and Idle mode tags are mutually exclusive and shall NOT be used together in a mode’s - * ModeTags. - * * @see {@link MatterSpecification.v13.Cluster} § 7.2.5.1 */ export interface ModeOption extends TypeFromSchema {} @@ -305,37 +266,7 @@ export namespace RvcRunMode { /** * @see {@link MatterSpecification.v13.Cluster} § 7.2.7.1 */ - BatteryLow = 72, - - /** - * Switching to the mode indicated by the NewMode field is allowed and possible. The CurrentMode attribute is - * set to the value of the NewMode field. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 - */ - Success = 0, - - /** - * The value of the NewMode field doesn’t match any entries in the SupportedMode attribute. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 - */ - UnsupportedMode = 1, - - /** - * Generic failure code, indicating that switching to the mode indicated by the NewMode field is not allowed or - * not possible. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 - */ - GenericFailure = 2, - - /** - * The received request cannot be handled due to the current mode of the device - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.2.1.2 - */ - InvalidInMode = 3 + BatteryLow = 72 } /** @@ -344,23 +275,28 @@ export namespace RvcRunMode { export const Base = MutableCluster.Component({ id: 0x54, name: "RvcRunMode", - revision: 2, + revision: 3, features: { /** * OnOff * - * This feature creates a dependency between an OnOff cluster instance and this cluster instance on the - * same endpoint. See OnMode for more information. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.10.4.1 + * Dependency with the OnOff cluster */ onOff: BitFlag(0) }, attributes: { /** - * @see {@link MatterSpecification.v13.Cluster} § 7.2.6 + * At least one entry in the SupportedModes attribute shall include the Idle mode tag in the ModeTags field. + * + * At least one entry in the SupportedModes attribute (different from the one above) shall include the + * Cleaning mode tag in the ModeTags field. + * + * The Mapping, Cleaning, and Idle mode tags are mutually exclusive and shall NOT be used together in a + * mode’s ModeTags. + * + * @see {@link MatterSpecification.v13.Cluster} § 7.2.6.1 */ supportedModes: FixedAttribute( 0x0, @@ -371,7 +307,7 @@ export namespace RvcRunMode { /** * @see {@link MatterSpecification.v13.Cluster} § 7.2.6 */ - currentMode: Attribute(0x1, TlvUInt8, { scene: true, persistent: true }) + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) }, commands: { @@ -389,7 +325,7 @@ export namespace RvcRunMode { * This metadata controls which RvcRunModeCluster elements matter.js activates for specific feature * combinations. */ - extensions: MutableCluster.Extensions() + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) }); /** @@ -398,8 +334,8 @@ export namespace RvcRunMode { export const ClusterInstance = MutableCluster(Base); /** - * This cluster is derived from the Mode Base cluster to define specifics for Robotic Vacuum Cleaner devices. It - * also defines a namespace for the running modes of these devices. + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated + * values for the running modes of robotic vacuum cleaner devices. * * RvcRunModeCluster supports optional features that you can enable with the RvcRunModeCluster.with() factory * method. diff --git a/packages/types/src/clusters/scenes-management.ts b/packages/types/src/clusters/scenes-management.ts index 6d497ff497..e1d06862a6 100644 --- a/packages/types/src/clusters/scenes-management.ts +++ b/packages/types/src/clusters/scenes-management.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -136,17 +136,19 @@ export namespace ScenesManagement { /** * This field shall be present for all instances in a given ExtensionFieldSetStruct. * - * The data type of AttributeValue shall be the data type of the attribute indicated by AttributeID. + * Which Value* field is used shall be determined based on the data type of the attribute indicated by + * AttributeID, as described in the Value* Fields subsection. * * The AttributeID field shall NOT refer to an attribute without the Scenes ("S") designation in the Quality * column of the cluster specification. * - * 1.4.7.3.2. ValueUnsigned8, ValueSigned8, ValueUnsigned16, ValueSigned16, ValueUnsigned32, ValueSigned32, - * ValueUnsigned64, ValueSigned64 Fields + * ### 1.4.7.3.2. ValueUnsigned8, ValueSigned8, ValueUnsigned16, ValueSigned16, ValueUnsigned32, ValueSigned32, + * ValueUnsigned64, ValueSigned64 Fields * * These fields shall indicate the attribute value as part of an extension field set, associated with a given - * AttributeID under an ExtensionFieldSetStruct’s ClusterID. The proper field shall be present that maps to the - * data type of the attribute indicated. + * AttributeID under an ExtensionFieldSetStruct’s ClusterID. Which of the fields is used shall + * + * be determined by the type of the attribute indicated by AttributeID as follows: * * • Data types bool, map8, and uint8 shall map to ValueUnsigned8. * @@ -160,33 +162,48 @@ export namespace ScenesManagement { * * • Data types int24 and int32 shall map to ValueSigned32. * - * • Data types map64, uint48, uint56 and uint64 shall map to ValueUnsigned64. + * • Data types map64, uint40, uint48, uint56 and uint64 shall map to ValueUnsigned64. + * + * • Data types int40, int48, int56 and int64 shall map to ValueSigned64. + * + * • For derived types, the mapping shall be based on the base type. For example, an attribute of type + * percent shall be treated as if it were of type uint8, whereas an attribute of type percent100ths shall + * be treated as if it were of type uint16. + * + * • For boolean nullable attributes, any value that is not 0 or 1 shall be considered to have the null value. * - * • Data types int48, int56 and int64 shall map to ValueSigned64. + * • For boolean non-nullable attributes, any value that is not 0 or 1 shall be considered to have the value + * FALSE. * - * • For nullable attributes, any value that is not a valid numeric value for the attribute’s type after - * accounting for range reductions due to being nullable and constraints shall be considered to have the - * null value for the type. + * • For non-boolean nullable attributes, any value that is not a valid numeric value for the attribute’s + * type after accounting for range reductions due to being nullable and constraints shall be considered to + * have the null value for the type. * - * • For non-nullable attributes, any value that is not a valid numeric value for the attribute’s type after - * accounting for constraints shall be considered to have the maximum legal value in the attribute’s - * constrained range. + * • For non-boolean non-nullable attributes, any value that is not a valid numeric value for the attribute’s + * type after accounting for constraints shall be considered to be the valid attribute value that is + * closest to the provided value. + * + * ◦ In the event that an invalid provided value is of equal numerical distance to the two closest valid + * values, the lowest of those values shall be considered the closest valid attribute value. + * + * If the used field does not match the data type of the attribute indicated by AttributeID, the + * AttributeValuePairStruct shall be considered invalid. * * Examples of processing are: * * • ColorControl cluster CurrentX (AttributeID 0x0003) has a type of uint16 and is not nullable. * - * ◦ AttributeValue of 0xAB12 would be used as-is, as it is in range. + * ◦ ValueUnsigned16 of 0xAB12 would be used as-is, as it is in range. * - * ◦ AttributeValue of 0xAA0011 is outside of the range of uint16, and would be saturated to the maximum of - * the attribute’s constraint range: 0xFEFF. + * ◦ ValueUnsigned16 of 0xFF80 is outside of the range allowed for attribute CurrentX, and would be + * saturated to the closest valid value, which is the maximum of the attribute’s constraint range: 0xFEFF. * * • LevelControl cluster CurrentLevel (AttributeID 0x0000) has a type of uint8 and is nullable. * - * ◦ AttributeValue of 0xA1 would be used as-is, as it is in range. + * ◦ ValueUnsigned8 of 0xA1 would be used as-is, as it is in range. * - * ◦ AttributeValue of 0xBB12 is outside the range of nullable uint8, and would be considered as the null - * value. + * ◦ ValueUnsigned8 of 0xFF is outside the range allowed for nullable attribute CurrentLevel, and would be + * considered as the null value. * * @see {@link MatterSpecification.v13.Cluster} § 1.4.7.3.1 */ @@ -756,9 +773,7 @@ export namespace ScenesManagement { groupIdentifierFrom: TlvField(1, TlvGroupId), /** - * This field shall be set to the same values as in the corresponding fields of the received CopyScene - * - * command. + * This field shall be set to the same values as in the corresponding fields of the received CopyScene command. * * @see {@link MatterSpecification.v13.Cluster} § 1.4.9.16.3 */ @@ -991,7 +1006,7 @@ export namespace ScenesManagement { * In most cases scenes are associated with a particular group identifier. Scenes may also exist without a group, * in which case the value 0 replaces the group identifier. Note that extra care is required in these cases to * avoid a scene identifier collision, and that commands related to scenes without a group may only be unicast, - * i.e., they may not be multicast or broadcast. + * i.e., they shall NOT be multicast or broadcast. * * NOTE Support for Scenes Management cluster is provisional. * diff --git a/packages/types/src/clusters/service-area.ts b/packages/types/src/clusters/service-area.ts new file mode 100644 index 0000000000..bfad803a52 --- /dev/null +++ b/packages/types/src/clusters/service-area.ts @@ -0,0 +1,904 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { Attribute, OptionalAttribute, Command, OptionalCommand } from "../cluster/Cluster.js"; +import { TlvArray } from "../tlv/TlvArray.js"; +import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js"; +import { TlvUInt32, TlvEnum, TlvUInt8, TlvEpochS } from "../tlv/TlvNumber.js"; +import { TlvString } from "../tlv/TlvString.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { TlvNullable } from "../tlv/TlvNullable.js"; +import { BitFlag } from "../schema/BitmapSchema.js"; +import { TlvLocationdesc } from "../globals/Locationdesc.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace ServiceArea { + /** + * These are optional features supported by ServiceAreaCluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.4 + */ + export enum Feature { + /** + * SelectWhileRunning (SELRUN) + * + * This feature indicates whether this device allows changing the selected areas, by using the SelectAreas + * command, while operating. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.4.1 + */ + SelectWhileRunning = "SelectWhileRunning", + + /** + * ProgressReporting (PROG) + * + * The device implements the progress reporting feature + */ + ProgressReporting = "ProgressReporting", + + /** + * Maps (MAPS) + * + * The device has map support + */ + Maps = "Maps" + } + + /** + * This is a struct representing a map. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.3 + */ + export const TlvMap = TlvObject({ + /** + * This field shall represent the map’s identifier. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.3.1 + */ + mapId: TlvField(0, TlvUInt32), + + /** + * This field shall represent a human understandable map description. For example: "Main Floor", or "Second + * Level". + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.3.2 + */ + name: TlvField(1, TlvString.bound({ maxLength: 64 })) + }); + + /** + * This is a struct representing a map. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.3 + */ + export interface Map extends TypeFromSchema {} + + /** + * The following table defines the status values. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.6 + */ + export enum OperationalStatus { + /** + * The device has not yet started operating at the given area, or has not finished operating at that area but + * it is not currently operating at the area + */ + Pending = 0, + + /** + * The device is currently operating at the given area + */ + Operating = 1, + + /** + * The device has skipped the given area, before or during operating at it, due to a SkipArea command, due an + * out of band command (e.g. from the vendor’s application), due to a vendor specific reason, such as a time + * limit used by the device, or due the device ending operating unsuccessfully + */ + Skipped = 2, + + /** + * The device has completed operating at the given area + */ + Completed = 3 + } + + /** + * This is a struct indicating the progress. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.5 + */ + export const TlvProgress = TlvObject({ + /** + * This field shall indicate the identifier of the area, and the identifier shall be an entry in the + * SupportedAreas attribute’s list. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.5.1 + */ + areaId: TlvField(0, TlvUInt32), + + /** + * This field shall indicate the operational status of the device regarding the area indicated by the AreaID + * field. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.5.2 + */ + status: TlvField(1, TlvEnum()), + + /** + * This field shall indicate the total operational time, in seconds, from when the device started to operate at + * the area indicated by the AreaID field, until the operation finished, due to completion or due to skipping, + * including any time spent while paused. + * + * A value of null indicates that the total operational time is unknown. + * + * There may be cases where the total operational time exceeds the maximum value that can be conveyed by this + * attribute, and in such instances this attribute shall be populated with null. + * + * Null if the Status field is not set to Completed or Skipped. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.5.3 + */ + totalOperationalTime: TlvOptionalField(2, TlvNullable(TlvUInt32)), + + /** + * This field shall indicate the estimated time for the operation, in seconds, from when the device will start + * operating at the area indicated by the AreaID field, until the operation completes, excluding any time spent + * while not operating in the area. + * + * A value of null indicates that the estimated time is unknown. If the estimated time is unknown, or if it + * exceeds the maximum value that can be conveyed by this attribute, this attribute shall be null. + * + * After initializing the ProgressStruct instance, the server SHOULD NOT change the value of this field, except + * when repopulating the entire instance, to avoid excessive reporting of the Progress attribute changes. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.5.4 + */ + initialTimeEstimate: TlvOptionalField(3, TlvNullable(TlvUInt32)) + }); + + /** + * This is a struct indicating the progress. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.5 + */ + export interface Progress extends TypeFromSchema {} + + /** + * The data from this structure indicates a landmark and position relative to the landmark. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.1 + */ + export const TlvLandmarkInfo = TlvObject({ + /** + * This field shall indicate that the area is associated with a landmark. + * + * This field shall be the ID of a landmark semantic tag, located within the Common Landmark Namespace. For + * example, this tag may indicate that the area refers to an area next to a table. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.1.1 + */ + landmarkTag: TlvField(0, TlvUInt8), + + /** + * This field shall identify the position of the area relative to a landmark. This is a static description of a + * zone known to the server, and this field never reflects the device’s own proximity or position relative to + * the landmark, but that of the zone. + * + * This field shall be the ID of a relative position semantic tag, located within the Common Relative Position + * Namespace. + * + * If the RelativePositionTag field is null, this field indicates proximity to the landmark. Otherwise, the + * RelativePositionTag field indicates the position of the area relative to the landmark indicated by the + * LandmarkTag field. For example, this tag, in conjunction with the LandmarkTag field, may indicate that the + * area refers to a zone under a table. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.1.2 + */ + relativePositionTag: TlvField(1, TlvNullable(TlvUInt8)) + }); + + /** + * The data from this structure indicates a landmark and position relative to the landmark. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.1 + */ + export interface LandmarkInfo extends TypeFromSchema {} + + /** + * The data from this structure indicates the name and/or semantic data describing an area, as detailed below. + * + * This data type includes the LocationInfo field, with the following fields: LocationName, FloorNumber, AreaType. + * Additional semantic data may be available in the LandmarkInfo field. + * + * For an area description to be meaningful, it shall have at least one of the following: + * + * • a non-empty name (LocationInfo’s LocationName field) OR + * + * • some semantic data (one or more of these: FloorNumber, AreaType or LandmarkTag) The normative text from the + * remainder of this section describes these constraints. + * + * If the LocationInfo field is null, the LandmarkInfo field shall NOT be null. If the LandmarkInfo field is null, + * the LocationInfo field shall NOT be null. + * + * If LocationInfo is not null, and its LocationName field is an empty string, at least one of the following shall + * NOT be null: + * + * • LocationInfo’s FloorNumber field + * + * • LocationInfo’s AreaType field + * + * • LandmarkInfo field + * + * If all three of the following are null, LocationInfo’s LocationName field shall NOT be an empty string: + * + * • LocationInfo’s FloorNumber field + * + * • LocationInfo’s AreaType field + * + * • LandmarkInfo field + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.2 + */ + export const TlvAreaInfo = TlvObject({ + /** + * This field shall indicate the name of the area, floor number and/or area type. A few examples are provided + * below. + * + * • An area can have LocationInfo’s LocationName field set to "blue room", and the AreaType field set to the + * ID of a "Living Room" semantic tag. Clients wishing to direct the device to operate in (or service) the + * living room can use this area. + * + * • An area can have LocationInfo set to null, the LandmarkInfo’s LandmarkTag field set to the ID of the + * "Table" landmark semantic tag, and the RelativePositionTag field set to the ID of the "Under" position + * semantic tag. With such an area indication, the client can request the device to operate in (or service) + * the area located under the table. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.2.1 + */ + locationInfo: TlvField(0, TlvNullable(TlvLocationdesc)), + + /** + * This field shall indicate an association with a landmark. A value of null indicates that the information is + * not available or known. For example, this may indicate that the area refers to a zone next to a table. + * + * If this field is not null, that indicates that the area is restricted to the zone where the landmark is + * located, as indicated by the LandmarkTag and, if not null, by the RelativePositionTag fields, rather than to + * the entire room or floor where the landmark is located, if those are indicated by the LocationInfo field. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.2.2 + */ + landmarkInfo: TlvField(1, TlvNullable(TlvLandmarkInfo)) + }); + + /** + * The data from this structure indicates the name and/or semantic data describing an area, as detailed below. + * + * This data type includes the LocationInfo field, with the following fields: LocationName, FloorNumber, AreaType. + * Additional semantic data may be available in the LandmarkInfo field. + * + * For an area description to be meaningful, it shall have at least one of the following: + * + * • a non-empty name (LocationInfo’s LocationName field) OR + * + * • some semantic data (one or more of these: FloorNumber, AreaType or LandmarkTag) The normative text from the + * remainder of this section describes these constraints. + * + * If the LocationInfo field is null, the LandmarkInfo field shall NOT be null. If the LandmarkInfo field is null, + * the LocationInfo field shall NOT be null. + * + * If LocationInfo is not null, and its LocationName field is an empty string, at least one of the following shall + * NOT be null: + * + * • LocationInfo’s FloorNumber field + * + * • LocationInfo’s AreaType field + * + * • LandmarkInfo field + * + * If all three of the following are null, LocationInfo’s LocationName field shall NOT be an empty string: + * + * • LocationInfo’s FloorNumber field + * + * • LocationInfo’s AreaType field + * + * • LandmarkInfo field + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.2 + */ + export interface AreaInfo extends TypeFromSchema {} + + /** + * This is a struct representing an area known to the server. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.4 + */ + export const TlvArea = TlvObject({ + /** + * This field shall represent the identifier of the area. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.4.1 + */ + areaId: TlvField(0, TlvUInt32), + + /** + * This field shall indicate the map identifier which the area is associated with. A value of null indicates + * that the area is not associated with a map. + * + * If the SupportedMaps attribute is not empty, this field shall match the MapID field of an entry from the + * SupportedMaps attribute’s list. If the SupportedMaps attribute is empty, this field shall be null. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.4.2 + */ + mapId: TlvField(1, TlvNullable(TlvUInt32)), + + /** + * This field shall contain data describing the area. + * + * This SHOULD be used by clients to determine the name and/or the full, or the partial, semantics of a certain + * area. + * + * NOTE + * + * If any entries on the SupportedAreas attribute’s list have the AreaInfo field missing the semantic data, the + * client may remind the user to assign the respective data. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.4.3 + */ + areaInfo: TlvField(2, TlvAreaInfo) + }); + + /** + * This is a struct representing an area known to the server. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.4 + */ + export interface Area extends TypeFromSchema {} + + /** + * Input to the ServiceArea selectAreas command + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.1 + */ + export const TlvSelectAreasRequest = TlvObject({ + /** + * This field indicates which areas the device is to operate at. + * + * If this field is empty, that indicates that the device is to operate without being constrained to any + * specific areas, and the operation will not allow skipping using the SkipArea Command, otherwise the field + * shall be a list of unique values that match the AreaID field of entries on the SupportedAreas list. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.1.1 + */ + newAreas: TlvField(0, TlvArray(TlvUInt32)) + }); + + /** + * Input to the ServiceArea selectAreas command + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.1 + */ + export interface SelectAreasRequest extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.6.1 + */ + export enum SelectAreasStatus { + /** + * Attempting to operate in the areas identified by the entries of the NewAreas field is allowed and possible. + * The SelectedAreas attribute is set to the value of the NewAreas field. + */ + Success = 0, + + /** + * The value of at least one of the entries of the NewAreas field doesn’t match any entries in the + * SupportedAreas attribute. + */ + UnsupportedArea = 1, + + /** + * The received request cannot be handled due to the current mode of the device. + */ + InvalidInMode = 2, + + /** + * The set of values is invalid. For example, areas on different floors, that a robot knows it can’t reach on + * its own. + */ + InvalidSet = 3 + } + + /** + * This command is sent by the device on receipt of the SelectAreas command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.2 + */ + export const TlvSelectAreasResponse = TlvObject({ + /** + * If the Status field is set to Success or UnsupportedArea, the server may use a non-empty string for the + * StatusText field to provide additional information. For example, if Status is set to Unsupport + * + * edArea, the server may use StatusText to indicate which areas are unsupported. + * + * If the Status field is not set to Success, or UnsupportedArea, the StatusText field shall include a + * vendor-defined error description which can be used to explain the error to the user. For example, if the + * Status field is set to InvalidInMode, the StatusText field SHOULD indicate why the request is not allowed, + * given the current mode of the device, which may involve other clusters. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.2.1 + */ + status: TlvField(0, TlvEnum()), + + statusText: TlvField(1, TlvString.bound({ maxLength: 256 })) + }); + + /** + * This command is sent by the device on receipt of the SelectAreas command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.2 + */ + export interface SelectAreasResponse extends TypeFromSchema {} + + /** + * Input to the ServiceArea skipArea command + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.3 + */ + export const TlvSkipAreaRequest = TlvObject({ + /** + * The SkippedArea field indicates the area to be skipped. + * + * The SkippedArea field shall match an entry in the SupportedAreas list. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.3.1 + */ + skippedArea: TlvField(0, TlvUInt32) + }); + + /** + * Input to the ServiceArea skipArea command + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.3 + */ + export interface SkipAreaRequest extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Cluster} § 1.17.5.6.2 + */ + export enum SkipAreaStatus { + /** + * Skipping the area is allowed and possible, or the device was operating at the last available area and has + * stopped. + */ + Success = 0, + + /** + * The SelectedAreas attribute is empty. + */ + InvalidAreaList = 1, + + /** + * The received request cannot be handled due to the current mode of the device. For example, the CurrentArea + * attribute is null or the device is not operating. + */ + InvalidInMode = 2, + + /** + * The SkippedArea field doesn’t match an entry in the SupportedAreas list. + */ + InvalidSkippedArea = 3 + } + + /** + * This command is sent by the device on receipt of the SkipArea command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.4 + */ + export const TlvSkipAreaResponse = TlvObject({ + /** + * If the Status field is set to Success or InvalidAreaList, the server may use a non-empty string for the + * StatusText field to provide additional information. For example, if Status is set to InvalidAreaList, the + * server may use StatusText to indicate why this list is invalid. + * + * If the Status field is not set to Success or InvalidAreaList, the StatusText field shall include a vendor + * defined error description which can be used to explain the error to the user. For example, if the Status + * field is set to InvalidInMode, the StatusText field SHOULD indicate why the request is not allowed, given + * the current mode of the device, which may involve other clusters. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.4.1 + */ + status: TlvField(0, TlvEnum()), + + statusText: TlvField(1, TlvString.bound({ maxLength: 256 })) + }); + + /** + * This command is sent by the device on receipt of the SkipArea command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.4 + */ + export interface SkipAreaResponse extends TypeFromSchema {} + + /** + * A ServiceAreaCluster supports these elements if it supports feature Maps. + */ + export const MapsComponent = MutableCluster.Component({ + attributes: { + /** + * This attribute shall contain the list of supported maps. + * + * A map is a full or a partial representation of a home, known to the device. For example: + * + * • a single level home may be represented using a single map + * + * • a two level home may be represented using two maps, one for each level + * + * • a single level home may be represented using two maps, each including a different set of rooms, such + * as "map of living room and kitchen" and "map of bedrooms and hallway" + * + * • a single level home may be represented using one map for the indoor areas (living room, bedrooms + * etc.) and one for the outdoor areas (garden, swimming pool etc.) + * + * Each map includes one or more areas - see the SupportedAreas attribute. In the context of this cluster + * specification, a map is effectively a group label for a set of areas, rather than a graphical + * representation that the clients can display to the users. The clients that present the list of available + * areas for user selection (see the SelectAreas command) may choose to filter the SupportedAreas list + * based on the associated map. For example, the clients may allow the user to indicate that the device is + * to operate on the first floor, and allow the user to choose only from the areas situated on that level. + * + * If empty, that indicates that the device is currently unable to provide this information. Each entry in + * this list shall have a unique value for the MapID field. + * + * Each entry in this list shall have a unique value for the Name field. + * + * NOTE + * + * due to the maximum size of this list and to the fact that the entries may include strings (see the Name + * field of the MapStruct data type), care must be taken by implementers to avoid creating a data structure + * that is overly large, which can result in significant latency in accessing this attribute. + * + * The value of this attribute may change at any time via an out-of-band interaction outside of the server, + * such as interactions with a user interface. + * + * When updating the SupportedMaps attribute list by deleting entries, or by setting the attribute to an + * empty list, the SupportedLocations attribute shall be updated such that all entries in that list meet + * the constraints indicated in the description of the SupportedLocations attribute. This may result in + * + * the server removing entries from the SupportedAreas attribute list. See the SupportedAreas attribute + * description for the implications of changing that attribute. + * + * The SupportedMaps attribute list changes mentioned above SHOULD NOT be allowed while the device is + * operating, to reduce the impact on the clients, and the potential confusion for the users. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.6.2 + */ + supportedMaps: Attribute(0x1, TlvArray(TlvMap, { maxLength: 255 }), { default: [] }) + } + }); + + /** + * A ServiceAreaCluster supports these elements if it supports feature ProgressReporting. + */ + export const ProgressReportingComponent = MutableCluster.Component({ + attributes: { + /** + * Indicates the operating status at one or more areas. Each entry in this list shall have a unique value + * for the AreaID field. + * + * For each entry in this list, the AreaID field shall match an entry on the SupportedAreas attribute’s + * list. + * + * When this attribute is empty, that represents that no progress information is currently available. + * + * If the SelectedAreas attribute is empty, indicating the device is not constrained to operate in any + * specific areas, the Progress attribute list may change while the device operates, due to the device + * adding new entries dynamically, when it determines which ones it can attempt to operate at. + * + * If the SelectedAreas attribute is not empty, and the device starts operating: + * + * • the Progress attribute list shall be updated so each entry of SelectedAreas has a matching Progress + * list entry, based on the AreaID field + * + * • the length of the Progress and SelectedAreas list shall be the same + * + * • the entries in the Progress list shall be initialized by the server, by having their status set to + * Pending or Operating, and the TotalOperationalTime field set to null + * + * When the device ends operation unexpectedly, such as due to an error, the server shall update all + * Progress list entries with the Status field set to Operating or Pending to Skipped. + * + * When the device finishes operating, successfully or not, it shall NOT change the Progress attribute, + * except in the case of an unexpected end of operation as described above, or due to changes to the + * SupportedMaps or SupportedAreas attributes, so the clients can retrieve the progress information at that + * time. + * + * NOTE + * + * if the device implements the Operational Status cluster, or a derivation of it, in case the device fails + * to service any locations in the SelectedAreas list before ending the operation, it SHOULD use the + * Operational Status cluster to indicate that the device was unable to complete the operation (see the + * UnableToCompleteOperation error from that cluster specification). The clients SHOULD then read the + * Progress attribute, and indicate which areas have been successfully serviced (marked as completed). + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.6.6 + */ + progress: Attribute(0x5, TlvArray(TlvProgress, { maxLength: 255 }), { default: [] }) + } + }); + + /** + * These elements and properties are present in all ServiceArea clusters. + */ + export const Base = MutableCluster.Component({ + id: 0x150, + name: "ServiceArea", + revision: 1, + + features: { + /** + * SelectWhileRunning + * + * This feature indicates whether this device allows changing the selected areas, by using the SelectAreas + * command, while operating. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.4.1 + */ + selectWhileRunning: BitFlag(0), + + /** + * ProgressReporting + * + * The device implements the progress reporting feature + */ + progressReporting: BitFlag(1), + + /** + * Maps + * + * The device has map support + */ + maps: BitFlag(2) + }, + + attributes: { + /** + * This attribute shall contain the list of areas that can be included in the SelectedAreas attribute’s + * list. Each item in this list represents a unique area, as indicated by the AreaID field of AreaStruct. + * + * Each entry in this list shall have a unique value for the AreaID field. + * + * If the SupportedMaps attribute is not empty, each entry in this list shall have a unique value for the + * combination of the MapID and AreaInfo fields. + * + * If the SupportedMaps attribute is empty, each entry in this list shall have a unique value for the + * AreaInfo field and shall have the MapID field set to null. + * + * An empty value indicates that the device is currently unable to provide the list of supported areas. + * + * NOTE + * + * due to the maximum size of this list and to the fact that the entries may include strings (see + * LocationName), care must be taken by implementers to avoid creating a data structure that is overly + * large, which can result in significant latency in accessing this attribute. + * + * The value of this attribute may change at any time via an out-of-band interaction outside of the server, + * such as interactions with a user interface, or due to internal device changes. + * + * When removing entries in the SupportedAreas attribute list the server shall adjust the values of the + * SelectedAreas, CurrentArea, and Progress attributes such that they only reference valid entries in the + * updated SupportedAreas attribute list. These changes to the SelectedAreas, CurrentArea, and Progress + * attributes may result in the server setting some or all of them to empty (for SelectedAreas and + * Progress) or null (for CurrentArea), or updating them with data that matches the constraints from the + * description of the respective attributes. These actions are required to ensure having a consistent + * representation of the maps and locations available to the clients. + * + * The SupportedAreas attribute list changes mentioned above SHOULD NOT be allowed while the device is + * operating, to reduce the impact on the clients, and the potential confusion for the users. + * + * A few examples are provided below. Valid list of areas: + * + * • AreaID=0, LocationName="yellow bedroom", MapID=null + * + * • AreaID=1, LocationName="orange bedroom", MapID=null Valid list of areas: + * + * • AreaID=5, LocationName="hallway", MapID=1 + * + * • AreaID=3, LocationName="hallway", MapID=2 + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.6.1 + */ + supportedAreas: Attribute(0x0, TlvArray(TlvArea, { maxLength: 255 }), { default: [] }), + + /** + * Indicates the set of areas where the device SHOULD attempt to operate. + * + * The mobile devices may travel without operating across any areas while attempting to reach the areas + * indicated by the SelectedAreas attribute. For example, a robotic vacuum cleaner may drive without + * cleaning when traveling without operating. + * + * If this attribute is empty, the device is not constrained to operate in any specific areas. If this + * attribute is not empty: + * + * • each item in this list shall match the AreaID field of an entry in the SupportedAreas attribute’s + * list + * + * • each entry in this list shall have a unique value + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.6.3 + */ + selectedAreas: Attribute(0x2, TlvArray(TlvUInt32), { default: [] }), + + /** + * If the device is mobile, this attribute shall indicate the area where the device is currently located, + * regardless of whether it is operating or not, such as while traveling between areas. + * + * If the device is not mobile and can operate at multiple areas sequentially, this attribute shall + * indicate the area which is currently being serviced, or the area which is currently traversed by the + * device. For example, a camera device may use this attribute to indicate which area it currently takes + * video of (serviced area) or which area it currently has in view but not taking video of (e.g. an area + * which is traversed while panning). + * + * NOTE + * + * A device may traverse an area regardless of the status of the area (pending, skipped, or completed). + * + * If a device can simultaneously operate at multiple areas, such as in the case of a sensor that can + * monitor multiple areas at the same time, the CurrentArea attribute shall NOT be implemented, since it + * doesn’t apply. Else this attribute shall be optionally implemented. + * + * A null value indicates that the device is currently unable to provide this information. For example, the + * device is traversing an unknown area, or the SupportedAreas attribute was updated and the area where the + * device is located was removed from that list. + * + * If not null, the value of this attribute shall match the AreaID field of an entry on the SupportedAreas + * attribute’s list. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.6.4 + */ + currentArea: OptionalAttribute(0x3, TlvNullable(TlvUInt32), { default: null }), + + /** + * Indicates the estimated Epoch time for completing operating at the area indicated by the CurrentArea + * attribute, in seconds. + * + * A value of 0 means that the operation has completed. + * + * When this attribute is null, that represents that there is no time currently defined until operation + * completion. This may happen, for example, because no operation is in progress or because the completion + * time is unknown. + * + * Null if the CurrentArea attribute is null. + * + * If the Progress attribute is available, and it contains an entry matching CurrentArea, the server may + * use the time estimate provided in the InitialTimeEstimate field of that entry to compute the + * EstimatedEndTime attribute. + * + * The value of this attribute shall only be reported in the following cases: + * + * • when it changes to or from 0 + * + * • when it decreases + * + * • when it changes to or from null + * + * NOTE + * + * If the device is capable of pausing its operation, this attribute may be set to null, to indicate that + * completion time is unknown, or increment the value while being in the paused state. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.6.5 + */ + estimatedEndTime: Attribute(0x4, TlvNullable(TlvEpochS), { default: null }) + }, + + commands: { + /** + * This command is used to select a set of device areas, where the device is to operate. + * + * On receipt of this command the device shall respond with a SelectAreasResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.1 + */ + selectAreas: Command(0x0, TlvSelectAreasRequest, 0x1, TlvSelectAreasResponse), + + /** + * This command is used to skip the given area, and to attempt operating at other areas on the + * SupportedAreas attribute list. + * + * This command shall NOT be implemented if the CurrentArea attribute and the Progress attribute are both + * not implemented. Else, this command shall be optionally implemented. + * + * On receipt of this command the device shall respond with a SkipAreaResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17.7.3 + */ + skipArea: OptionalCommand(0x2, TlvSkipAreaRequest, 0x3, TlvSkipAreaResponse) + }, + + /** + * This metadata controls which ServiceAreaCluster elements matter.js activates for specific feature + * combinations. + */ + extensions: MutableCluster.Extensions( + { flags: { maps: true }, component: MapsComponent }, + { flags: { progressReporting: true }, component: ProgressReportingComponent } + ) + }); + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster(Base); + + /** + * This cluster provides an interface for controlling the areas where a device should operate, for reporting the + * status at each area, and for querying the current area. + * + * The device may operate at one area at a time, as in the case of a mobile device, such as a robot. Other devices + * may operate at (service) multiple areas simultaneously, as in the case of a sensor that can monitor multiple + * areas. This cluster specification uses the term "operate" to describe both the operating and servicing actions, + * regardless of the device type. + * + * The cluster allows the client to select one or more areas on the server, to indicate where the device SHOULD + * attempt to operate. An area is one of a list of options that may be presented by a client for a user choice, or + * understood by the client, via the semantic data of the area. + * + * The area semantic data is a combination of semantic tags, indicating one or more of the following: the building + * floor, area type, landmark, and relative position. + * + * ServiceAreaCluster supports optional features that you can enable with the ServiceAreaCluster.with() factory + * method. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.17 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + const MAPS = { maps: true }; + const PROG = { progressReporting: true }; + + /** + * @see {@link Complete} + */ + export const CompleteInstance = MutableCluster({ + id: Cluster.id, + name: Cluster.name, + revision: Cluster.revision, + features: Cluster.features, + + attributes: { + ...Cluster.attributes, + supportedMaps: MutableCluster.AsConditional( + MapsComponent.attributes.supportedMaps, + { mandatoryIf: [MAPS] } + ), + progress: MutableCluster.AsConditional( + ProgressReportingComponent.attributes.progress, + { mandatoryIf: [PROG] } + ) + }, + + commands: Cluster.commands + }); + + /** + * This cluster supports all ServiceArea features. It may support illegal feature combinations. + * + * If you use this cluster you must manually specify which features are active and ensure the set of active + * features is legal per the Matter specification. + */ + export interface Complete extends Identity {} + + export const Complete: Complete = CompleteInstance; +} + +export type ServiceAreaCluster = ServiceArea.Cluster; +export const ServiceAreaCluster = ServiceArea.Cluster; +ClusterRegistry.register(ServiceArea.Complete); diff --git a/packages/types/src/clusters/smoke-co-alarm.ts b/packages/types/src/clusters/smoke-co-alarm.ts index d2d7f589fc..f3c4520093 100644 --- a/packages/types/src/clusters/smoke-co-alarm.ts +++ b/packages/types/src/clusters/smoke-co-alarm.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -85,16 +85,13 @@ export namespace SmokeCoAlarm { } /** + * This value shall indicate that the smoke sensor has nominal contamination levels, no customer action is required. + * * @see {@link MatterSpecification.v13.Cluster} § 2.11.5.6 */ export enum ContaminationState { /** * Nominal state, the sensor is not contaminated - * - * This value shall indicate that the smoke sensor has nominal contamination levels, no customer action is - * required. - * - * @see {@link MatterSpecification.v13.Cluster} § 2.11.5.6.1 */ Normal = 0, @@ -235,15 +232,13 @@ export namespace SmokeCoAlarm { export interface InterconnectCoAlarmEvent extends TypeFromSchema {} /** + * This value shall indicate that this alarm is not alarming. + * * @see {@link MatterSpecification.v13.Cluster} § 2.11.5.3 */ export enum ExpressedState { /** * Nominal state, the device is not alarming - * - * This value shall indicate that this alarm is not alarming. - * - * @see {@link MatterSpecification.v13.Cluster} § 2.11.5.3.1 */ Normal = 0, @@ -599,9 +594,8 @@ export namespace SmokeCoAlarm { /** * This command shall initiate a device self-test. The return status shall indicate whether the test was * successfully initiated. Only one SelfTestRequest may be processed at a time. When the value of the - * ExpressedState attribute is any of SmokeAlarm, COAlarm, Testing, InterconnectSmoke, Inter - * - * connectCO, the device shall NOT execute the self-test, and shall return status code BUSY. + * ExpressedState attribute is any of SmokeAlarm, COAlarm, Testing, InterconnectSmoke, InterconnectCO, the + * device shall NOT execute the self-test, and shall return status code BUSY. * * Upon successful acceptance of SelfTestRequest, the TestInProgress attribute shall be set to True and * ExpressedState attribute shall be set to Testing. Any faults identified during the test shall be diff --git a/packages/types/src/clusters/software-diagnostics.ts b/packages/types/src/clusters/software-diagnostics.ts index bda0f1e141..063e6855a2 100644 --- a/packages/types/src/clusters/software-diagnostics.ts +++ b/packages/types/src/clusters/software-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/switch.ts b/packages/types/src/clusters/switch.ts index 945f8bf1bc..c7faa1cc48 100644 --- a/packages/types/src/clusters/switch.ts +++ b/packages/types/src/clusters/switch.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -25,7 +25,7 @@ export namespace Switch { /** * LatchingSwitch (LS) * - * This feature is for a switch that maintains its position after being pressed (or turned). + * This feature flag is for a switch that maintains its position after being pressed (or turned). * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.1 */ @@ -34,7 +34,7 @@ export namespace Switch { /** * MomentarySwitch (MS) * - * This feature is for a switch that does not maintain its position after being pressed (or turned). After + * This feature flag is for a switch that does not maintain its position after being pressed (or turned). After * releasing, it goes back to its idle position. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.2 @@ -44,8 +44,7 @@ export namespace Switch { /** * MomentarySwitchRelease (MSR) * - * This feature is for a momentary switch that can distinguish and report release events. When this feature - * flag MSR is present, MS shall be present as well. + * This feature flag is for a momentary switch that can distinguish and report release events. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.3 */ @@ -54,8 +53,7 @@ export namespace Switch { /** * MomentarySwitchLongPress (MSL) * - * This feature is for a momentary switch that can distinguish and report long presses from short presses. When - * this feature flag MSL is present, MS and MSR shall be present as well. + * This feature flag is for a momentary switch that can distinguish and report long presses from short presses. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.4 */ @@ -64,48 +62,23 @@ export namespace Switch { /** * MomentarySwitchMultiPress (MSM) * - * This feature is for a momentary switch that can distinguish and report double press and potentially multiple - * presses with more events, such as triple press, etc. When this feature flag MSM is present, MS and MSR shall - * be present as well. + * This feature flag is for a momentary switch that can distinguish and report double press and potentially + * multiple presses with more events, such as triple press, etc. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.5 */ - MomentarySwitchMultiPress = "MomentarySwitchMultiPress" - } - - /** - * Body of the Switch multiPressOngoing event - * - * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6 - */ - export const TlvMultiPressOngoingEvent = TlvObject({ - /** - * This field shall indicate the new value of the CurrentPosition attribute, i.e. while pressed. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6.1 - */ - newPosition: TlvField(0, TlvUInt8), + MomentarySwitchMultiPress = "MomentarySwitchMultiPress", /** - * This field shall contain: - * - * • a value of 2 when the second press of a multi-press sequence has been detected, + * ActionSwitch (AS) * - * • a value of 3 when the third press of a multi-press sequence has been detected, + * This feature flag indicates simplified handling of events for multi-press-capable switches. See Multi Press + * Details. * - * • a value of N when the Nth press of a multi-press sequence has been detected. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6.2 + * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.6 */ - currentNumberOfPressesCounted: TlvField(1, TlvUInt8.bound({ min: 2 })) - }); - - /** - * Body of the Switch multiPressOngoing event - * - * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6 - */ - export interface MultiPressOngoingEvent extends TypeFromSchema {} + ActionSwitch = "ActionSwitch" + } /** * Body of the Switch multiPressComplete event @@ -114,7 +87,7 @@ export namespace Switch { */ export const TlvMultiPressCompleteEvent = TlvObject({ previousPosition: TlvField(0, TlvUInt8), - totalNumberOfPressesCounted: TlvField(1, TlvUInt8.bound({ min: 1 })) + totalNumberOfPressesCounted: TlvField(1, TlvUInt8) }); /** @@ -229,6 +202,40 @@ export namespace Switch { */ export interface ShortReleaseEvent extends TypeFromSchema {} + /** + * Body of the Switch multiPressOngoing event + * + * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6 + */ + export const TlvMultiPressOngoingEvent = TlvObject({ + /** + * This field shall indicate the new value of the CurrentPosition attribute, i.e. while pressed. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6.1 + */ + newPosition: TlvField(0, TlvUInt8), + + /** + * This field shall contain: + * + * • a value of 2 when the second press of a multi-press sequence has been detected, + * + * • a value of 3 when the third press of a multi-press sequence has been detected, + * + * • a value of N when the Nth press of a multi-press sequence has been detected. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6.2 + */ + currentNumberOfPressesCounted: TlvField(1, TlvUInt8.bound({ min: 2 })) + }); + + /** + * Body of the Switch multiPressOngoing event + * + * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6 + */ + export interface MultiPressOngoingEvent extends TypeFromSchema {} + /** * A SwitchCluster supports these elements if it supports feature MomentarySwitchMultiPress. */ @@ -236,8 +243,26 @@ export namespace Switch { attributes: { /** * Indicates how many consecutive presses can be detected and reported by a momentary switch which supports - * multi-press (e.g. it will report the value 3 if it can detect single press, double press and triple - * press, but not quad press and beyond). + * multi-press (MSM feature flag set). + * + * For example, a momentary switch supporting single press, double press and triple press, but not quad + * press and beyond, would return the value 3. + * + * When more than MultiPressMax presses are detected within a multi-press sequence: + * + * • The server for cluster revision < 2 SHOULD generate a MultiPressComplete event with the + * TotalNumberOfPressesCounted field set to the value of the MultiPressMax attribute, and avoid + * generating any further InitialPress and MultiPressOngoing events until the switch has become fully + * idle (i.e. no longer in the process of counting presses within the multipress). + * + * • The server for cluster revision >= 2 shall generate a MultiPressComplete event with the + * TotalNumberOfPressesCounted field set to zero (indicating an aborted sequence), and shall NOT + * generate any further InitialPress and MultiPressOngoing events until the switch has become fully + * idle (i.e. no longer in the process of counting presses within the multipress). + * + * This approach avoids unintentionally causing intermediate actions where there is a very long sequence of + * presses beyond MultiPressMax that may be taken in account specially by switches (e.g. to trigger special + * behavior such as factory reset for which generating events towards the client is not appropriate). * * @see {@link MatterSpecification.v13.Cluster} § 1.13.5.3 */ @@ -245,14 +270,6 @@ export namespace Switch { }, events: { - /** - * This event shall be generated to indicate how many times the momentary switch has been pressed in a - * multi-press sequence, during that sequence. See Multi Press Details below. - * - * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6 - */ - multiPressOngoing: Event(0x5, EventPriority.Info, TlvMultiPressOngoingEvent), - /** * This event shall be generated to indicate how many times the momentary switch has been pressed in a * multi-press sequence, after it has been detected that the sequence has ended. See Multi Press Details. @@ -262,9 +279,11 @@ export namespace Switch { * * The TotalNumberOfPressesCounted field shall contain: * - * • a value of 1 when there was one press in a multi-press sequence (and the sequence has ended), + * • a value of 0 when there was an aborted multi-press sequence, where the number of presses goes beyond + * MultiPressMax presses, * - * i.e. there was no double press (or more), + * • a value of 1 when there was exactly one press in a multi-press sequence (and the sequence has + * ended), i.e. there was no double press (or more), * * • a value of 2 when there were exactly two presses in a multi-press sequence (and the sequence has * ended), @@ -275,6 +294,14 @@ export namespace Switch { * • a value of N when there were exactly N presses in a multi-press sequence (and the sequence has * ended). * + * NOTE + * + * The introduction of TotalNumberOfPressesCounted supporting the value 0 may impact clients of switches + * using cluster revision 1 since such servers would not use this value of TotalNumberOfPressesCounted to + * indicate an aborted sequence. Clients SHOULD always act using the TotalNumberOfPressesCounted field + * taken into account since for values from 1 to MultiPressMax, the user action that led to the event was + * different depending on the count. + * * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.7 */ multiPressComplete: Event(0x6, EventPriority.Info, TlvMultiPressCompleteEvent) @@ -316,8 +343,36 @@ export namespace Switch { export const MomentarySwitchLongPressComponent = MutableCluster.Component({ events: { /** - * This event shall be generated, when the momentary switch has been pressed for a "long" time (this time - * interval is manufacturer determined (e.g. since it depends on the switch physics)). + * This event shall be generated when the momentary switch has been pressed for a "long" time. The time + * interval constituting a "long" time is manufacturer-determined, since it depends on the switch physics. + * + * • When the AS feature flag is set, this event: + * + * ◦ shall NOT be generated during a multi-press sequence (since a long press is a separate cycle from + * any multi-press cycles); + * + * ◦ shall only be generated after the first InitialPress following a MultiPressComplete when a long + * press is detected after the idle time. + * + * • Else, when the MSM feature flag is set, this event: + * + * ◦ shall NOT be generated during a multi-press sequence (since a long press is a separate cycle from + * any multi-press cycles); + * + * ◦ shall only be generated after the first InitialPress following a MultiPressComplete when a long + * press is detected after the idle time; + * + * ◦ shall NOT be generated after a MultiPressOngoing event without an intervening MultiPressComplete + * event. + * + * The above constraints imply that for a given activity detection cycle of a switch having MSM and/or MSL + * feature flags set, the entire activity is either a single long press detection cycle of (InitialPress, + * LongPress, LongRelease), or a single multi-press detection cycle (ending in MultiPressComplete), where + * presses that would otherwise be reported as long presses are instead reported as a counted press in the + * MultiPressComplete event, and as InitialPress/ShortRelease pairs otherwise (where applicable). + * + * The rationale for this constraint is the ambiguity of interpretation of events when mixing long presses + * and multi-press events. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.3 */ @@ -341,14 +396,19 @@ export namespace Switch { export const MomentarySwitchReleaseComponent = MutableCluster.Component({ events: { /** + * If the server has the Action Switch (AS) feature flag set, this event shall NOT be generated at all, + * since setting the Action Switch feature flag forbids the Momentary Switch ShortRelease (MSR) feature + * flag from being set. Otherwise, the following paragraphs describe the situations where this event is + * generated. + * * This event shall be generated, when the momentary switch has been released (after debouncing). * - * • If the server supports the Momentary Switch LongPress (MSL) feature, this event shall be generated - * when the switch is released if no LongPress event had been generated since the previous InitialPress - * event. + * • If the server has the Momentary Switch LongPress (MSL) feature flag set, then this event shall be + * generated when the switch is released if no LongPress event had been generated since the previous + * InitialPress event. * - * • If the server does not support the Momentary Switch LongPress (MSL) feature, this event shall be - * generated when the switch is released - even when the switch was pressed for a long time. + * • If the server does not have the Momentary Switch LongPress (MSL) feature flag set, this event shall + * be generated when the switch is released - even when the switch was pressed for a long time. * * • Also see Section 1.13.7, “Sequence of generated events”. * @@ -358,19 +418,38 @@ export namespace Switch { } }); + /** + * A SwitchCluster supports these elements if it supports feature MomentarySwitchMultiPress and it doesn't support + * feature AS. + */ + export const MomentarySwitchMultiPressNotActionSwitchComponent = MutableCluster.Component({ + events: { + /** + * If the server has the Action Switch (AS) feature flag set, this event shall NOT be generated at all. + * Otherwise, the following paragraphs describe the situations where this event is generated. + * + * This event shall be generated to indicate how many times the momentary switch has been pressed in a + * multi-press sequence, during that sequence. See Multi Press Details below. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.13.6.6 + */ + multiPressOngoing: Event(0x5, EventPriority.Info, TlvMultiPressOngoingEvent) + } + }); + /** * These elements and properties are present in all Switch clusters. */ export const Base = MutableCluster.Component({ id: 0x3b, name: "Switch", - revision: 1, + revision: 2, features: { /** * LatchingSwitch * - * This feature is for a switch that maintains its position after being pressed (or turned). + * This feature flag is for a switch that maintains its position after being pressed (or turned). * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.1 */ @@ -379,8 +458,8 @@ export namespace Switch { /** * MomentarySwitch * - * This feature is for a switch that does not maintain its position after being pressed (or turned). After - * releasing, it goes back to its idle position. + * This feature flag is for a switch that does not maintain its position after being pressed (or turned). + * After releasing, it goes back to its idle position. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.2 */ @@ -389,8 +468,7 @@ export namespace Switch { /** * MomentarySwitchRelease * - * This feature is for a momentary switch that can distinguish and report release events. When this feature - * flag MSR is present, MS shall be present as well. + * This feature flag is for a momentary switch that can distinguish and report release events. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.3 */ @@ -399,8 +477,8 @@ export namespace Switch { /** * MomentarySwitchLongPress * - * This feature is for a momentary switch that can distinguish and report long presses from short presses. - * When this feature flag MSL is present, MS and MSR shall be present as well. + * This feature flag is for a momentary switch that can distinguish and report long presses from short + * presses. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.4 */ @@ -409,13 +487,22 @@ export namespace Switch { /** * MomentarySwitchMultiPress * - * This feature is for a momentary switch that can distinguish and report double press and potentially - * multiple presses with more events, such as triple press, etc. When this feature flag MSM is present, MS - * and MSR shall be present as well. + * This feature flag is for a momentary switch that can distinguish and report double press and potentially + * multiple presses with more events, such as triple press, etc. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.5 */ - momentarySwitchMultiPress: BitFlag(4) + momentarySwitchMultiPress: BitFlag(4), + + /** + * ActionSwitch + * + * This feature flag indicates simplified handling of events for multi-press-capable switches. See Multi + * Press Details. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.13.4.6 + */ + actionSwitch: BitFlag(5) }, attributes: { @@ -428,9 +515,10 @@ export namespace Switch { numberOfPositions: FixedAttribute(0x0, TlvUInt8.bound({ min: 2 }), { default: 2 }), /** - * Indicates the position of the switch. The valid range is zero to NumberOfPositions-1. CurrentPosition - * value 0 shall be assigned to the default position of the switch: for example the "open" state of a - * rocker switch, or the "idle" state of a push button switch. + * Indicates the position of the switch. The valid range is zero to NumberOfPositions - 1. + * + * CurrentPosition value 0 shall be assigned to the default position of the switch: for example the "open" + * state of a rocker switch, or the "idle" state of a push button switch. * * @see {@link MatterSpecification.v13.Cluster} § 1.13.5.2 */ @@ -446,11 +534,21 @@ export namespace Switch { { flags: { momentarySwitch: true }, component: MomentarySwitchComponent }, { flags: { momentarySwitchLongPress: true }, component: MomentarySwitchLongPressComponent }, { flags: { momentarySwitchRelease: true }, component: MomentarySwitchReleaseComponent }, + { + flags: { momentarySwitchMultiPress: true, actionSwitch: false }, + component: MomentarySwitchMultiPressNotActionSwitchComponent + }, { flags: { momentarySwitchRelease: true, momentarySwitch: false }, component: false }, + { flags: { momentarySwitchRelease: true, actionSwitch: true }, component: false }, { flags: { momentarySwitchLongPress: true, momentarySwitch: false }, component: false }, - { flags: { momentarySwitchLongPress: true, momentarySwitchRelease: false }, component: false }, + { + flags: { momentarySwitchLongPress: true, momentarySwitchRelease: false, actionSwitch: false }, + component: false + }, + { flags: { actionSwitch: true, momentarySwitchMultiPress: false }, component: false }, { flags: { momentarySwitchMultiPress: true, momentarySwitch: false }, component: false }, { flags: { momentarySwitchMultiPress: true, momentarySwitchRelease: false }, component: false }, + { flags: { actionSwitch: true, momentarySwitch: false }, component: false }, { flags: { latchingSwitch: true, momentarySwitch: true }, component: false }, { flags: { latchingSwitch: false, momentarySwitch: false }, component: false } ) @@ -488,6 +586,7 @@ export namespace Switch { const MS = { momentarySwitch: true }; const MSL = { momentarySwitchLongPress: true }; const MSR = { momentarySwitchRelease: true }; + const MSM_NOT_AS = { momentarySwitchMultiPress: true, actionSwitch: false }; /** * @see {@link Complete} @@ -528,8 +627,8 @@ export namespace Switch { { mandatoryIf: [MSL] } ), multiPressOngoing: MutableCluster.AsConditional( - MomentarySwitchMultiPressComponent.events.multiPressOngoing, - { mandatoryIf: [MSM] } + MomentarySwitchMultiPressNotActionSwitchComponent.events.multiPressOngoing, + { mandatoryIf: [MSM_NOT_AS] } ), multiPressComplete: MutableCluster.AsConditional( MomentarySwitchMultiPressComponent.events.multiPressComplete, diff --git a/packages/types/src/clusters/target-navigator.ts b/packages/types/src/clusters/target-navigator.ts index 06bda74bae..884b79abb8 100644 --- a/packages/types/src/clusters/target-navigator.ts +++ b/packages/types/src/clusters/target-navigator.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -151,7 +151,7 @@ export namespace TargetNavigator { attributes: { /** * Indicates a list of targets that can be navigated to within the experience presented to the user by the - * Endpoint (Video Player or Content App). The list shall not contain any entries with the same Identifier + * Endpoint (Video Player or Content App). The list shall NOT contain any entries with the same Identifier * in the TargetInfoStruct object. * * @see {@link MatterSpecification.v13.Cluster} § 6.11.5.1 diff --git a/packages/types/src/clusters/temperature-control.ts b/packages/types/src/clusters/temperature-control.ts index 3f27c81f15..dd2585970a 100644 --- a/packages/types/src/clusters/temperature-control.ts +++ b/packages/types/src/clusters/temperature-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/temperature-measurement.ts b/packages/types/src/clusters/temperature-measurement.ts index de103f420b..da692e6fab 100644 --- a/packages/types/src/clusters/temperature-measurement.ts +++ b/packages/types/src/clusters/temperature-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/thermostat-user-interface-configuration.ts b/packages/types/src/clusters/thermostat-user-interface-configuration.ts index a14c3c83fe..101703e12e 100644 --- a/packages/types/src/clusters/thermostat-user-interface-configuration.ts +++ b/packages/types/src/clusters/thermostat-user-interface-configuration.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/thermostat.ts b/packages/types/src/clusters/thermostat.ts index 5dcd0e333a..88f2cbb05b 100644 --- a/packages/types/src/clusters/thermostat.ts +++ b/packages/types/src/clusters/thermostat.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -21,11 +21,13 @@ import { OccupancySensing } from "./occupancy-sensing.js"; import { TlvUInt8, TlvBitmap, TlvInt16, TlvInt8, TlvEnum, TlvUInt16, TlvEpochS, TlvUInt32 } from "../tlv/TlvNumber.js"; import { BitsFromPartial, BitFlag, BitField } from "../schema/BitmapSchema.js"; import { AccessLevel } from "#model"; -import { TlvField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js"; import { TlvArray } from "../tlv/TlvArray.js"; import { TlvNullable } from "../tlv/TlvNullable.js"; import { TypeFromSchema } from "../tlv/TlvSchema.js"; import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; +import { TlvByteString, TlvString } from "../tlv/TlvString.js"; +import { TlvBoolean } from "../tlv/TlvBoolean.js"; import { Identity } from "#general"; import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; @@ -87,11 +89,25 @@ export namespace Thermostat { * * @see {@link MatterSpecification.v13.Cluster} § 4.3.4.1 */ - LocalTemperatureNotExposed = "LocalTemperatureNotExposed" + LocalTemperatureNotExposed = "LocalTemperatureNotExposed", + + /** + * MatterScheduleConfiguration (MSCH) + * + * Supports enhanced schedules + */ + MatterScheduleConfiguration = "MatterScheduleConfiguration", + + /** + * Presets (PRES) + * + * Thermostat supports setpoint presets + */ + Presets = "Presets" } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.26 */ export enum ThermostatRunningMode { /** @@ -111,7 +127,7 @@ export namespace Thermostat { } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.20 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.24 */ export enum StartOfWeek { Sunday = 0, @@ -124,7 +140,7 @@ export namespace Thermostat { } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.10 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.13 */ export const ScheduleDayOfWeek = { /** @@ -169,7 +185,7 @@ export namespace Thermostat { }; /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.11 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.14 */ export const ScheduleMode = { /** @@ -186,7 +202,7 @@ export namespace Thermostat { /** * This represents a single transition in a Thermostat schedule * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.24 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.30 */ export const TlvWeeklyScheduleTransition = TlvObject({ /** @@ -195,21 +211,21 @@ export namespace Thermostat { * will be represented by 360 minutes since midnight and 11:30pm will be represented by 1410 minutes since * midnight. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.24.1 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.30.1 */ transitionTime: TlvField(0, TlvUInt16.bound({ max: 1439 })), /** * This field shall represent the heat setpoint to be applied at this associated transition start time. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.24.2 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.30.2 */ heatSetpoint: TlvField(1, TlvNullable(TlvInt16)), /** * This field shall represent the cool setpoint to be applied at this associated transition start time. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.24.3 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.30.3 */ coolSetpoint: TlvField(2, TlvNullable(TlvInt16)) }); @@ -217,14 +233,14 @@ export namespace Thermostat { /** * This represents a single transition in a Thermostat schedule * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.24 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.30 */ export interface WeeklyScheduleTransition extends TypeFromSchema {} /** * Input to the Thermostat setWeeklySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.2 */ export const TlvSetWeeklyScheduleRequest = TlvObject({ /** @@ -232,7 +248,7 @@ export namespace Thermostat { * device supports more than 10 transitions in its schedule they can send this by sending more than 1 “Set * Weekly Schedule” command, each containing the separate information that the device needs to set. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4.1 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.2.1 */ numberOfTransitionsForSequence: TlvField(0, TlvUInt8), @@ -245,7 +261,7 @@ export namespace Thermostat { * Each setpoint transition will begin with the day of week for this transition. There can be up to 10 * transitions for each command. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4.2 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.2.2 */ dayOfWeekForSequence: TlvField(1, TlvBitmap(TlvUInt8, ScheduleDayOfWeek)), @@ -270,14 +286,14 @@ export namespace Thermostat { * Both bits must be respected, even if the HEAT or COOL feature is not supported, to ensure the command is * decoded and handled correctly. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4.3 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.2.3 */ modeForSequence: TlvField(2, TlvBitmap(TlvUInt8, ScheduleMode)), /** * This field shall contain the list of setpoint transitions used to update the specified daily schedules * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4.4 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.2.4 */ transitions: TlvField(3, TlvArray(TlvWeeklyScheduleTransition, { maxLength: 10 })) }); @@ -285,21 +301,21 @@ export namespace Thermostat { /** * Input to the Thermostat setWeeklySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.2 */ export interface SetWeeklyScheduleRequest extends TypeFromSchema {} /** * Input to the Thermostat getWeeklySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.5 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.3 */ export const TlvGetWeeklyScheduleRequest = TlvObject({ /** * This field shall indicate the number of days the client would like to return the setpoint values for and * could be any combination of single days or the entire week. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.5.1 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.3.1 */ daysToReturn: TlvField(0, TlvBitmap(TlvUInt8, ScheduleDayOfWeek)), @@ -307,7 +323,7 @@ export namespace Thermostat { * This field shall indicate the mode the client would like to return the set point values for and could be any * combination of heat only, cool only or heat & cool. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.5.2 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.3.2 */ modeToReturn: TlvField(1, TlvBitmap(TlvUInt8, ScheduleMode)) }); @@ -315,14 +331,14 @@ export namespace Thermostat { /** * Input to the Thermostat getWeeklySchedule command * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.5 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.3 */ export interface GetWeeklyScheduleRequest extends TypeFromSchema {} /** * This command has the same payload format as the Set Weekly Schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.6 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4 */ export const TlvGetWeeklyScheduleResponse = TlvObject({ numberOfTransitionsForSequence: TlvField(0, TlvUInt8), @@ -334,10 +350,611 @@ export namespace Thermostat { /** * This command has the same payload format as the Set Weekly Schedule. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.6 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4 */ export interface GetWeeklyScheduleResponse extends TypeFromSchema {} + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22 + */ + export enum PresetScenario { + /** + * The thermostat-controlled area is occupied + * + * This value shall indicate the preset for periods when the thermostat’s temperature-controlled area is + * occupied. It is intended for thermostats that can automatically determine occupancy. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22.2 + */ + Occupied = 1, + + /** + * The thermostat-controlled area is unoccupied + * + * This value shall indicate the preset for periods when the thermostat’s temperature-controlled area is + * unoccupied. It is intended for thermostats that can automatically determine occupancy. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22.3 + */ + Unoccupied = 2, + + /** + * Users are likely to be sleeping + * + * This value shall indicate the preset for periods when users are likely to be asleep. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22.4 + */ + Sleep = 3, + + /** + * Users are likely to be waking up + * + * This value shall indicate the preset for periods when users are likely to be waking up. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22.5 + */ + Wake = 4, + + /** + * Users are on vacation + * + * This value shall indicate the preset for periods when users are on vacation, or otherwise out-of- home for + * extended periods of time. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22.6 + */ + Vacation = 5, + + /** + * Users are likely to be going to sleep + * + * This value shall indicate the preset for periods when users are likely to be going to sleep. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22.7 + */ + GoingToSleep = 6, + + /** + * Custom presets + * + * This value shall indicate a free-form preset; when set, the Name field on PresetStruct shall NOT be null. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.22.8 + */ + UserDefined = 254 + } + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.8 + */ + export const PresetTypeFeatures = { + /** + * Preset may be automatically activated by the thermostat + */ + automatic: BitFlag(0), + + /** + * Preset supports user- provided names + */ + supportsNames: BitFlag(1) + }; + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.29 + */ + export const TlvPresetType = TlvObject({ + /** + * This field shall specify a PresetScenarioEnum value supported by this thermostat. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.29.1 + */ + presetScenario: TlvField(0, TlvEnum()), + + /** + * This field shall specify a limit for the number of presets for this PresetScenarioEnum. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.29.2 + */ + numberOfPresets: TlvField(1, TlvUInt8), + + /** + * This field shall specify a bitmap of features for this PresetTypeStruct. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.29.3 + */ + presetTypeFeatures: TlvField(2, TlvBitmap(TlvUInt16, PresetTypeFeatures)) + }); + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.29 + */ + export interface PresetType extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.28 + */ + export const TlvPreset = TlvObject({ + /** + * This field shall indicate a device generated identifier for this preset. It shall be unique on the device, + * and shall NOT be reused after the associated preset has been deleted. + * + * This field shall only be null when the encompassing PresetStruct is appended to the Presets attribute for + * the purpose of creating a new Preset. Refer to Presets for the creation of Preset handles. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.28.1 + */ + presetHandle: TlvField(0, TlvNullable(TlvByteString.bound({ maxLength: 16 }))), + + /** + * This field shall indicate the associated PresetScenarioEnum value for this preset. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.28.2 + */ + presetScenario: TlvField(1, TlvEnum()), + + /** + * This field shall indicate a name provided by a user. The null value shall indicate no name. + * + * Within each subset of presets sharing the same PresetScenario field value, there shall NOT be any presets + * with the same value, including null as a value, in the Name field. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.28.3 + */ + name: TlvOptionalField(2, TlvNullable(TlvString.bound({ maxLength: 64 }))), + + /** + * This field shall indicate the cooling setpoint for the preset. Refer to Setpoint Limits for value + * constraints. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.28.4 + */ + coolingSetpoint: TlvOptionalField(3, TlvInt16), + + /** + * This field shall indicate the heating setpoint for the preset. Refer to Setpoint Limits for value + * constraints. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.28.5 + */ + heatingSetpoint: TlvOptionalField(4, TlvInt16), + + /** + * This field shall indicate whether the preset is marked as "built-in", meaning that it can be modified, but + * it cannot be deleted. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.28.6 + */ + builtIn: TlvField(5, TlvNullable(TlvBoolean)) + }); + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.28 + */ + export interface Preset extends TypeFromSchema {} + + /** + * Input to the Thermostat setActivePresetRequest command + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.9 + */ + export const TlvSetActivePresetRequest = TlvObject({ + /** + * This field shall specify the value of the PresetHandle field on the PresetStruct to be made active. If the + * field is set to null, that indicates there should be no active preset. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.9.1 + */ + presetHandle: TlvField(0, TlvNullable(TlvByteString.bound({ maxLength: 16 }))) + }); + + /** + * Input to the Thermostat setActivePresetRequest command + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.9 + */ + export interface SetActivePresetRequest extends TypeFromSchema {} + + /** + * Table 9. Interpretation of Heat, Cool and Auto SystemModeEnum Values + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.25 + */ + export enum SystemMode { + /** + * The Thermostat does not generate demand for Cooling or Heating + */ + Off = 0, + + /** + * Demand is generated for either Cooling or Heating, as required + */ + Auto = 1, + + /** + * Demand is only generated for Cooling + */ + Cool = 3, + + /** + * Demand is only generated for Heating + */ + Heat = 4, + + /** + * 2nd stage heating is in use to achieve desired temperature + */ + EmergencyHeat = 5, + + /** + * (see Terms) + */ + Precooling = 6, + + FanOnly = 7, + Dry = 8, + Sleep = 9 + } + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.12 + */ + export const ScheduleTypeFeatures = { + /** + * Supports presets + * + * This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the SystemMode + * field on the encompassing ScheduleTypeStruct supports specifying presets on ScheduleTransitionStructs + * contained in its Transitions field. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.12.1 + */ + supportsPresets: BitFlag(0), + + /** + * Supports setpoints + * + * This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the SystemMode + * field on the encompassing ScheduleTypeStruct supports specifying setpoints on ScheduleTransitionStructs + * contained in its Transitions field. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.12.2 + */ + supportsSetpoints: BitFlag(1), + + /** + * Supports user-provided names + * + * This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the SystemMode + * field on the encompassing ScheduleTypeStruct supports setting the value of the Name field. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.12.3 + */ + supportsNames: BitFlag(2), + + /** + * Supports transitioning to SystemModeOff + * + * This bit shall indicate that any ScheduleStruct with a SystemMode field whose value matches the SystemMode + * field on the encompassing ScheduleTypeStruct supports setting its SystemMode field to Off. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.12.4 + */ + supportsOff: BitFlag(3) + }; + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.33 + */ + export const TlvScheduleType = TlvObject({ + /** + * This field shall specify a SystemModeEnum supported by this thermostat for Schedules. The only valid values + * for this field shall be Auto, Heat, and Cool. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.33.1 + */ + systemMode: TlvField(0, TlvEnum()), + + /** + * This field shall specify a limit for the number of Schedules for this SystemMode. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.33.2 + */ + numberOfSchedules: TlvField(1, TlvUInt8), + + /** + * This field shall specify a bitmap of features for this schedule entry. At least one of SupportsPresets and + * SupportsSetpoints shall be set. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.33.3 + */ + scheduleTypeFeatures: TlvField(2, TlvBitmap(TlvUInt16, ScheduleTypeFeatures)) + }); + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.33 + */ + export interface ScheduleType extends TypeFromSchema {} + + /** + * This struct provides a time of day and a set of days of the week for a state transition within a schedule. The + * thermostat shall use the following order of precedence for determining a new setpoint at the time of transition: + * + * 1. If the PresetHandle field is provided, then the setpoint for the PresetStruct in the Presets attribute with + * that identifier shall be used + * + * 2. If either the HeatingSetpoint or CoolingSetpoint is provided, then it shall be used + * + * a. If the SystemMode field is provided, the HeatingSetpoint and CoolingSetpoint fields shall be interpreted + * using the SystemMode field + * + * b. If the SystemMode field is not provided, the HeatingSetpoint and CoolingSetpoint fields shall be + * interpreted using the SystemMode field on the parent ScheduleStruct + * + * 3. If neither the PresetHandle field or any Setpoint field is provided, then the PresetHandle field on the + * parent ScheduleStruct shall be used to determine the active PresetStruct + * + * 4. If the PresetHandle is not indicated and no setpoint is provided for the current SystemMode, the server + * shall use a default value for the current SystemMode. + * + * If the setpoint was derived from a preset, then the ActivePresetHandle shall be set to the PresetHandle of that + * preset. + * + * If a CoolingSetpoint was used to determine the cooling setpoint: + * + * • If the server supports the OCC feature, and the Occupied bit is not set on the Occupancy attribute, then the + * UnoccupiedCoolingSetpoint attribute shall be set to the CoolingSetpoint + * + * • Otherwise, the OccupiedCoolingSetpoint attribute shall be set to the CoolingSetpoint If a HeatingSetpoint + * was used to determine the heating setpoint: + * + * • If the server supports the OCC feature, and the Occupied bit is not set on the Occupancy attribute, then the + * UnoccupiedHeatingSetpoint attribute shall be set to the HeatingSetpoint + * + * • Otherwise, the OccupiedHeatingSetpoint attribute shall be set to the HeatingSetpoint The + * ScheduleTransitionStruct shall be invalid if all the following are true: + * + * • The HeatingSetpoint field is not provided + * + * • The PresetHandle field is not provided + * + * • The PresetHandle field on the encompassing ScheduleStruct is not provided + * + * • The SystemMode field is provided and has the value Heat or Auto, or the SystemMode field on the parent + * ScheduleStruct has the value Heat or Auto + * + * The ScheduleTransitionStruct shall be invalid if all the following are true: + * + * • The CoolingSetpoint field is not provided + * + * • The PresetHandle field is not provided + * + * • The PresetHandle field on the encompassing ScheduleStruct is not provided + * + * • The SystemMode field is provided and has the value Cool or Auto, or the SystemMode field on the parent + * ScheduleStruct has the value Cool or Auto + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.32 + */ + export const TlvScheduleTransition = TlvObject({ + /** + * This field shall specify a bitmask of days of the week that the transition applies to. The Vacation bit + * shall NOT be set; vacation schedules shall be set via the vacation preset. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.32.1 + */ + dayOfWeek: TlvField(0, TlvBitmap(TlvUInt8, ScheduleDayOfWeek)), + + /** + * This shall specify the time of day at which the transition becomes active, in terms of minutes within the + * day representing the wall clock, where 0 is 00:00:00, 1 is 00:01:00 and 1439 is 23:59:00. + * + * Handling of transitions during the changeover of Daylight Saving Time is implementation-dependent. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.32.2 + */ + transitionTime: TlvField(1, TlvUInt16.bound({ max: 1439 })), + + /** + * This field shall specify the preset used at the TransitionTime. If this field is provided, then the + * SystemMode, CoolingSetpoint and HeatingSetpoint fields shall NOT be provided. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.32.3 + */ + presetHandle: TlvOptionalField(2, TlvByteString.bound({ maxLength: 16 })), + + /** + * This shall specify the default mode to which the thermostat will switch for this transition, overriding the + * default for the schedule. The only valid values for this field shall be Auto, Heat, Cool and Off. This field + * shall only be included when the required system mode differs from the schedule’s default SystemMode. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.32.4 + */ + systemMode: TlvOptionalField(3, TlvEnum()), + + /** + * This field shall specify the cooling setpoint for the transition. If PresetHandle is set, this field shall + * NOT be included. Refer to Setpoint Limits for value constraints. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.32.5 + */ + coolingSetpoint: TlvOptionalField(4, TlvInt16), + + /** + * This field shall specify the cooling setpoint for the transition. If PresetHandle is set, this field shall + * NOT be included. Refer to Setpoint Limits for value constraints. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.32.6 + */ + heatingSetpoint: TlvOptionalField(5, TlvInt16) + }); + + /** + * This struct provides a time of day and a set of days of the week for a state transition within a schedule. The + * thermostat shall use the following order of precedence for determining a new setpoint at the time of transition: + * + * 1. If the PresetHandle field is provided, then the setpoint for the PresetStruct in the Presets attribute with + * that identifier shall be used + * + * 2. If either the HeatingSetpoint or CoolingSetpoint is provided, then it shall be used + * + * a. If the SystemMode field is provided, the HeatingSetpoint and CoolingSetpoint fields shall be interpreted + * using the SystemMode field + * + * b. If the SystemMode field is not provided, the HeatingSetpoint and CoolingSetpoint fields shall be + * interpreted using the SystemMode field on the parent ScheduleStruct + * + * 3. If neither the PresetHandle field or any Setpoint field is provided, then the PresetHandle field on the + * parent ScheduleStruct shall be used to determine the active PresetStruct + * + * 4. If the PresetHandle is not indicated and no setpoint is provided for the current SystemMode, the server + * shall use a default value for the current SystemMode. + * + * If the setpoint was derived from a preset, then the ActivePresetHandle shall be set to the PresetHandle of that + * preset. + * + * If a CoolingSetpoint was used to determine the cooling setpoint: + * + * • If the server supports the OCC feature, and the Occupied bit is not set on the Occupancy attribute, then the + * UnoccupiedCoolingSetpoint attribute shall be set to the CoolingSetpoint + * + * • Otherwise, the OccupiedCoolingSetpoint attribute shall be set to the CoolingSetpoint If a HeatingSetpoint + * was used to determine the heating setpoint: + * + * • If the server supports the OCC feature, and the Occupied bit is not set on the Occupancy attribute, then the + * UnoccupiedHeatingSetpoint attribute shall be set to the HeatingSetpoint + * + * • Otherwise, the OccupiedHeatingSetpoint attribute shall be set to the HeatingSetpoint The + * ScheduleTransitionStruct shall be invalid if all the following are true: + * + * • The HeatingSetpoint field is not provided + * + * • The PresetHandle field is not provided + * + * • The PresetHandle field on the encompassing ScheduleStruct is not provided + * + * • The SystemMode field is provided and has the value Heat or Auto, or the SystemMode field on the parent + * ScheduleStruct has the value Heat or Auto + * + * The ScheduleTransitionStruct shall be invalid if all the following are true: + * + * • The CoolingSetpoint field is not provided + * + * • The PresetHandle field is not provided + * + * • The PresetHandle field on the encompassing ScheduleStruct is not provided + * + * • The SystemMode field is provided and has the value Cool or Auto, or the SystemMode field on the parent + * ScheduleStruct has the value Cool or Auto + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.32 + */ + export interface ScheduleTransition extends TypeFromSchema {} + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.31 + */ + export const TlvSchedule = TlvObject({ + /** + * This field shall indicate a device generated identifier for this schedule. It shall be unique on the device, + * and shall NOT be reused after the associated schedule has been deleted. + * + * This field shall only be null when the encompassing ScheduleStruct is appended to the Schedules attribute + * for the purpose of creating a new Schedule. Refer to Schedules for the creation of Schedule handles. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.31.1 + */ + scheduleHandle: TlvField(0, TlvNullable(TlvByteString.bound({ maxLength: 16 }))), + + /** + * This field shall specify the default thermostat system mode for transitions in this schedule. The only valid + * values for this field shall be Auto, Heat, and Cool. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.31.2 + */ + systemMode: TlvField(1, TlvEnum()), + + /** + * This field shall specify a name for the ScheduleStruct. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.31.3 + */ + name: TlvOptionalField(2, TlvString.bound({ maxLength: 64 })), + + /** + * This field shall indicate the default PresetHandle value for transitions in this schedule. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.31.4 + */ + presetHandle: TlvOptionalField(3, TlvByteString.bound({ maxLength: 16 })), + + /** + * This field shall specify a list of transitions for the schedule. + * + * This field shall NOT contain more than one ScheduleStruct with the same TransitionTime field and overlapping + * DayOfWeek fields; i.e. there shall be no duplicate transitions. + * + * If the NumberOfScheduleTransitionsPerDay attribute is not null, then for each bit in + * ScheduleDayOfWeekBitmap, the number of transitions with that bit set in DayOfWeek shall NOT be greater than + * the value of the NumberOfScheduleTransitionsPerDay attribute. + * + * For the purposes of determining which ScheduleStruct in this list is currently active, the current time + * shall be the number of minutes past midnight in the display value of the current time, not the actual number + * of minutes that have elapsed since midnight. On days which transition into or out of daylight saving time, + * certain values may repeat or not occur during the transition period. + * + * A ScheduleTransitionStruct in this list shall be active if the current day of the week matches its DayOfWeek + * field and the current time is greater than or equal to the TransitionTime, but less than the TransitionTime + * on any other ScheduleTransitionStruct in the Transitions field whose DayOfWeek field also matches the + * current day of the week. + * + * If the current time is less than every ScheduleTransitionStruct whose DayOfWeek field also matches the + * current day of the week, the server shall attempt the same process to identify the active + * ScheduleTransitionStruct for the day preceding the previously attempted day of the week, repeating until an + * active ScheduleTransitionStruct is found or the attempted day is the current day of the week again. If no + * active ScheduleTransitionStruct is found, then the active ScheduleTransitionStruct shall be the + * ScheduleTransitionStruct with the largest TransitionTime field from the set of ScheduleTransitionStructs + * whose DayOfWeek field matches the current day of the week. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.31.5 + */ + transitions: TlvField(4, TlvArray(TlvScheduleTransition, { minLength: 1 })), + + /** + * This field shall indicate whether the schedule is marked as "built-in", meaning that it can be modified, but + * it cannot be deleted. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.31.6 + */ + builtIn: TlvField(5, TlvNullable(TlvBoolean)) + }); + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.31 + */ + export interface Schedule extends TypeFromSchema {} + + /** + * Input to the Thermostat setActiveScheduleRequest command + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.8 + */ + export const TlvSetActiveScheduleRequest = TlvObject({ + /** + * This field shall specify the value of the ScheduleHandle field on the ScheduleStruct to be made active. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.8.1 + */ + scheduleHandle: TlvField(0, TlvByteString.bound({ maxLength: 16 })) + }); + + /** + * Input to the Thermostat setActiveScheduleRequest command + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.8 + */ + export interface SetActiveScheduleRequest extends TypeFromSchema {} + /** * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.6 */ @@ -357,7 +974,7 @@ export namespace Thermostat { * * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.6.1 */ - coolingStage: BitField(0, 2), + coolingStage: BitField(1, 0), /** * Stage of heating the HVAC system is using. @@ -374,7 +991,7 @@ export namespace Thermostat { * * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.6.2 */ - heatingStage: BitField(2, 2), + heatingStage: BitField(3, 0), /** * Is the heating type Heat Pump. @@ -404,7 +1021,7 @@ export namespace Thermostat { }; /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.9 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.11 */ export const RemoteSensing = { /** @@ -417,7 +1034,7 @@ export namespace Thermostat { * * This bit shall be supported if the OutdoorTemperature attribute is supported. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.9.1 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.11.1 */ outdoorTemperature: BitFlag(1), @@ -438,7 +1055,7 @@ export namespace Thermostat { * Systems which support cooling or heating, requiring external intervention to change modes or where the whole * building must be in the same mode, SHOULD report CoolingOnly or HeatingOnly based on the current capability. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.18 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.21 */ export enum ControlSequenceOfOperation { /** @@ -473,48 +1090,7 @@ export namespace Thermostat { } /** - * Table 35. Interpretation of Heat, Cool and Auto SystemModeEnum Values - * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.21 - */ - export enum SystemMode { - /** - * The Thermostat does not generate demand for Cooling or Heating - */ - Off = 0, - - /** - * Demand is generated for either Cooling or Heating, as required - */ - Auto = 1, - - /** - * Demand is only generated for Cooling - */ - Cool = 3, - - /** - * Demand is only generated for Heating - */ - Heat = 4, - - /** - * 2nd stage heating is in use to achieve desired temperature - */ - EmergencyHeat = 5, - - /** - * (see Terms) - */ - Precooling = 6, - - FanOnly = 7, - Dry = 8, - Sleep = 9 - } - - /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.23 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.27 */ export enum TemperatureSetpointHold { /** @@ -529,7 +1105,7 @@ export namespace Thermostat { } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.7 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.9 */ export const ProgrammingOperationMode = { /** @@ -549,36 +1125,36 @@ export namespace Thermostat { }; /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.8 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.10 */ export const RelayState = { /** - * Heat State On + * Heat Stage On */ heat: BitFlag(0), /** - * Cool State On + * Cool Stage On */ cool: BitFlag(1), /** - * Fan State On + * Fan Stage On */ fan: BitFlag(2), /** - * Heat 2nd State On + * Heat 2nd Stage On */ heatStage2: BitFlag(3), /** - * Cool 2nd State On + * Cool 2nd Stage On */ coolStage2: BitFlag(4), /** - * Fan 2nd State On + * Fan 2nd Stage On */ fanStage2: BitFlag(5), @@ -589,7 +1165,7 @@ export namespace Thermostat { }; /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.19 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.23 */ export enum SetpointChangeSource { /** @@ -609,7 +1185,7 @@ export namespace Thermostat { } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.16 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.19 */ export enum AcType { /** @@ -639,7 +1215,7 @@ export namespace Thermostat { } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.15 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.18 */ export enum AcRefrigerantType { /** @@ -664,7 +1240,7 @@ export namespace Thermostat { } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.13 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.16 */ export enum AcCompressorType { /** @@ -719,7 +1295,7 @@ export namespace Thermostat { }; /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.14 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.17 */ export enum AcLouverPosition { /** @@ -749,7 +1325,7 @@ export namespace Thermostat { } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.12 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.15 */ export enum AcCapacityFormat { /** @@ -759,7 +1335,7 @@ export namespace Thermostat { } /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.17 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.8.20 */ export enum SetpointRaiseLowerMode { /** @@ -784,7 +1360,19 @@ export namespace Thermostat { * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.1 */ export const TlvSetpointRaiseLowerRequest = TlvObject({ + /** + * The field shall specify which setpoints are to be adjusted. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.1.1 + */ mode: TlvField(0, TlvEnum()), + + /** + * This field shall indicate the amount (possibly negative) that should be added to the setpoint(s), in steps + * of 0.1°C. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.1.2 + */ amount: TlvField(1, TlvInt8) }); @@ -824,7 +1412,7 @@ export namespace Thermostat { * Indicates whether the heated/cooled space is occupied or not, as measured locally or remotely (over the * network). * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.5 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.4 */ occupancy: Attribute( 0x2, @@ -840,7 +1428,12 @@ export namespace Thermostat { export const HeatingComponent = MutableCluster.Component({ attributes: { /** - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9 + * Indicates the absolute minimum level that the heating setpoint may be set to. This is a limitation + * imposed by the manufacturer. + * + * Refer to Setpoint Limits for constraints + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.5 */ absMinHeatSetpointLimit: OptionalFixedAttribute(0x3, TlvInt16, { default: 700 }), @@ -855,26 +1448,31 @@ export namespace Thermostat { * * This attribute is reported regularly and may be used to control a heating device. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.11 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.10 */ piHeatingDemand: OptionalAttribute(0x8, TlvUInt8.bound({ max: 100 })), /** - * Indicates the heating mode setpoint when the room is occupied. + * Indicates the heating mode setpoint when the room is occupied. Refer to Setpoint Limits for constraints. * - * Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute such that these - * constraints are violated, a response with the status code CONSTRAINT_ERROR shall be returned. + * If an attempt is made to set this attribute to a value greater than MaxHeatSetpointLimit or less than + * MinHeatSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * If this attribute is set to a value that is greater than + * + * Band), the value of OccupiedCoolingSetpoint shall be adjusted to (OccupiedHeatingSetpoint + + * MinSetpointDeadBand). * * If the occupancy status of the room is unknown, this attribute shall be used as the heating mode * setpoint. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.15 + * If a client changes the value of this attribute, the server supports the PRES feature, and the server + * either does not support the OCC feature or the Occupied bit is set on the Occupancy attribute, the value + * of the ActivePresetHandle attribute shall be set to null. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.14 */ - occupiedHeatingSetpoint: WritableAttribute( - 0x12, - TlvInt16, - { scene: true, persistent: true, default: 2000 } - ), + occupiedHeatingSetpoint: WritableAttribute(0x12, TlvInt16, { persistent: true, default: 2000 }), /** * Indicates the minimum level that the heating setpoint may be set to. @@ -889,7 +1487,7 @@ export namespace Thermostat { * which is not consistent with the constraints and cannot be resolved by modifying setpoints then a * response with the status code CONSTRAINT_ERROR shall be returned. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.18 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.17 */ minHeatSetpointLimit: OptionalWritableAttribute( 0x15, @@ -906,7 +1504,7 @@ export namespace Thermostat { * which is not consistent with the constraints and cannot be resolved by modifying setpoints then a * response with the status code CONSTRAINT_ERROR shall be returned. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.19 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.18 */ maxHeatSetpointLimit: OptionalWritableAttribute( 0x16, @@ -922,12 +1520,7 @@ export namespace Thermostat { export const CoolingComponent = MutableCluster.Component({ attributes: { /** - * Indicates the absolute minimum level that the cooling setpoint may be set to. This is a limitation - * imposed by the manufacturer. - * - * Refer to Setpoint Limits for constraints - * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.8 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9 */ absMinCoolSetpointLimit: OptionalFixedAttribute(0x5, TlvInt16, { default: 1600 }), @@ -937,7 +1530,7 @@ export namespace Thermostat { * * Refer to Setpoint Limits for constraints * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.9 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.8 */ absMaxCoolSetpointLimit: OptionalFixedAttribute(0x6, TlvInt16, { default: 3200 }), @@ -947,26 +1540,30 @@ export namespace Thermostat { * * This attribute is reported regularly and may be used to control a cooling device. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.10 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.9 */ piCoolingDemand: OptionalAttribute(0x7, TlvUInt8.bound({ max: 100 })), /** - * Indicates the cooling mode setpoint when the room is occupied. + * Indicates the cooling mode setpoint when the room is occupied. Refer to Setpoint Limits for constraints. * - * Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute such that these - * constraints are violated, a response with the status code CONSTRAINT_ERROR shall be returned. + * If an attempt is made to set this attribute to a value greater than MaxCoolSetpointLimit or less than + * MinCoolSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * If this attribute is set to a value that is less than (OccupiedHeatingSetpoint + MinSetpointDeadBand), + * the value of OccupiedHeatingSetpoint shall be adjusted to (OccupiedCoolingSetpoint - + * MinSetpointDeadBand). * * If the occupancy status of the room is unknown, this attribute shall be used as the cooling mode * setpoint. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.14 + * If a client changes the value of this attribute, the server supports the PRES feature, and the server + * either does not support the OCC feature or the Occupied bit is set on the Occupancy attribute, the value + * of the ActivePresetHandle attribute shall be set to null. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.13 */ - occupiedCoolingSetpoint: WritableAttribute( - 0x11, - TlvInt16, - { scene: true, persistent: true, default: 2600 } - ), + occupiedCoolingSetpoint: WritableAttribute(0x11, TlvInt16, { persistent: true, default: 2600 }), /** * Indicates the minimum level that the cooling setpoint may be set to. @@ -977,7 +1574,7 @@ export namespace Thermostat { * which is not consistent with the constraints and cannot be resolved by modifying setpoints then a * response with the status code CONSTRAINT_ERROR shall be returned. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.20 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.19 */ minCoolSetpointLimit: OptionalWritableAttribute( 0x17, @@ -994,7 +1591,7 @@ export namespace Thermostat { * which is not consistent with the constraints and cannot be resolved by modifying setpoints then a * response with the status code CONSTRAINT_ERROR shall be returned. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.21 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.20 */ maxCoolSetpointLimit: OptionalWritableAttribute( 0x18, @@ -1021,7 +1618,12 @@ export namespace Thermostat { * (e.g., out of the range supported by the Thermostat server), the Thermostat server shall respond with a * status of SUCCESS and set the value of LocalTemperatureCalibration to the upper or lower limit reached. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.13 + * NOTE + * + * Prior to revision 8 of this cluster specification the value of this attribute was constrained to a range + * of -2.5°C to 2.5°C. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.12 */ localTemperatureCalibration: OptionalWritableAttribute( 0x10, @@ -1037,14 +1639,23 @@ export namespace Thermostat { export const CoolingAndOccupancyComponent = MutableCluster.Component({ attributes: { /** - * Indicates the cooling mode setpoint when the room is unoccupied. + * Indicates the cooling mode setpoint when the room is unoccupied. Refer to Setpoint Limits for + * constraints. + * + * If an attempt is made to set this attribute to a value greater than MaxCoolSetpointLimit or less than + * MinCoolSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned. * - * Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute such that these - * constraints are violated, a response with the status code CONSTRAINT_ERROR shall be returned. + * If this attribute is set to a value that is less than (UnoccupiedHeatingSetpoint + MinSetpointDeadBand), + * the value of UnoccupiedHeatingSetpoint shall be adjusted to (UnoccupiedCoolingSetpoint - + * MinSetpointDeadBand). * * If the occupancy status of the room is unknown, this attribute shall NOT be used. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.16 + * If a client changes the value of this attribute, the server supports the PRES and OCC features, and the + * Occupied bit is not set on the Occupancy attribute, the value of the ActivePresetHandle attribute shall + * be set to null. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.15 */ unoccupiedCoolingSetpoint: WritableAttribute(0x13, TlvInt16, { persistent: true, default: 2600 }) } @@ -1056,14 +1667,24 @@ export namespace Thermostat { export const HeatingAndOccupancyComponent = MutableCluster.Component({ attributes: { /** - * Indicates the heating mode setpoint when the room is unoccupied. + * Indicates the heating mode setpoint when the room is unoccupied. Refer to Setpoint Limits for + * constraints. + * + * If an attempt is made to set this attribute to a value greater than MaxHeatSetpointLimit or less than + * MinHeatSetpointLimit, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * If this attribute is set to a value that is greater than (UnoccupiedCoolingSetpoint - + * MinSetpointDeadBand), the value of UnoccupiedCoolingSetpoint shall be adjusted to * - * Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute such that these - * constraints are violated, a response with the status code CONSTRAINT_ERROR shall be returned. + * + MinSetpointDeadBand). * * If the occupancy status of the room is unknown, this attribute shall NOT be used. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.17 + * If a client changes the value of this attribute, the server supports the PRES and OCC features, and the + * Occupied bit is not set on the Occupancy attribute, the value of the ActivePresetHandle attribute shall + * be set to null. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.16 */ unoccupiedHeatingSetpoint: WritableAttribute(0x14, TlvInt16, { persistent: true, default: 2000 }) } @@ -1078,22 +1699,32 @@ export namespace Thermostat { * On devices which support the AUTO feature, this attribute shall indicate the minimum difference between * the Heat Setpoint and the Cool Setpoint. * - * Refer to Setpoint Limits for constraints. If an attempt is made to set this attribute to a value which - * conflicts with setpoint values then those setpoints shall be adjusted by the minimum amount to permit - * this attribute to be set to the desired value. If an attempt is made to set this attribute to a value - * which is not consistent with the constraints and cannot be resolved by modifying setpoints then a - * response with the status code CONSTRAINT_ERROR shall be returned. + * Refer to Setpoint Limits for constraints. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.22 + * NOTE + * + * Prior to revision 8 of this cluster specification the value of this attribute was constrained to a range + * of 0°C to 2.5°C. + * + * NOTE + * + * For backwards compatibility, this attribute is optionally writeable. However any writes to this + * attribute shall be silently ignored. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.21 */ - minSetpointDeadBand: WritableAttribute(0x19, TlvInt8, { persistent: true, writeAcl: AccessLevel.Manage }), + minSetpointDeadBand: WritableAttribute( + 0x19, + TlvInt8.bound({ min: 0 }), + { persistent: true, writeAcl: AccessLevel.Manage } + ), /** * Indicates the running mode of the thermostat. This attribute uses the same values as SystemModeEnum but * can only be Off, Cool or Heat. This attribute is intended to provide additional information when the * thermostat’s system mode is in auto mode. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.27 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.26 */ thermostatRunningMode: OptionalAttribute( 0x1e, @@ -1115,57 +1746,37 @@ export namespace Thermostat { * This attribute may be able to be used as the base to determine if the device supports weekly scheduling * by reading the attribute. Successful response means that the weekly scheduling is supported. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.28 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.27 */ startOfWeek: FixedAttribute(0x20, TlvEnum()), /** * Indicates how many weekly schedule transitions the thermostat is capable of handling. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.29 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.28 */ numberOfWeeklyTransitions: FixedAttribute(0x21, TlvUInt8, { default: 0 }), /** * Indicates how many daily schedule transitions the thermostat is capable of handling. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.30 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.29 */ numberOfDailyTransitions: FixedAttribute(0x22, TlvUInt8, { default: 0 }) }, commands: { /** - * Upon receipt, the weekly schedule for updating setpoints shall be stored in the thermostat and SHOULD - * begin at the time of receipt. A status code shall be sent in response. - * - * When a command is received that requires a total number of transitions greater than the device supports, - * the status of the response shall be INSUFFICIENT_SPACE. - * - * When any of the setpoints sent in the sequence is out of range (AbsMin/MaxSetPointLimit), or when the - * Mode for Sequence field includes a mode not supported by the device, the status of the response shall be - * CONSTRAINT_ERROR and no setpoints from the entire sequence SHOULD be used. - * - * When an overlapping transition is detected, the status of the response shall be FAILURE. - * - * When a device which does not support multiple days in a command receives a command with more than one - * bit set in the DayOfWeekForSequence field, or when a device which does not support multiple modes in a - * command receives a command with more than one bit set in the ModeForSequence field, or when the contents - * of the Transitions field does not agree with NumberOfTransitionsForSequence, DayOfWeekForSequence or - * ModeForSequence, the status of the response shall be INVALID_COMMAND. - * - * When the transitions could be added successfully, the status of the response shall be SUCCESS. - * - * The set weekly schedule command is used to update the thermostat weekly setpoint schedule from a - * management system. If the thermostat already has a weekly setpoint schedule programmed, then it SHOULD - * replace each daily setpoint set as it receives the updates from the management system. For example, if - * the thermostat has 4 setpoints for every day of the week and is sent a Set Weekly Schedule command with - * one setpoint for Saturday then the thermostat SHOULD remove all 4 setpoints for Saturday and replace - * those with the updated setpoint but leave all other days unchanged. If the schedule is larger than what - * fits in one frame or contains more than 10 transitions, the schedule shall then be sent using multiple - * Set Weekly Schedule Commands. - * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.4 + * This command is used to update the thermostat weekly setpoint schedule from a management system. If the + * thermostat already has a weekly setpoint schedule programmed, then it SHOULD replace each daily setpoint + * set as it receives the updates from the management system. For example, if the thermostat has 4 + * setpoints for every day of the week and is sent a SetWeeklySchedule command with one setpoint for + * Saturday then the thermostat SHOULD remove all 4 setpoints for Saturday and replace those with the + * updated setpoint but leave all other days unchanged. If the schedule is larger than what fits in one + * frame or contains more than 10 transitions, the schedule shall then be sent using multiple + * SetWeeklySchedule Commands. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.2 */ setWeeklySchedule: Command( 0x1, @@ -1176,12 +1787,7 @@ export namespace Thermostat { ), /** - * Upon receipt, the unit SHOULD send in return the Get Weekly Schedule Response command. The Days to - * Return and Mode to Return fields are defined as bitmask for the flexibility to support multiple days and - * multiple modes within one command. If thermostat cannot handle incoming command with multiple days - * and/or multiple modes within one command, it shall send default response of INVALID_COMMAND in return. - * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.5 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.3 */ getWeeklySchedule: Command(0x2, TlvGetWeeklyScheduleRequest, 0x0, TlvGetWeeklyScheduleResponse), @@ -1191,7 +1797,7 @@ export namespace Thermostat { * Upon receipt, all transitions currently stored shall be cleared and a default response of SUCCESS shall * be sent in response. There are no error responses to this command. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.7 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.5 */ clearWeeklySchedule: Command(0x3, TlvNoArguments, 0x3, TlvNoResponse, { invokeAcl: AccessLevel.Manage }) } @@ -1223,7 +1829,7 @@ export namespace Thermostat { * Thermostat server shall set its OccupiedSetback value to OccupiedSetbackMin and shall send a Write * Attribute Response command with a Status Code field enumeration of SUCCESS response. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.38 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.37 */ occupiedSetback: WritableAttribute( 0x34, @@ -1237,7 +1843,7 @@ export namespace Thermostat { * * The null value indicates the attribute is unused. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.39 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.38 */ occupiedSetbackMin: FixedAttribute(0x35, TlvNullable(TlvUInt8), { default: null }), @@ -1247,7 +1853,7 @@ export namespace Thermostat { * * The null value indicates the attribute is unused. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.40 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.39 */ occupiedSetbackMax: FixedAttribute(0x36, TlvNullable(TlvUInt8), { default: null }) } @@ -1280,7 +1886,7 @@ export namespace Thermostat { * the Thermostat server shall set its UnoccupiedSetback value to UnoccupiedSetbackMin and shall send a * Write Attribute Response command with a Status Code field enumeration of SUCCESS response. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.41 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.40 */ unoccupiedSetback: WritableAttribute( 0x37, @@ -1294,7 +1900,7 @@ export namespace Thermostat { * * The null value indicates the attribute is unused. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.42 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.41 */ unoccupiedSetbackMin: FixedAttribute(0x38, TlvNullable(TlvUInt8), { default: null }), @@ -1304,19 +1910,310 @@ export namespace Thermostat { * * The null value indicates the attribute is unused. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.43 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.42 */ unoccupiedSetbackMax: FixedAttribute(0x39, TlvNullable(TlvUInt8), { default: null }) } }); + /** + * A ThermostatCluster supports these elements if it supports feature Presets. + */ + export const PresetsComponent = MutableCluster.Component({ + attributes: { + /** + * Indicates the supported PresetScenarioEnum values, limits on how many presets can be created for each + * PresetScenarioEnum, and whether or not a thermostat can transition automatically to a given scenario. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.52 + */ + presetTypes: FixedAttribute(0x48, TlvArray(TlvPresetType), { default: [] }), + + /** + * Indicates the maximum number of entries supported by the Presets attribute. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.54 + */ + numberOfPresets: FixedAttribute(0x4a, TlvUInt8, { default: 0 }), + + /** + * Indicates the PresetHandle of the active preset. If this attribute is null, then there is no active + * preset. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.58 + */ + activePresetHandle: Attribute( + 0x4e, + TlvNullable(TlvByteString.bound({ maxLength: 16 })), + { persistent: true, default: null } + ), + + /** + * This attribute shall contain the current list of configured presets. On receipt of a write request: + * + * 1. If the PresetHandle field is null, the PresetStruct shall be treated as an added preset, and the + * device shall create a new unique value for the PresetHandle field. + * + * a. If the BuiltIn field is true, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * 2. If the PresetHandle field is not null, the PresetStruct shall be treated as a modification of an + * existing preset. + * + * a. If the value of the PresetHandle field does not match any of the existing presets, a response + * with the status code NOT_FOUND shall be returned. + * + * b. If the value of the PresetHandle field is duplicated on multiple presets in the updated list, a + * response with the status code CONSTRAINT_ERROR shall be returned. + * + * c. If the BuiltIn field is true, and the PresetStruct in the current value with a matching + * PresetHandle field has a BuiltIn field set to false, a response with the status code + * CONSTRAINT_ERROR shall be returned. + * + * d. If the BuiltIn field is false, and the PresetStruct in the current value with a matching + * PresetHandle field has a BuiltIn field set to true, a response with the status code + * CONSTRAINT_ERROR shall be returned. + * + * 3. If the specified PresetScenarioEnum value does not exist in PresetTypes, a response with the status + * code CONSTRAINT_ERROR shall be returned. + * + * 4. If the Name is set, but the associated PresetTypeStruct does not have the SupportsNames bit set, a + * response with the status code CONSTRAINT_ERROR shall be returned. + * + * 5. If appending the received PresetStruct to the pending list of Presets would cause the total number + * of pending presets to exceed the value of the NumberOfPresets attribute, a response with the status + * code RESOURCE_EXHAUSTED shall be returned. + * + * 6. If appending the received PresetStruct to the pending list of Presets would cause the total number + * of pending presets whose PresetScenario field matches the appended preset’s PresetScenario field to + * exceed the value of the NumberOfPresets field on the PresetTypeStruct whose PresetScenario matches + * the appended preset’s PresetScenario field, a response with the status code RESOURCE_EXHAUSTED + * shall be returned. + * + * 7. Otherwise, the write shall be pended until receipt of a commit request, and the status code SUCCESS + * shall be returned. + * + * a. If the BuiltIn field is null: + * + * i. If there is a PresetStruct in the current value with a matching PresetHandle field, the BuiltIn + * field on the pending PresetStruct shall be set to the value of the BuiltIn on the matching + * PresetStruct. + * + * ii. Otherwise, the BuiltIn field on the pending PresetStruct shall be set to false. + * + * On an attempt to commit, the status of this attribute shall be determined as follows: + * + * 1. For all existing presets: + * + * a. If, after applying all pending changes, the updated value of the Presets attribute would not + * contain a PresetStruct with a matching PresetHandle field, indicating the removal of the + * PresetStruct, the server shall check for invalid removal of the PresetStruct: + * + * i. If the BuiltIn field is true on the removed PresetStruct, the attribute status shall be + * CONSTRAINT_ERROR. + * + * ii. If the MSCH feature is supported and the removed PresetHandle would be referenced by any + * PresetHandle on any ScheduleTransitionStruct on any ScheduleStruct in the updated value of + * the Schedules attribute, the attribute status shall be INVALID_IN_STATE. + * + * iii. If the removed PresetHandle is equal to the value of the ActivePresetHandle attribute, the + * attribute status shall be INVALID_IN_STATE. + * + * 2. Otherwise, the attribute status shall be SUCCESS. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.60 + */ + presets: WritableAttribute( + 0x50, + TlvArray(TlvPreset), + { persistent: true, default: [], writeAcl: AccessLevel.Manage } + ) + }, + + commands: { + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.9 + */ + setActivePresetRequest: Command(0x6, TlvSetActivePresetRequest, 0x6, TlvNoResponse) + } + }); + + /** + * A ThermostatCluster supports these elements if it supports feature MatterScheduleConfiguration. + */ + export const MatterScheduleConfigurationComponent = MutableCluster.Component({ + attributes: { + /** + * Indicates the supported SystemMode values for Schedules, limits on how many schedules can be created for + * each SystemMode value, and whether or not a given SystemMode value supports transitions to Presets, + * target setpoints, or both. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.53 + */ + scheduleTypes: FixedAttribute(0x49, TlvArray(TlvScheduleType), { default: [] }), + + /** + * Indicates the maximum number of entries supported by the Schedules attribute. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.55 + */ + numberOfSchedules: FixedAttribute(0x4b, TlvUInt8, { default: 0 }), + + /** + * Indicates the maximum number of transitions per Schedules attribute entry. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.56 + */ + numberOfScheduleTransitions: FixedAttribute(0x4c, TlvUInt8, { default: 0 }), + + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9 + */ + numberOfScheduleTransitionPerDay: FixedAttribute(0x4d, TlvNullable(TlvUInt8), { default: null }), + + /** + * Indicates the ScheduleHandle of the active schedule. A null value in this attribute indicates that there + * is no active schedule. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.59 + */ + activeScheduleHandle: Attribute( + 0x4f, + TlvNullable(TlvByteString.bound({ maxLength: 16 })), + { persistent: true, default: null } + ), + + /** + * This attribute shall contain a list of ScheduleStructs. On receipt of a write request: + * + * 1. For all schedules in the write request: + * + * a. If the ScheduleHandle field is null, the ScheduleStruct shall be treated as an added schedule, + * and the device shall create a new unique value for the ScheduleHandle field. + * + * i. If the BuiltIn field is true, a response with the status code CONSTRAINT_ERROR shall be + * returned. + * + * b. Otherwise, if the ScheduleHandle field is not null, the ScheduleStruct shall be treated as a + * modification of an existing schedule. + * + * i. If the value of the ScheduleHandle field does not match any of the existing schedules, a + * response with the status code NOT_FOUND shall be returned. + * + * ii. If the BuiltIn field is true, and the ScheduleStruct in the current value with a matching + * ScheduleHandle field has a BuiltIn field set to false, a response with the status code + * CONSTRAINT_ERROR shall be returned. + * + * iii. If the BuiltIn field is false, and the ScheduleStruct in the current value with a matching + * ScheduleHandle field has a BuiltIn field set to true, a response with the status code + * CONSTRAINT_ERROR shall be returned. + * + * c. If the specified SystemMode does not exist in ScheduleTypes, a response with the status code + * CONSTRAINT_ERROR shall be returned. + * + * d. If the number of transitions exceeds the NumberOfScheduleTransitions value, a response with the + * status code RESOURCE_EXHAUSTED shall be returned. + * + * e. If the value of the NumberOfScheduleTransitionsPerDay attribute is not null, and the number of + * transitions on any single day of the week exceeds the NumberOfScheduleTransitionsPerDay value, a + * response with the status code RESOURCE_EXHAUSTED shall be returned. + * + * f. If the PresetHandle field is present, but the associated ScheduleTypeStruct does not have the + * SupportsPresets bit set, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * g. If the PresetHandle field is present, but after applying all pending changes, the Presets + * attribute would not contain a PresetStruct whose PresetHandle field matches the value of the + * PresetHandle field, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * h. If the Name is set, but the associated ScheduleTypeStruct does not have the SupportsNames bit + * set, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * i. For all transitions in all schedules in the write request: + * + * i. If the PresetHandle field is present, but the ScheduleTypeStruct matching the value of the + * SystemMode field on the encompassing ScheduleStruct does not have the SupportsPresets bit set, + * a response with the status code CONSTRAINT_ERROR shall be returned. + * + * j. If the PresetHandle field is present, but after applying all pending changes, the Presets + * attribute would not contain a PresetStruct whose PresetHandle field matches the value of the + * PresetHandle field, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * i. If the SystemMode field is present, but the ScheduleTypeStruct matching the value of the + * SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints bit + * set, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * ii. If the SystemMode field is has a value of SystemModeOff, but the ScheduleTypeStruct matching + * the value of the SystemMode field on the encompassing ScheduleStruct does not have the + * SupportsOff bit set, a response with the status code CONSTRAINT_ERROR shall be returned. + * + * k. If the HeatingSetpoint field is present, but the ScheduleTypeStruct matching the value of the + * SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints bit set, + * a response with the status code CONSTRAINT_ERROR shall be returned. + * + * l. If the CoolingSetpoint field is present, but the ScheduleTypeStruct matching the value of the + * SystemMode field on the encompassing ScheduleStruct does not have the SupportsSetpoints bit set, + * a response with the status code CONSTRAINT_ERROR shall be returned. + * + * 2. If appending the received ScheduleStruct to the pending list of Schedules would cause the total + * number of pending schedules to exceed the value of the NumberOfSchedules attribute, a response with + * the status code RESOURCE_EXHAUSTED shall be returned. + * + * 3. If appending the received ScheduleStruct to the pending list of Schedules would cause the total + * number of pending schedules whose SystemMode field matches the appended schedule’s SystemMode field + * to exceed the value of the NumberOfSchedules field on the ScheduleTypeStruct whose SystemMode field + * matches the appended schedule’s SystemMode field, a response with the status code + * RESOURCE_EXHAUSTED shall be returned. + * + * 4. Otherwise, the write shall be pended until receipt of a commit request, and the attribute status + * shall be SUCCESS. + * + * a. If the BuiltIn field is null: + * + * i. If there is a ScheduleStruct in the current value with a matching ScheduleHandle field, the + * BuiltIn field on the pending ScheduleStruct shall be set to the value of the BuiltIn on the + * matching ScheduleStruct. + * + * ii. Otherwise, the BuiltIn field on the pending ScheduleStruct shall be set to false. + * + * On an attempt to commit, the status of this attribute shall be determined as follows: + * + * 1. For all existing schedules: + * + * a. If, after applying all pending changes, the updated value of the Schedules attribute would not + * contain a ScheduleStruct with a matching ScheduleHandle field, indicating the removal of the + * ScheduleStruct, the server shall check for invalid removal of the ScheduleStruct: + * + * i. If the BuiltIn field is true on the removed ScheduleStruct, the attribute status shall be + * CONSTRAINT_ERROR. + * + * ii. If the removed ScheduleHandle is equal to the value of the ActiveScheduleHandle attribute, the + * attribute status shall be INVALID_IN_STATE. + * + * 2. Otherwise, the attribute status shall be SUCCESS. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.61 + */ + schedules: WritableAttribute( + 0x51, + TlvArray(TlvSchedule), + { persistent: true, default: [], writeAcl: AccessLevel.Manage } + ) + }, + + commands: { + /** + * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.8 + */ + setActiveScheduleRequest: Command(0x5, TlvSetActiveScheduleRequest, 0x5, TlvNoResponse) + } + }); + /** * These elements and properties are present in all Thermostat clusters. */ export const Base = MutableCluster.Component({ id: 0x201, name: "Thermostat", - revision: 6, + revision: 8, features: { /** @@ -1370,7 +2267,21 @@ export namespace Thermostat { * * @see {@link MatterSpecification.v13.Cluster} § 4.3.4.1 */ - localTemperatureNotExposed: BitFlag(6) + localTemperatureNotExposed: BitFlag(6), + + /** + * MatterScheduleConfiguration + * + * Supports enhanced schedules + */ + matterScheduleConfiguration: BitFlag(7), + + /** + * Presets + * + * Thermostat supports setpoint presets + */ + presets: BitFlag(8) }, attributes: { @@ -1387,24 +2298,25 @@ export namespace Thermostat { * • Otherwise, if the LTNE feature is supported, there is no feedback externally available for the * LocalTemperatureCalibration. In that case, the LocalTemperature attribute shall always report null. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.3 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.2 */ localTemperature: Attribute(0x0, TlvNullable(TlvInt16), { default: null }), /** * Indicates the outdoor temperature, as measured locally or remotely (over the network). * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.4 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.3 */ outdoorTemperature: OptionalAttribute(0x1, TlvNullable(TlvInt16), { default: null }), /** * Indicates the HVAC system type controlled by the thermostat. If the thermostat uses physical DIP - * switches to set these parameters, this information shall be available read-only from the DIP switches. - * If these parameters are set via software, there shall be read/write access in order to provide remote - * programming capability. + * switches to set these parameters, this information shall be available read-only * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.12 + * from the DIP switches. If these parameters are set via software, there shall be read/write access in + * order to provide remote programming capability. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.11 * @deprecated */ hvacSystemTypeConfiguration: OptionalWritableAttribute( @@ -1423,7 +2335,7 @@ export namespace Thermostat { * If the LocalTemperature RemoteSensing bit is written with a value of 1 when the LTNE feature is present, * the write shall fail and the server shall report a CONSTRAINT_ERROR. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.23 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.22 */ remoteSensing: OptionalWritableAttribute( 0x1a, @@ -1435,7 +2347,11 @@ export namespace Thermostat { * Indicates the overall operating environment of the thermostat, and thus the possible system modes that * the thermostat can operate in. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.24 + * If an attempt is made to write to this attribute, the server shall silently ignore the write and the + * value of this attribute shall remain unchanged. This behavior is in place for backwards compatibility + * with existing thermostats. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.23 */ controlSequenceOfOperation: WritableAttribute( 0x1b, @@ -1447,12 +2363,12 @@ export namespace Thermostat { * Indicates the current operating mode of the thermostat. Its value shall be limited by the * ControlSequenceOfOperation attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.25 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.24 */ systemMode: WritableAttribute( 0x1c, TlvEnum(), - { scene: true, persistent: true, default: SystemMode.Auto, writeAcl: AccessLevel.Manage } + { persistent: true, default: SystemMode.Auto, writeAcl: AccessLevel.Manage } ), /** @@ -1462,7 +2378,18 @@ export namespace Thermostat { * If the thermostat supports setpoint hold for a specific duration, it SHOULD also implement the * TemperatureSetpointHoldDuration attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.31 + * If the server supports a setpoint hold for a specific duration, it SHOULD also implement the + * SetpointHoldExpiryTimestamp attribute. + * + * If this attribute is updated to SetpointHoldOn and the TemperatureSetpointHoldDuration has a non- null + * value and the SetpointHoldExpiryTimestamp is supported, the server shall update the + * SetpointHoldExpiryTimestamp with a value of current UTC timestamp, in seconds, plus the value in + * TemperatureSetpointHoldDuration multiplied by 60. + * + * If this attribute is updated to SetpointHoldOff and the SetpointHoldExpiryTimestamp is supported, the + * server shall set the SetpointHoldExpiryTimestamp to null. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.30 */ temperatureSetpointHold: OptionalWritableAttribute( 0x23, @@ -1475,7 +2402,15 @@ export namespace Thermostat { * specified duration SHOULD implement this attribute. The null value indicates the field is unused. All * other values are reserved. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.32 + * If this attribute is updated to a non-null value and the TemperatureSetpointHold is set to + * SetpointHoldOn and the SetpointHoldExpiryTimestamp is supported, the server shall update + * SetpointHoldExpiryTimestamp with a value of current UTC timestamp, in seconds, plus the new value of + * this attribute multiplied by 60. + * + * If this attribute is set to null and the SetpointHoldExpiryTimestamp is supported, the server shall set + * the SetpointHoldExpiryTimestamp to null. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.31 */ temperatureSetpointHoldDuration: OptionalWritableAttribute( 0x24, @@ -1501,7 +2436,7 @@ export namespace Thermostat { * Modifying the ScheduleActive bit does not clear or delete previous weekly schedule programming * configurations. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.33 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.32 */ thermostatProgrammingOperationMode: OptionalWritableAttribute( 0x25, @@ -1513,7 +2448,7 @@ export namespace Thermostat { * Indicates the current relay state of the heat, cool, and fan relays. Unimplemented outputs shall be * treated as if they were Off. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.34 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.33 */ thermostatRunningState: OptionalAttribute(0x29, TlvBitmap(TlvUInt16, RelayState)), @@ -1526,7 +2461,7 @@ export namespace Thermostat { * provider). Because automation services may initiate frequent setpoint changes, this attribute clearly * differentiates the source of setpoint changes made at the thermostat. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.35 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.34 */ setpointChangeSource: OptionalAttribute( 0x30, @@ -1541,14 +2476,14 @@ export namespace Thermostat { * * The null value indicates that the previous setpoint was unknown. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.36 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.35 */ setpointChangeAmount: OptionalAttribute(0x31, TlvNullable(TlvInt16), { default: null }), /** * Indicates the time in UTC at which the SetpointChangeAmount attribute change was recorded. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.37 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.36 */ setpointChangeSourceTimestamp: OptionalAttribute(0x32, TlvEpochS, { default: 0 }), @@ -1578,7 +2513,7 @@ export namespace Thermostat { * when a setpoint is of a specified amount greater than the measured temperature. This allows the heated * space to be quickly heated to the desired level set by the user. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.44 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.43 */ emergencyHeatDelta: OptionalWritableAttribute( 0x3a, @@ -1590,7 +2525,7 @@ export namespace Thermostat { * Indicates the type of Mini Split ACTypeEnum of Mini Split AC is defined depending on how Cooling and * Heating condition is achieved by Mini Split AC. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.45 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.44 */ acType: OptionalWritableAttribute( 0x40, @@ -1601,7 +2536,7 @@ export namespace Thermostat { /** * Indicates capacity of Mini Split AC in terms of the format defined by the ACCapacityFormat attribute * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.46 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.45 */ acCapacity: OptionalWritableAttribute( 0x41, @@ -1612,7 +2547,7 @@ export namespace Thermostat { /** * Indicates type of refrigerant used within the Mini Split AC. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.47 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.46 */ acRefrigerantType: OptionalWritableAttribute( 0x42, @@ -1623,7 +2558,7 @@ export namespace Thermostat { /** * Indicates the type of compressor used within the Mini Split AC. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.48 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.47 */ acCompressorType: OptionalWritableAttribute( 0x43, @@ -1634,7 +2569,7 @@ export namespace Thermostat { /** * Indicates the type of errors encountered within the Mini Split AC. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.49 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.48 */ acErrorCode: OptionalWritableAttribute( 0x44, @@ -1645,7 +2580,7 @@ export namespace Thermostat { /** * Indicates the position of Louver on the AC. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.50 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.49 */ acLouverPosition: OptionalWritableAttribute( 0x45, @@ -1656,29 +2591,41 @@ export namespace Thermostat { /** * Indicates the temperature of the AC coil, as measured locally or remotely (over the network). * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.51 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.50 */ acCoilTemperature: OptionalAttribute(0x46, TlvNullable(TlvInt16), { default: null }), /** * Indicates the format for the ACCapacity attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.52 + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.51 */ acCapacityFormat: OptionalWritableAttribute( 0x47, TlvEnum(), { persistent: true, default: AcCapacityFormat.BtUh, writeAcl: AccessLevel.Manage } + ), + + /** + * If there is a known time when the TemperatureSetpointHold shall be cleared, this attribute shall contain + * the timestamp in UTC indicating when that will happen. If there is no such known time, this attribute + * shall be null. + * + * If the TemperatureSetpointHold is set to SetpointHoldOff or the TemperatureSetpointHoldDuration is set + * to null, this attribute shall be set to null indicating there is no hold on the Thermostat either with + * or without a duration. + * + * @see {@link MatterSpecification.v13.Cluster} § 4.3.9.62 + */ + setpointHoldExpiryTimestamp: OptionalAttribute( + 0x52, + TlvNullable(TlvEpochS), + { persistent: true, default: null } ) }, commands: { /** - * Upon receipt, the attributes for the indicated setpoint(s) shall have the amount specified in the Amount - * field added to them. If the resulting value is outside the limits imposed by MinCoolSetpointLimit, - * MaxCoolSetpointLimit, MinHeatSetpointLimit and MaxHeatSetpointLimit, the value is clamped to those - * limits. This is not considered an error condition. - * * @see {@link MatterSpecification.v13.Cluster} § 4.3.10.1 */ setpointRaiseLower: Command(0x0, TlvSetpointRaiseLowerRequest, 0x0, TlvNoResponse) @@ -1699,6 +2646,8 @@ export namespace Thermostat { { flags: { scheduleConfiguration: true }, component: ScheduleConfigurationComponent }, { flags: { setback: true }, component: SetbackComponent }, { flags: { setback: true, occupancy: true }, component: SetbackAndOccupancyComponent }, + { flags: { presets: true }, component: PresetsComponent }, + { flags: { matterScheduleConfiguration: true }, component: MatterScheduleConfigurationComponent }, { flags: { autoMode: true, heating: false }, component: false }, { flags: { autoMode: true, cooling: false }, component: false }, { flags: { heating: false, cooling: false }, component: false } @@ -1713,6 +2662,44 @@ export namespace Thermostat { /** * This cluster provides an interface to the functionality of a thermostat. * + * Optional temperature, humidity and occupancy sensors + * + * Thermostat + * + * Heating / cooling control panel + * + * C + * + * Dehumidification configuration + * + * Dehumidification notification + * + * ThermostatS + * + * Heating / cooling device (e.g. indoor air handler) + * + * S + * + * user interface S + * + * configuration + * + * C + * + * Configuration tool + * + * Thermostat configuration + * + * C C Fan control S + * + * ThermostatS notification C + * + * C = Client S = Server + * + * Note: Device names are examples for illustration purposes only + * + * Figure 15. Example Usage of the Thermostat and Related Clusters" + * * Per the Matter specification you cannot use {@link ThermostatCluster} without enabling certain feature * combinations. You must use the {@link with} factory method to obtain a working cluster. * @@ -1730,6 +2717,8 @@ export namespace Thermostat { const SCH = { scheduleConfiguration: true }; const SB = { setback: true }; const SB_OCC = { setback: true, occupancy: true }; + const PRES = { presets: true }; + const MSCH = { matterScheduleConfiguration: true }; /** * @see {@link Complete} @@ -1846,6 +2835,40 @@ export namespace Thermostat { unoccupiedSetbackMax: MutableCluster.AsConditional( SetbackAndOccupancyComponent.attributes.unoccupiedSetbackMax, { mandatoryIf: [SB_OCC] } + ), + presetTypes: MutableCluster.AsConditional(PresetsComponent.attributes.presetTypes, { mandatoryIf: [PRES] }), + scheduleTypes: MutableCluster.AsConditional( + MatterScheduleConfigurationComponent.attributes.scheduleTypes, + { mandatoryIf: [MSCH] } + ), + numberOfPresets: MutableCluster.AsConditional( + PresetsComponent.attributes.numberOfPresets, + { mandatoryIf: [PRES] } + ), + numberOfSchedules: MutableCluster.AsConditional( + MatterScheduleConfigurationComponent.attributes.numberOfSchedules, + { mandatoryIf: [MSCH] } + ), + numberOfScheduleTransitions: MutableCluster.AsConditional( + MatterScheduleConfigurationComponent.attributes.numberOfScheduleTransitions, + { mandatoryIf: [MSCH] } + ), + numberOfScheduleTransitionPerDay: MutableCluster.AsConditional( + MatterScheduleConfigurationComponent.attributes.numberOfScheduleTransitionPerDay, + { mandatoryIf: [MSCH] } + ), + activePresetHandle: MutableCluster.AsConditional( + PresetsComponent.attributes.activePresetHandle, + { mandatoryIf: [PRES] } + ), + activeScheduleHandle: MutableCluster.AsConditional( + MatterScheduleConfigurationComponent.attributes.activeScheduleHandle, + { mandatoryIf: [MSCH] } + ), + presets: MutableCluster.AsConditional(PresetsComponent.attributes.presets, { mandatoryIf: [PRES] }), + schedules: MutableCluster.AsConditional( + MatterScheduleConfigurationComponent.attributes.schedules, + { mandatoryIf: [MSCH] } ) }, @@ -1862,6 +2885,14 @@ export namespace Thermostat { clearWeeklySchedule: MutableCluster.AsConditional( ScheduleConfigurationComponent.commands.clearWeeklySchedule, { mandatoryIf: [SCH] } + ), + setActiveScheduleRequest: MutableCluster.AsConditional( + MatterScheduleConfigurationComponent.commands.setActiveScheduleRequest, + { mandatoryIf: [MSCH] } + ), + setActivePresetRequest: MutableCluster.AsConditional( + PresetsComponent.commands.setActivePresetRequest, + { mandatoryIf: [PRES] } ) } }); diff --git a/packages/types/src/clusters/thread-border-router-management.ts b/packages/types/src/clusters/thread-border-router-management.ts new file mode 100644 index 0000000000..78f51a63ba --- /dev/null +++ b/packages/types/src/clusters/thread-border-router-management.ts @@ -0,0 +1,355 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { Command, TlvNoResponse, Attribute, FixedAttribute } from "../cluster/Cluster.js"; +import { TlvField, TlvObject, TlvOptionalField } from "../tlv/TlvObject.js"; +import { TlvByteString, TlvString } from "../tlv/TlvString.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { AccessLevel } from "#model"; +import { BitFlag } from "../schema/BitmapSchema.js"; +import { TlvUInt16, TlvUInt64 } from "../tlv/TlvNumber.js"; +import { TlvBoolean } from "../tlv/TlvBoolean.js"; +import { TlvNullable } from "../tlv/TlvNullable.js"; +import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace ThreadBorderRouterManagement { + /** + * These are optional features supported by ThreadBorderRouterManagementCluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.4 + */ + export enum Feature { + /** + * PanChange (PC) + * + * This feature shall indicate the ability of the Border Router to change its already configured PAN to + * another, by setting a pending dataset. + * + * NOTE + * + * This feature flag can be used to protect an already-configured network from accidental configuration change, + * e.g. when the Thread Border Router serves non-Matter devices that do not support PAN change for an + * implementation-specific reason. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.4.1 + */ + PanChange = "PanChange" + } + + /** + * Input to the ThreadBorderRouterManagement setPendingDatasetRequest command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.5 + */ + export const TlvSetPendingDatasetRequest = TlvObject({ + pendingDataset: TlvField(0, TlvByteString.bound({ maxLength: 254 })) + }); + + /** + * Input to the ThreadBorderRouterManagement setPendingDatasetRequest command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.5 + */ + export interface SetPendingDatasetRequest extends TypeFromSchema {} + + /** + * This command is sent in response to GetActiveDatasetRequest or GetPendingDatasetRequest command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.3 + */ + export const TlvDatasetResponse = TlvObject({ + /** + * If no dataset (active or pending as requested) is configured, this field shall be set to empty. + * + * Otherwise, this field shall contain the active or pending dataset of the Thread network to which the Border + * Router is connected as an octet string containing the raw Thread TLV value of the dataset, as defined in the + * Thread specification. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.3.1 + */ + dataset: TlvField(0, TlvByteString.bound({ maxLength: 254 })) + }); + + /** + * This command is sent in response to GetActiveDatasetRequest or GetPendingDatasetRequest command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.3 + */ + export interface DatasetResponse extends TypeFromSchema {} + + /** + * Input to the ThreadBorderRouterManagement setActiveDatasetRequest command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.4 + */ + export const TlvSetActiveDatasetRequest = TlvObject({ + /** + * This field shall contain the active dataset to set of the Thread network to configure in the Border Router + * as an octet string containing the raw Thread TLV value of the dataset, as defined in the Thread + * specification. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.4.1 + */ + activeDataset: TlvField(0, TlvByteString.bound({ maxLength: 254 })), + + /** + * See Breadcrumb Attribute section of General Commissioning Cluster in [MatterCore] for usage. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.4.2 + */ + breadcrumb: TlvOptionalField(1, TlvUInt64) + }); + + /** + * Input to the ThreadBorderRouterManagement setActiveDatasetRequest command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.4 + */ + export interface SetActiveDatasetRequest extends TypeFromSchema {} + + /** + * A ThreadBorderRouterManagementCluster supports these elements if it supports feature PanChange. + */ + export const PanChangeComponent = MutableCluster.Component({ + commands: { + /** + * This command shall be used to set or update the pending Dataset of the Thread network to which the + * Border Router is connected, if the Border Router supports PAN Change. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * UNSUPPORTED_ACCESS. + * + * This PendingDataset field shall contain the pending dataset to which the Thread network should be + * updated. The format of the data shall be an octet string containing the raw Thread TLV value of the + * pending dataset, as defined in the Thread specification. + * + * If any of the parameters in the PendingDataset is invalid, the command shall fail with a status of + * INVALID_COMMAND. + * + * Otherwise, this command shall configure the pending dataset of the Thread network to which the Border + * Router is connected, with the value given in the PendingDataset parameter. The Border Router will manage + * activation of the pending dataset as defined in the Thread specification. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.5 + */ + setPendingDatasetRequest: Command( + 0x4, + TlvSetPendingDatasetRequest, + 0x4, + TlvNoResponse, + { invokeAcl: AccessLevel.Manage, timed: true } + ) + } + }); + + /** + * These elements and properties are present in all ThreadBorderRouterManagement clusters. + */ + export const Base = MutableCluster.Component({ + id: 0x452, + name: "ThreadBorderRouterManagement", + revision: 1, + + features: { + /** + * PanChange + * + * This feature shall indicate the ability of the Border Router to change its already configured PAN to + * another, by setting a pending dataset. + * + * NOTE + * + * This feature flag can be used to protect an already-configured network from accidental configuration + * change, e.g. when the Thread Border Router serves non-Matter devices that do not support PAN change for + * an implementation-specific reason. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.4.1 + */ + panChange: BitFlag(0) + }, + + attributes: { + /** + * Indicates a user-friendly name identifying the device model or product of the Border Router in MeshCOP + * (DNS-SD service name) as defined in the Thread specification, and has the following recommended format: + * ._meshcop._udp. An example name would be ACME Border Router + * (74be)._meshcop._udp. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.5.1 + */ + borderRouterName: Attribute(0x0, TlvString.bound({ minLength: 1, maxLength: 63 })), + + /** + * Indicates a 16-byte globally unique ID for a Thread Border Router device. This ID is + * manufacturer-specific, and it is created and managed by the border router’s implementation. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.5.2 + */ + borderAgentId: Attribute(0x1, TlvByteString.bound({ length: 16 })), + + /** + * Indicates the Thread version supported by the Thread interface configured by the cluster instance. + * + * The format shall match the value mapping defined in the "Version TLV" section of the Thread + * specification. For example, Thread 1.3.0 would have ThreadVersion set to 4. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.5.3 + */ + threadVersion: FixedAttribute(0x2, TlvUInt16), + + /** + * Indicates whether the associated IEEE 802.15.4 Thread interface is enabled or disabled. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.5.4 + */ + interfaceEnabled: Attribute(0x3, TlvBoolean, { persistent: true, default: false }), + + /** + * Null if the Thread Border Router has no dataset configured, otherwise it shall be the timestamp value + * extracted from the Active Dataset value configured by the Thread Node to which the border router is + * connected. This attribute shall be updated when a new Active dataset is configured on the Thread network + * to which the border router is connected. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.5.5 + */ + activeDatasetTimestamp: Attribute(0x4, TlvNullable(TlvUInt64), { persistent: true, default: 0 }), + + /** + * Null if the Thread Border Router has no Pending dataset configured, otherwise it shall be the timestamp + * value extracted from the Pending Dataset value configured by the Thread Node to which the border router + * is connected. This attribute shall be updated when a new Pending dataset is configured on the Thread + * network to which the border router is connected. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.5.6 + */ + pendingDatasetTimestamp: Attribute(0x5, TlvNullable(TlvUInt64), { persistent: true, default: 0 }) + }, + + commands: { + /** + * This command shall be used to request the active operational dataset of the Thread network to which the + * border router is connected. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * UNSUPPORTED_ACCESS. + * + * If an internal error occurs, then this command shall fail with a FAILURE status code sent back to the + * initiator. + * + * Otherwise, this shall generate a DatasetResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.1 + */ + getActiveDatasetRequest: Command( + 0x0, + TlvNoArguments, + 0x2, + TlvDatasetResponse, + { invokeAcl: AccessLevel.Manage } + ), + + /** + * This command shall be used to request the pending dataset of the Thread network to which the border + * router is connected. + * + * If the command is not executed via a CASE session, the command shall fail with a status code of + * UNSUPPORTED_ACCESS. + * + * If an internal error occurs, then this command shall fail with a FAILURE status code sent back to the + * initiator. + * + * Otherwise, this shall generate a DatasetResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.2 + */ + getPendingDatasetRequest: Command( + 0x1, + TlvNoArguments, + 0x2, + TlvDatasetResponse, + { invokeAcl: AccessLevel.Manage } + ), + + /** + * This command shall be used to set the active Dataset of the Thread network to which the Border Router is + * connected, when there is no active dataset already. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3.6.4 + */ + setActiveDatasetRequest: Command( + 0x3, + TlvSetActiveDatasetRequest, + 0x3, + TlvNoResponse, + { invokeAcl: AccessLevel.Manage, timed: true } + ) + }, + + /** + * This metadata controls which ThreadBorderRouterManagementCluster elements matter.js activates for specific + * feature combinations. + */ + extensions: MutableCluster.Extensions({ flags: { panChange: true }, component: PanChangeComponent }) + }) + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster(Base); + + /** + * This cluster provides an interface for managing a Thread Border Router and the Thread network that it belongs + * to. Privileged nodes within the same fabric as a Thread Border Router can use these interfaces to request and + * set credentials information to the Thread network. + * + * ThreadBorderRouterManagementCluster supports optional features that you can enable with the + * ThreadBorderRouterManagementCluster.with() factory method. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.3 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + const PC = { panChange: true }; + + /** + * @see {@link Complete} + */ + export const CompleteInstance = MutableCluster({ + id: Cluster.id, + name: Cluster.name, + revision: Cluster.revision, + features: Cluster.features, + attributes: Cluster.attributes, + + commands: { + ...Cluster.commands, + setPendingDatasetRequest: MutableCluster.AsConditional( + PanChangeComponent.commands.setPendingDatasetRequest, + { mandatoryIf: [PC] } + ) + } + }); + + /** + * This cluster supports all ThreadBorderRouterManagement features. It may support illegal feature combinations. + * + * If you use this cluster you must manually specify which features are active and ensure the set of active + * features is legal per the Matter specification. + */ + export interface Complete extends Identity {} + + export const Complete: Complete = CompleteInstance; +} + +export type ThreadBorderRouterManagementCluster = ThreadBorderRouterManagement.Cluster; +export const ThreadBorderRouterManagementCluster = ThreadBorderRouterManagement.Cluster; +ClusterRegistry.register(ThreadBorderRouterManagement.Complete); diff --git a/packages/types/src/clusters/thread-network-diagnostics.ts b/packages/types/src/clusters/thread-network-diagnostics.ts index fbe1f12cba..595661b30a 100644 --- a/packages/types/src/clusters/thread-network-diagnostics.ts +++ b/packages/types/src/clusters/thread-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -301,7 +301,6 @@ export namespace ThreadNetworkDiagnostics { /** * This field shall specify if a link has been established to the Node for which this route table entry - * * corresponds. * * @see {@link MatterSpecification.v13.Core} § 11.14.5.5.10 @@ -683,10 +682,11 @@ export namespace ThreadNetworkDiagnostics { txAckedCount: OptionalAttribute(0x1a, TlvUInt32, { omitChanges: true, default: 0 }), /** - * The TxNoAckRequestedCount attribute shall indicate the total number of unique MAC frame transmission - * requests without requested acknowledgment. The TxNoAckRequestedCount attribute shall only be incremented - * by 1 for each MAC transmission request that is does not request acknowledgement regardless of the amount - * of CCA failures, CSMA-CA attempts, or retransmissions. + * The TxNoAckRequestedCount attribute shall indicate the total number of unique MAC frame + * + * transmission requests without requested acknowledgment. The TxNoAckRequestedCount attribute shall only + * be incremented by 1 for each MAC transmission request that is does not request acknowledgement + * regardless of the amount of CCA failures, CSMA-CA attempts, or retransmissions. * * @see {@link MatterSpecification.v13.Core} § 11.14.6.28 */ @@ -752,10 +752,11 @@ export namespace ThreadNetworkDiagnostics { txRetryCount: OptionalAttribute(0x21, TlvUInt32, { omitChanges: true, default: 0 }), /** - * The TxDirectMaxRetryExpiryCount attribute shall indicate the total number of unique MAC transmission - * packets that meet maximal retry limit for direct packets. The TxDirectMaxRetryExpiryCount attribute - * shall only be incremented by 1 for each unique MAC transmission packets that meets the maximal retry - * limit for direct packets. This value shall only be reset upon a Node reboot. + * The TxDirectMaxRetryExpiryCount attribute shall indicate the total number of unique MAC + * + * transmission packets that meet maximal retry limit for direct packets. The TxDirectMaxRetryExpiryCount + * attribute shall only be incremented by 1 for each unique MAC transmission packets that meets the maximal + * retry limit for direct packets. This value shall only be reset upon a Node reboot. * * @see {@link MatterSpecification.v13.Core} § 11.14.6.35 */ @@ -824,8 +825,9 @@ export namespace ThreadNetworkDiagnostics { rxBroadcastCount: OptionalAttribute(0x29, TlvUInt32, { omitChanges: true, default: 0 }), /** - * The RxDataCount attribute shall indicate the total number of received unique MAC Data frames. This value - * shall only be reset upon a Node reboot. + * The RxDataCount attribute shall indicate the total number of received unique MAC Data frames. + * + * This value shall only be reset upon a Node reboot. * * @see {@link MatterSpecification.v13.Core} § 11.14.6.43 */ @@ -901,8 +903,9 @@ export namespace ThreadNetworkDiagnostics { /** * The RxErrUnknownNeighborCount attribute shall indicate the total number of received unique MAC frame - * requests that have been dropped as a result of originating from an unknown neighbor device. This value - * shall only be reset upon a Node reboot. + * requests that have been dropped as a result of originating from an unknown neighbor + * + * device. This value shall only be reset upon a Node reboot. * * @see {@link MatterSpecification.v13.Core} § 11.14.6.52 */ @@ -952,7 +955,7 @@ export namespace ThreadNetworkDiagnostics { export const Base = MutableCluster.Component({ id: 0x35, name: "ThreadNetworkDiagnostics", - revision: 2, + revision: 3, features: { /** @@ -997,9 +1000,10 @@ export namespace ThreadNetworkDiagnostics { /** * The RoutingRole attribute shall indicate the role that this Node has within the routing of messages - * through the Thread network, as defined by RoutingRoleEnum. The potential roles are defined in the - * following table. A value of null shall indicate that the Thread interface is not currently configured or - * operational. + * through the Thread network, as defined by RoutingRoleEnum. The potential roles are defined + * + * in the following table. A value of null shall indicate that the Thread interface is not currently + * configured or operational. * * @see {@link MatterSpecification.v13.Core} § 11.14.6.2 */ @@ -1081,9 +1085,8 @@ export namespace ThreadNetworkDiagnostics { dataVersion: Attribute(0xb, TlvNullable(TlvUInt16.bound({ max: 255 }))), /** - * The StableDataVersion attribute shall indicate the Network Data Version for the stable subset of - * - * data the Node currently uses. Null if not attached to a Thread network. + * The StableDataVersion attribute shall indicate the Network Data Version for the stable subset of data + * the Node currently uses. Null if not attached to a Thread network. * * @see {@link MatterSpecification.v13.Core} § 11.14.6.13 */ @@ -1152,7 +1155,17 @@ export namespace ThreadNetworkDiagnostics { 0x3e, TlvArray(TlvEnum(), { maxLength: 4 }), { default: [] } - ) + ), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.14.6 + */ + extAddress: Attribute(0x3f, TlvNullable(TlvUInt64)), + + /** + * @see {@link MatterSpecification.v13.Core} § 11.14.6 + */ + rloc16: Attribute(0x40, TlvNullable(TlvUInt16)) }, events: { diff --git a/packages/types/src/clusters/thread-network-directory.ts b/packages/types/src/clusters/thread-network-directory.ts new file mode 100644 index 0000000000..627a46b81d --- /dev/null +++ b/packages/types/src/clusters/thread-network-directory.ts @@ -0,0 +1,256 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { WritableAttribute, Attribute, FixedAttribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; +import { TlvByteString, TlvString } from "../tlv/TlvString.js"; +import { TlvNullable } from "../tlv/TlvNullable.js"; +import { AccessLevel } from "#model"; +import { TlvArray } from "../tlv/TlvArray.js"; +import { TlvField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvUInt16, TlvUInt64, TlvUInt8 } from "../tlv/TlvNumber.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace ThreadNetworkDirectory { + /** + * Represents the data associated with a Thread Network. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.4.1 + */ + export const TlvThreadNetwork = TlvObject({ + /** + * This field shall indicate the Extended PAN ID from the OperationalDataset for the given Thread network. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.4.1.1 + */ + extendedPanId: TlvField(0, TlvByteString.bound({ length: 8 })), + + /** + * This field shall indicate the Network Name from the OperationalDataset for the given Thread network. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.4.1.2 + */ + networkName: TlvField(1, TlvString.bound({ minLength: 1, maxLength: 16 })), + + /** + * This field shall indicate the Channel from the OperationalDataset for the given Thread network. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.4.1.3 + */ + channel: TlvField(2, TlvUInt16), + + /** + * This field shall indicate the Active Timestamp from the OperationalDataset for the given Thread network. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.4.1.4 + */ + activeTimestamp: TlvField(3, TlvUInt64) + }); + + /** + * Represents the data associated with a Thread Network. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.4.1 + */ + export interface ThreadNetwork extends TypeFromSchema {} + + /** + * Input to the ThreadNetworkDirectory addNetwork command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.1 + */ + export const TlvAddNetworkRequest = TlvObject({ + /** + * This field shall represent the Operational Dataset for the network, using the encoding defined in the Thread + * specification. It shall contain at least the following sub-TLVs: Active Timestamp, Channel, Channel Mask, + * Extended PAN ID, Network Key, Network Mesh-Local Prefix, Network Name, PAN ID, PSKc, and Security Policy. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.1.1 + */ + operationalDataset: TlvField(0, TlvByteString.bound({ maxLength: 254 })) + }); + + /** + * Input to the ThreadNetworkDirectory addNetwork command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.1 + */ + export interface AddNetworkRequest extends TypeFromSchema {} + + /** + * Input to the ThreadNetworkDirectory removeNetwork command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.2 + */ + export const TlvRemoveNetworkRequest = TlvObject({ extendedPanId: TlvField(0, TlvByteString.bound({ length: 8 })) }); + + /** + * Input to the ThreadNetworkDirectory removeNetwork command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.2 + */ + export interface RemoveNetworkRequest extends TypeFromSchema {} + + /** + * Input to the ThreadNetworkDirectory getOperationalDataset command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.3 + */ + export const TlvGetOperationalDatasetRequest = TlvObject({ + extendedPanId: TlvField(0, TlvByteString.bound({ length: 8 })) + }); + + /** + * Input to the ThreadNetworkDirectory getOperationalDataset command + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.3 + */ + export interface GetOperationalDatasetRequest extends TypeFromSchema {} + + /** + * Contains the Thread Operational Dataset for the Extended PAN specified in GetOperationalDataset. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.4 + */ + export const TlvOperationalDatasetResponse = TlvObject({ + operationalDataset: TlvField(0, TlvByteString.bound({ maxLength: 254 })) + }); + + /** + * Contains the Thread Operational Dataset for the Extended PAN specified in GetOperationalDataset. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.4 + */ + export interface OperationalDatasetResponse extends TypeFromSchema {} + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster({ + id: 0x453, + name: "ThreadNetworkDirectory", + revision: 1, + + attributes: { + /** + * Indicates the Thread Extended PAN ID value for the Thread network designated by the user to be their + * preferred network for commissioning of Thread devices. If not null, the value of this attribute shall + * match the ExtendedPanID of a network in the ThreadNetworks attribute. A write operation with a non-null + * value that does not match any network in the ThreadNetworks list shall be rejected with a status of + * CONSTRAINT_ERROR. + * + * The purpose of designating one Thread network as preferred is to help a commissioner to select a Thread + * network when a Thread device is within suitable range of more than one Thread network which appears in + * the ThreadNetworks list. A value of null indicates that there is no current preferred network: All + * networks may be treated as equally preferred by a commissioner with access to this cluster. + * + * This attribute may be automatically set to the ExtendedPanID of the first Thread network added to the + * ThreadNetworks list. + * + * A client shall obtain user consent before changing the value of this attribute from a non-null value. + * + * On a factory reset this attribute shall be reset to null. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.5.1 + */ + preferredExtendedPanId: WritableAttribute( + 0x0, + TlvNullable(TlvByteString.bound({ length: 8 })), + { persistent: true, default: null, writeAcl: AccessLevel.Manage } + ), + + /** + * Indicates the list of Thread Networks known about by this cluster. If the node hosting this cluster + * includes a Thread Border Router, then an entry for its Thread Network shall be included in this list. + * + * The list can be modified via the AddNetwork and RemoveNetwork commands. + * + * For each entry in the list, the cluster server also stores a Thread Operational Dataset. Clients use the + * GetOperationalDataset command to obtain the Operational Dataset for an entry in this list. + * + * On a factory reset this list shall be cleared, and any Thread Operational datasets previously stored + * shall be removed from the Node. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.5.2 + */ + threadNetworks: Attribute(0x1, TlvArray(TlvThreadNetwork), { persistent: true, default: [] }), + + /** + * Indicates the maximum number of entries that can be held in the ThreadNetworks list; it shall be at + * least 2 times the number of SupportedFabrics advertised in the Operational Credentials Cluster on the + * root endpoint of this node. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.5.3 + */ + threadNetworkTableSize: FixedAttribute(0x2, TlvUInt8, { default: 10 }) + }, + + commands: { + /** + * Adds an entry to the ThreadNetworks attribute with the specified Thread Operational Dataset. + * + * If there is an existing entry with the Extended PAN ID then the Thread Operational Dataset for that + * entry is replaced. As a result, changes to the network parameters (e.g. Channel, Network Name, PSKc, …) + * of an existing entry with a given Extended PAN ID can be made using this command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.1 + */ + addNetwork: Command( + 0x0, + TlvAddNetworkRequest, + 0x0, + TlvNoResponse, + { invokeAcl: AccessLevel.Manage, timed: true } + ), + + /** + * Removes the network with the given Extended PAN ID from the ThreadNetworks attribute. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.2 + */ + removeNetwork: Command( + 0x1, + TlvRemoveNetworkRequest, + 0x1, + TlvNoResponse, + { invokeAcl: AccessLevel.Manage, timed: true } + ), + + /** + * Retrieves the Thread Operational Dataset with the given Extended PAN ID. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4.6.3 + */ + getOperationalDataset: Command( + 0x2, + TlvGetOperationalDatasetRequest, + 0x3, + TlvOperationalDatasetResponse, + { invokeAcl: AccessLevel.Manage } + ) + } + }); + + /** + * This cluster stores a list of Thread networks (including the credentials required to access each network), as + * well as a designation of the user’s preferred network, to facilitate the sharing of Thread networks across + * fabrics. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.4 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + export const Complete = Cluster; +} + +export type ThreadNetworkDirectoryCluster = ThreadNetworkDirectory.Cluster; +export const ThreadNetworkDirectoryCluster = ThreadNetworkDirectory.Cluster; +ClusterRegistry.register(ThreadNetworkDirectory.Complete); diff --git a/packages/types/src/clusters/time-format-localization.ts b/packages/types/src/clusters/time-format-localization.ts index 3b13e0d053..72003f468b 100644 --- a/packages/types/src/clusters/time-format-localization.ts +++ b/packages/types/src/clusters/time-format-localization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/time-synchronization.ts b/packages/types/src/clusters/time-synchronization.ts index 42a70ee405..c012668e87 100644 --- a/packages/types/src/clusters/time-synchronization.ts +++ b/packages/types/src/clusters/time-synchronization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -298,10 +298,9 @@ export namespace TimeSynchronization { */ export const TlvSetTimeZoneResponse = TlvObject({ /** - * If the node supports a time zone database with information for the time zone that will be applied, it - * - * may use this information to set the DSTOffset attribute. If the node is setting its own DSTOffset attribute, - * the DSTOffsetsRequired field shall be set to false, otherwise it shall be set to true. + * If the node supports a time zone database with information for the time zone that will be applied, it may + * use this information to set the DSTOffset attribute. If the node is setting its own DSTOffset attribute, the + * DSTOffsetsRequired field shall be set to false, otherwise it shall be set to true. * * @see {@link MatterSpecification.v13.Core} § 11.17.9.4.1 */ @@ -334,7 +333,15 @@ export namespace TimeSynchronization { * * @see {@link MatterSpecification.v13.Core} § 11.17.10.2 */ - export const TlvDstStatusEvent = TlvObject({ dstOffsetActive: TlvField(0, TlvBoolean) }); + export const TlvDstStatusEvent = TlvObject({ + /** + * Indicates whether the current DST offset is being applied (i.e, daylight savings time is applied, as opposed + * to standard time). + * + * @see {@link MatterSpecification.v13.Core} § 11.17.10.2.1 + */ + dstOffsetActive: TlvField(0, TlvBoolean) + }); /** * Body of the TimeSynchronization dstStatus event @@ -513,14 +520,14 @@ export namespace TimeSynchronization { utcTime: TlvField(0, TlvEpochUs), /** - * This shall give the Client’s Granularity, as described in Section 11.17.8.2, “Granularity Attribute”. + * This shall give the Client’s Granularity, as described in Granularity. * * @see {@link MatterSpecification.v13.Core} § 11.17.9.1.2 */ granularity: TlvField(1, TlvEnum()), /** - * This shall give the Client’s TimeSource, as described in Section 11.17.8.3, “TimeSource Attribute”. + * This shall give the Client’s TimeSource, as described in TimeSource. * * @see {@link MatterSpecification.v13.Core} § 11.17.9.1.3 */ @@ -551,8 +558,9 @@ export namespace TimeSynchronization { attributes: { /** * A Node ID, endpoint, and associated fabric index of a Node that may be used as trusted time source. See - * Time source prioritization. This attribute reflects the last value set by an administrator using the - * SetTrustedTimeSource command. If the value is null, no trusted time source has yet been set. + * Section 11.17.13, “Time source prioritization”. This attribute reflects the last value set by an + * administrator using the SetTrustedTimeSource command. If the value is null, no trusted time source has + * yet been set. * * @see {@link MatterSpecification.v13.Core} § 11.17.8.4 */ @@ -561,11 +569,14 @@ export namespace TimeSynchronization { commands: { /** - * This command shall set the TrustedTimeSource attribute. Upon receipt of this command, * If the - * TrustedTimeSource field in the command is null, the node shall set the TrustedTimeSource attribute to - * null and shall generate a MissingTrustedTimeSource event. * Otherwise, the node shall set the - * TrustedTimeSource attribute to a struct which has NodeID and Endpoint fields matching those in the - * TrustedTimeSource field and has its FabricIndex field set to the command’s accessing fabric index. + * This command shall set the TrustedTimeSource attribute. Upon receipt of this command: + * + * • If the TrustedTimeSource field in the command is null, the node shall set the TrustedTimeSource + * attribute to null and shall generate a MissingTrustedTimeSource event. + * + * • Otherwise, the node shall set the TrustedTimeSource attribute to a struct which has NodeID and + * Endpoint fields matching those in the TrustedTimeSource field and has its FabricIndex field set to + * the command’s accessing fabric index. * * @see {@link MatterSpecification.v13.Core} § 11.17.9.2 */ @@ -658,7 +669,6 @@ export namespace TimeSynchronization { * savings time). * * The first entry shall have a ValidAt entry of 0. If there is a second entry, it shall have a non-zero - * * ValidAt time. * * If a node supports a TimeZoneDatabase, and it has data for the given time zone Name and the given Offset @@ -780,7 +790,8 @@ export namespace TimeSynchronization { * This command is used to set the DST offsets for a node. * * • If the length of DSTOffset is larger than DSTOffsetListMaxSize, the node shall respond with - * RESOURCE_EXHAUSTED. + * + * RESOURCE_EXHAUSTED. * * • Else if the list entries do not conform to the list requirements for DSTOffset attribute, the node * shall respond with CONSTRAINT_ERROR. @@ -815,11 +826,6 @@ export namespace TimeSynchronization { /** * This event shall be generated when the node starts or stops applying a DST offset. * - * DSTOffsetActive - * - * Indicates whether the current DST offset is being applied (i.e, daylight savings time is applied, as - * opposed to standard time). - * * @see {@link MatterSpecification.v13.Core} § 11.17.10.2 */ dstStatus: Event(0x1, EventPriority.Info, TlvDstStatusEvent), @@ -944,8 +950,9 @@ export namespace TimeSynchronization { * time source, it may send a Granularity of NoTimeGranularity. * * Upon receipt of this command, the node may update its UTCTime attribute to match the time specified in - * the command, if the stated Granularity and TimeSource are acceptable. The node shall update its UTCTime - * attribute if its current Granularity is NoTimeGranularity. + * the command, if the stated Granularity and TimeSource are acceptable. The node shall + * + * update its UTCTime attribute if its current Granularity is NoTimeGranularity. * * If the time is updated, the node shall also update its Granularity attribute based on the granularity * specified in the command and the expected clock drift of the node. This SHOULD normally be one level diff --git a/packages/types/src/clusters/total-volatile-organic-compounds-concentration-measurement.ts b/packages/types/src/clusters/total-volatile-organic-compounds-concentration-measurement.ts index 6d081308b9..670a2b2006 100644 --- a/packages/types/src/clusters/total-volatile-organic-compounds-concentration-measurement.ts +++ b/packages/types/src/clusters/total-volatile-organic-compounds-concentration-measurement.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/unit-localization.ts b/packages/types/src/clusters/unit-localization.ts index 7764aaa7df..106acb0f9a 100644 --- a/packages/types/src/clusters/unit-localization.ts +++ b/packages/types/src/clusters/unit-localization.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -100,10 +100,9 @@ export namespace UnitLocalization { /** * Nodes should be expected to be deployed to any and all regions of the world. These global regions may have - * differing preferences for the units in which values are conveyed in communication to a - * - * user. As such, Nodes that visually or audibly convey measurable values to the user need a mechanism by which - * they can be configured to use a user’s preferred unit. + * differing preferences for the units in which values are conveyed in communication to a user. As such, Nodes that + * visually or audibly convey measurable values to the user need a mechanism by which they can be configured to use + * a user’s preferred unit. * * This cluster supports an interface to a Node. It provides attributes for determining and configuring the units * that a Node shall utilize when conveying values in communication to a user. diff --git a/packages/types/src/clusters/user-label.ts b/packages/types/src/clusters/user-label.ts index 1cd9867a8d..04e00138c7 100644 --- a/packages/types/src/clusters/user-label.ts +++ b/packages/types/src/clusters/user-label.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -39,7 +39,8 @@ export namespace UserLabel { }); /** - * This cluster provides a feature to tag an endpoint with zero or more labels. + * This cluster is derived from the Label cluster and provides a feature to tag an endpoint with zero or more + * writable labels. * * @see {@link MatterSpecification.v13.Core} § 9.9 */ diff --git a/packages/types/src/clusters/valid-proxies.ts b/packages/types/src/clusters/valid-proxies.ts index 7c55ec2be7..7677e91977 100644 --- a/packages/types/src/clusters/valid-proxies.ts +++ b/packages/types/src/clusters/valid-proxies.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/valve-configuration-and-control.ts b/packages/types/src/clusters/valve-configuration-and-control.ts index 7408527fea..0b760ca7fa 100644 --- a/packages/types/src/clusters/valve-configuration-and-control.ts +++ b/packages/types/src/clusters/valve-configuration-and-control.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/wake-on-lan.ts b/packages/types/src/clusters/wake-on-lan.ts index 351695ec37..7eadc4d8a6 100644 --- a/packages/types/src/clusters/wake-on-lan.ts +++ b/packages/types/src/clusters/wake-on-lan.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/clusters/water-heater-management.ts b/packages/types/src/clusters/water-heater-management.ts new file mode 100644 index 0000000000..b7a029dfc1 --- /dev/null +++ b/packages/types/src/clusters/water-heater-management.ts @@ -0,0 +1,457 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { Attribute, FixedAttribute, Command, TlvNoResponse, Event, EventPriority } from "../cluster/Cluster.js"; +import { + TlvUInt16, + TlvInt64, + TlvPercent, + TlvUInt8, + TlvBitmap, + TlvEnum, + TlvUInt32, + TlvInt16 +} from "../tlv/TlvNumber.js"; +import { BitFlag } from "../schema/BitmapSchema.js"; +import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvBoolean } from "../tlv/TlvBoolean.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { AccessLevel } from "#model"; +import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace WaterHeaterManagement { + /** + * These are optional features supported by WaterHeaterManagementCluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.4 + */ + export enum Feature { + /** + * EnergyManagement (EM) + * + * Allows energy management control of the tank + */ + EnergyManagement = "EnergyManagement", + + /** + * TankPercent (TP) + * + * Supports monitoring the percentage of hot water in the tank + */ + TankPercent = "TankPercent" + } + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.1 + */ + export const WaterHeaterHeatSource = { + /** + * Immersion Heating Element 1 + */ + immersionElement1: BitFlag(0), + + /** + * Immersion Heating Element 2 + */ + immersionElement2: BitFlag(1), + + /** + * Heat pump Heating + */ + heatPump: BitFlag(2), + + /** + * Boiler Heating (e.g. Gas or Oil) + */ + boiler: BitFlag(3), + + /** + * Other Heating + */ + other: BitFlag(4) + }; + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.2 + */ + export enum BoostState { + /** + * Boost is not currently active + */ + Inactive = 0, + + /** + * Boost is currently active + */ + Active = 1 + } + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3 + */ + export const TlvWaterHeaterBoostInfo = TlvObject({ + /** + * This field shall indicate the time period, in seconds, for which the boost state is activated. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3.1 + */ + duration: TlvField(0, TlvUInt32.bound({ min: 1 })), + + /** + * This field shall indicate whether the boost state shall be automatically canceled once the hot water has + * reached either: + * + * • the set point temperature (from the thermostat cluster) + * + * • the TemporarySetpoint temperature (if specified) + * + * • the TargetPercentage (if specified). + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3.2 + */ + oneShot: TlvOptionalField(1, TlvBoolean), + + /** + * This field shall indicate that the consumer wants the water to be heated quickly. This may cause multiple + * heat sources to be activated (e.g. a heat pump and direct electric immersion heating element). + * + * The choice of which heat sources are activated is manufacturer specific. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3.3 + */ + emergencyBoost: TlvOptionalField(2, TlvBoolean), + + /** + * This field shall indicate the target temperature to which the water will be heated. + * + * If included, it shall be used instead of the thermostat cluster set point temperature whilst the boost state + * is activated. + * + * The value of this field shall be within the constraints of the MinHeatSetpointLimit and MaxHeatSetpointLimit + * attributes (inclusive), of the thermostat cluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3.4 + */ + temporarySetpoint: TlvOptionalField(3, TlvInt16), + + /** + * This field shall indicate the target percentage of hot water in the tank that the TankPercentage attribute + * must reach before the heating is switched off. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3.5 + */ + targetPercentage: TlvOptionalField(4, TlvPercent), + + /** + * This field shall indicate the percentage to which the hot water in the tank shall be allowed to fall before + * again beginning to reheat it. + * + * For example if the TargetPercentage was 80%, and the TargetReheat was 40%, then after initial heating to 80% + * hot water, the tank may have hot water drawn off until only 40% hot water remains. At this point the heater + * will begin to heat back up to 80% of hot water. If this field and the OneShot field were both omitted, + * heating would begin again after any water draw which reduced the TankPercentage below 80%. + * + * This field shall be less than or equal to the TargetPercentage field. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3.6 + */ + targetReheat: TlvOptionalField(5, TlvPercent) + }); + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.5.6.3 + */ + export interface WaterHeaterBoostInfo extends TypeFromSchema {} + + /** + * Input to the WaterHeaterManagement boost command + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.8.1 + */ + export const TlvBoostRequest = TlvObject({ boostInfo: TlvField(0, TlvWaterHeaterBoostInfo) }); + + /** + * Input to the WaterHeaterManagement boost command + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.8.1 + */ + export interface BoostRequest extends TypeFromSchema {} + + /** + * Body of the WaterHeaterManagement boostStarted event + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.9.1 + */ + export const TlvBoostStartedEvent = TlvObject({ boostInfo: TlvField(0, TlvWaterHeaterBoostInfo) }); + + /** + * Body of the WaterHeaterManagement boostStarted event + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.9.1 + */ + export interface BoostStartedEvent extends TypeFromSchema {} + + /** + * A WaterHeaterManagementCluster supports these elements if it supports feature EnergyManagement. + */ + export const EnergyManagementComponent = MutableCluster.Component({ + attributes: { + /** + * Indicates the volume of water that the hot water tank can hold (in units of Litres). This allows an + * energy management system to estimate the required heating energy needed to reach the target temperature. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.7.3 + */ + tankVolume: Attribute(0x2, TlvUInt16, { default: 0 }), + + /** + * Indicates the estimated heat energy needed to raise the water temperature to the target setpoint. This + * can be computed by taking the specific heat capacity of water (4182 J/kg °C) and by knowing the current + * temperature of the water, the tank volume and target temperature. + * + * For example, if the target temperature was 60°C, the current temperature was 20°C and the tank volume + * was 100L: + * + * Mass of water = 1kg per Litre + * + * Total Mass = 100 x 1kg = 100kg + * + * Δ Temperature = (target temperature - current temperature) + * + * = (60°C - 20°C) = 40°C + * + * Energy required to + * + * heat the water to 60°C = 4182 x 40 x 100 = 16,728,000 J + * + * Converting Joules in to Wh of heat (divide by 3600): + * + * If the TankPercent feature is supported, then this estimate shall also take into account the percentage + * of the water in the tank which is already hot. + * + * NOTE + * + * The electrical energy required to heat the water depends on the heating system used to heat the water. + * For example, a direct electric immersion heating element can be close to 100% efficient, so the + * electrical energy needed to heat the hot water is nearly the same as the EstimatedHeatEnergyRequired. + * However some forms of heating, such as an air-source heat pump which extracts heat from ambient air, + * requires much less electrical energy to heat hot water. Heat pumps can be produce 3kWh of heat output + * for 1kWh of electrical energy input. The conversion between heat energy and electrical energy is outside + * the scope of this cluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.7.4 + */ + estimatedHeatRequired: Attribute(0x3, TlvInt64.bound({ min: 0 }), { default: 0 }) + } + }); + + /** + * A WaterHeaterManagementCluster supports these elements if it supports feature TankPercent. + */ + export const TankPercentComponent = MutableCluster.Component({ + attributes: { + /** + * Indicates an approximate level of hot water stored in the tank, which might help consumers understand + * the amount of hot water remaining in the tank. The accuracy of this attribute is manufacturer specific. + * + * In most hot water tanks, there is a stratification effect where the hot water layer rests above a cooler + * layer of water below. For this reason cold water is fed in at the bottom of the tank and the hot water + * is drawn from the top. + * + * Some water tanks might use multiple temperature probes to estimate the level of the hot water layer. A + * water heater with multiple temperature probes is likely to implement an algorithm to estimate the hot + * water tank percentage by taking into account the temperature values of each probe to determine the + * height of the hot water. + * + * However it might be possible with a single temperature probe to estimate how much hot water is left + * using a simpler algorithm: + * + * For example, if the target temperature was 60°C, the CurrentTemperature was 40°C from a single + * temperature probe measuring the average water temperature and the temperature of incoming cold water + * (COLD_WATER_TEMP) was assumed to be 20°C: + * + * TankPercentage = int(((current temperature - COLD_WATER_TEMP) / (target temperature - COLD_WATER_TEMP)) + * * 100) + * + * TankPercentage = min( max(TankPercentage,0), 100) + * + * TankPercentage = 50% + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.7.5 + */ + tankPercentage: Attribute(0x4, TlvPercent, { default: 0 }) + } + }); + + /** + * These elements and properties are present in all WaterHeaterManagement clusters. + */ + export const Base = MutableCluster.Component({ + id: 0x94, + name: "WaterHeaterManagement", + revision: 2, + + features: { + /** + * EnergyManagement + * + * Allows energy management control of the tank + */ + energyManagement: BitFlag(0), + + /** + * TankPercent + * + * Supports monitoring the percentage of hot water in the tank + */ + tankPercent: BitFlag(1) + }, + + attributes: { + /** + * Indicates the heat sources that the water heater can call on for heating. If a bit is set then the water + * heater supports the corresponding heat source. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.7.1 + */ + heaterTypes: FixedAttribute(0x0, TlvBitmap(TlvUInt8, WaterHeaterHeatSource)), + + /** + * Indicates if the water heater is heating water. If a bit is set then the corresponding heat source is + * active. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.7.2 + */ + heatDemand: Attribute(0x1, TlvBitmap(TlvUInt8, WaterHeaterHeatSource)), + + /** + * Indicates whether the Boost, as triggered by a Boost command, is currently + * + * Active or Inactive. + * + * See Boost and CancelBoost commands for more details. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.7.6 + */ + boostState: Attribute(0x5, TlvEnum(), { default: BoostState.Inactive }) + }, + + commands: { + /** + * Allows a client to request that the water heater is put into a Boost state. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.8.1 + */ + boost: Command(0x0, TlvBoostRequest, 0x0, TlvNoResponse, { invokeAcl: AccessLevel.Manage }), + + /** + * Allows a client to cancel an ongoing Boost operation. This command has no payload. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.8.2 + */ + cancelBoost: Command(0x1, TlvNoArguments, 0x1, TlvNoResponse, { invokeAcl: AccessLevel.Manage }) + }, + + events: { + /** + * This event shall be generated whenever a Boost command is accepted. + * + * The corresponding structure fields within the WaterHeaterBoostInfoStruct are copied from the Boost + * command. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.9.1 + */ + boostStarted: Event(0x0, EventPriority.Info, TlvBoostStartedEvent), + + /** + * This event shall be generated whenever the BoostState transitions from Active to Inactive. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5.9.2 + */ + boostEnded: Event(0x1, EventPriority.Info, TlvNoArguments) + }, + + /** + * This metadata controls which WaterHeaterManagementCluster elements matter.js activates for specific feature + * combinations. + */ + extensions: MutableCluster.Extensions( + { flags: { energyManagement: true }, component: EnergyManagementComponent }, + { flags: { tankPercent: true }, component: TankPercentComponent } + ) + }); + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster(Base); + + /** + * This cluster is used to allow clients to control the operation of a hot water heating appliance so that it can + * be used with energy management. + * + * Heating of hot water is one of the main energy uses in homes, and when coupled with the Energy Management + * cluster, it can help consumers save cost (e.g. using power at cheaper times or from local solar PV generation). + * + * WaterHeaterManagementCluster supports optional features that you can enable with the + * WaterHeaterManagementCluster.with() factory method. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.5 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + const EM = { energyManagement: true }; + const TP = { tankPercent: true }; + + /** + * @see {@link Complete} + */ + export const CompleteInstance = MutableCluster({ + id: Cluster.id, + name: Cluster.name, + revision: Cluster.revision, + features: Cluster.features, + + attributes: { + ...Cluster.attributes, + tankVolume: MutableCluster.AsConditional( + EnergyManagementComponent.attributes.tankVolume, + { mandatoryIf: [EM] } + ), + estimatedHeatRequired: MutableCluster.AsConditional( + EnergyManagementComponent.attributes.estimatedHeatRequired, + { mandatoryIf: [EM] } + ), + tankPercentage: MutableCluster.AsConditional( + TankPercentComponent.attributes.tankPercentage, + { mandatoryIf: [TP] } + ) + }, + + commands: Cluster.commands, + events: Cluster.events + }); + + /** + * This cluster supports all WaterHeaterManagement features. It may support illegal feature combinations. + * + * If you use this cluster you must manually specify which features are active and ensure the set of active + * features is legal per the Matter specification. + */ + export interface Complete extends Identity {} + + export const Complete: Complete = CompleteInstance; +} + +export type WaterHeaterManagementCluster = WaterHeaterManagement.Cluster; +export const WaterHeaterManagementCluster = WaterHeaterManagement.Cluster; +ClusterRegistry.register(WaterHeaterManagement.Complete); diff --git a/packages/types/src/clusters/water-heater-mode.ts b/packages/types/src/clusters/water-heater-mode.ts new file mode 100644 index 0000000000..c8368572dd --- /dev/null +++ b/packages/types/src/clusters/water-heater-mode.ts @@ -0,0 +1,301 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { BitFlag } from "../schema/BitmapSchema.js"; +import { FixedAttribute, Attribute, Command, TlvNoResponse } from "../cluster/Cluster.js"; +import { TlvArray } from "../tlv/TlvArray.js"; +import { TlvField, TlvOptionalField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvString } from "../tlv/TlvString.js"; +import { TlvUInt8, TlvEnum } from "../tlv/TlvNumber.js"; +import { TlvVendorId } from "../datatype/VendorId.js"; +import { ModeBase } from "./mode-base.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace WaterHeaterMode { + /** + * These are optional features supported by WaterHeaterModeCluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.6.4 + */ + export enum Feature { + /** + * OnOff (DEPONOFF) + * + * Dependency with the OnOff cluster + */ + OnOff = "OnOff" + } + + export enum ModeTag { + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + Auto = 0, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + Quick = 1, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + Quiet = 2, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + LowNoise = 3, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + LowEnergy = 4, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + Vacation = 5, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + Min = 6, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + Max = 7, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + Night = 8, + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1 + */ + Day = 9, + + /** + * While in modes with this tag, the device will not attempt to keep the water warm. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1.1 + */ + Off = 16384, + + /** + * While in modes with this tag, the device will attempt to keep the water warm based on the + * OccupiedHeatingSetpoint attribute of the associated Thermostat cluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1.2 + */ + Manual = 16385, + + /** + * While in modes with this tag, the device will attempt to keep the water warm based on the Schedules + * attribute of the associated Thermostat cluster. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.6.7.1.3 + */ + Timed = 16386 + } + + /** + * A Mode Tag is meant to be interpreted by the client for the purpose the cluster serves. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1 + */ + export const TlvModeTagStruct = TlvObject({ + /** + * If the MfgCode field exists, the Value field shall be in the manufacturer-specific value range (see Section + * 1.10.8, “Mode Namespace”). + * + * This field shall indicate the manufacturer’s VendorID and it shall determine the meaning of the Value field. + * + * The same manufacturer code and mode tag value in separate cluster instances are part of the same namespace + * and have the same meaning. For example: a manufacturer tag meaning "pinch" can be used both in a cluster + * whose purpose is to choose the amount of sugar, or in a cluster whose purpose is to choose the amount of + * salt. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.1 + */ + mfgCode: TlvOptionalField(0, TlvVendorId), + + /** + * This field shall indicate the mode tag within a mode tag namespace which is either manufacturer specific or + * standard. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1.2 + */ + value: TlvField(1, TlvEnum()) + }); + + /** + * A Mode Tag is meant to be interpreted by the client for the purpose the cluster serves. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.1 + */ + export interface ModeTagStruct extends TypeFromSchema {} + + /** + * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. + * A blank field indicates no change. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.6.5.1 + */ + export const TlvModeOption = TlvObject({ + /** + * This field shall indicate readable text that describes the mode option, so that a client can provide it to + * the user to indicate what this option means. This field is meant to be readable and understandable by the + * user. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.2.1 + */ + label: TlvField(0, TlvString.bound({ maxLength: 64 })), + + /** + * This field is used to identify the mode option. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.2.2 + */ + mode: TlvField(1, TlvUInt8), + + /** + * This field shall contain a list of tags that are associated with the mode option. This may be used by + * clients to determine the full or the partial semantics of a certain mode, depending on which tags they + * understand, using standard definitions and/or manufacturer specific namespace definitions. + * + * The standard mode tags are defined in this cluster specification. For the derived cluster instances, if the + * specification of the derived cluster defines a namespace, the set of standard mode tags also includes the + * mode tag values from that namespace. + * + * Mode tags can help clients look for options that meet certain criteria, render the user interface, use + * + * the mode in an automation, or to craft help text their voice-driven interfaces. A mode tag shall be either a + * standard tag or a manufacturer specific tag, as defined in each ModeTagStruct list entry. + * + * A mode option may have more than one mode tag. A mode option may be associated with a mixture of standard + * and manufacturer specific mode tags. A mode option shall be associated with at least one standard mode tag. + * + * A few examples are provided below. + * + * • A mode named "100%" can have both the High (manufacturer specific) and Max (standard) mode tag. Clients + * seeking the mode for either High or Max will find the same mode in this case. + * + * • A mode that includes a LowEnergy tag can be displayed by the client using a widget icon that shows a + * green leaf. + * + * • A mode that includes a LowNoise tag may be used by the client when the user wishes for a lower level of + * audible sound, less likely to disturb the household’s activities. + * + * • A mode that includes a LowEnergy tag (standard, defined in this cluster specification) and also a + * Delicate tag (standard, defined in the namespace of a Laundry Mode derived cluster). + * + * • A mode that includes both a generic Quick tag (defined here), and Vacuum and Mop tags, (defined in the + * RVC Clean cluster that is a derivation of this cluster). + * + * @see {@link MatterSpecification.v13.Cluster} § 1.10.5.2.3 + */ + modeTags: TlvField(2, TlvArray(TlvModeTagStruct, { maxLength: 8 })) + }); + + /** + * The table below lists the changes relative to the Mode Base cluster for the fields of the ModeOptionStruct type. + * A blank field indicates no change. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.6.5.1 + */ + export interface ModeOption extends TypeFromSchema {} + + /** + * These elements and properties are present in all WaterHeaterMode clusters. + */ + export const Base = MutableCluster.Component({ + id: 0x9e, + name: "WaterHeaterMode", + revision: 1, + + features: { + /** + * OnOff + * + * Dependency with the OnOff cluster + */ + onOff: BitFlag(0) + }, + + attributes: { + /** + * At least one entry in the SupportedModes attribute shall include the Manual mode tag in the ModeTags + * field list. + * + * At least one entry in the SupportedModes attribute shall include the Off mode tag in the ModeTags field + * list. + * + * An entry in the SupportedModes attribute that includes one of an Off, Manual, or Timed tag shall NOT + * also include an additional instance of any one of these tag types. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.6.6.1 + */ + supportedModes: FixedAttribute( + 0x0, + TlvArray(TlvModeOption, { minLength: 2, maxLength: 255 }), + { default: [] } + ), + + /** + * @see {@link MatterSpecification.v13.Cluster} § 9.6.6 + */ + currentMode: Attribute(0x1, TlvUInt8, { persistent: true }) + }, + + commands: { + /** + * This command is used to change device modes. + * + * On receipt of this command the device shall respond with a ChangeToModeResponse command. + * + * @see {@link MatterSpecification.v13.Cluster} § 1.10.7.1 + */ + changeToMode: Command(0x0, ModeBase.TlvChangeToModeRequest, 0x0, TlvNoResponse) + }, + + /** + * This metadata controls which WaterHeaterModeCluster elements matter.js activates for specific feature + * combinations. + */ + extensions: MutableCluster.Extensions({ flags: { onOff: true }, component: false }) + }); + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster(Base); + + /** + * This cluster is derived from the Mode Base cluster and defines additional mode tags and namespaced enumerated + * values for water heater devices. + * + * WaterHeaterModeCluster supports optional features that you can enable with the WaterHeaterModeCluster.with() + * factory method. + * + * @see {@link MatterSpecification.v13.Cluster} § 9.6 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + export const Complete = Cluster; +} + +export type WaterHeaterModeCluster = WaterHeaterMode.Cluster; +export const WaterHeaterModeCluster = WaterHeaterMode.Cluster; +ClusterRegistry.register(WaterHeaterMode.Complete); diff --git a/packages/types/src/clusters/water-tank-level-monitoring.ts b/packages/types/src/clusters/water-tank-level-monitoring.ts new file mode 100644 index 0000000000..de4237f75c --- /dev/null +++ b/packages/types/src/clusters/water-tank-level-monitoring.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { ResourceMonitoring } from "./resource-monitoring.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace WaterTankLevelMonitoring { + export const Base = { ...ResourceMonitoring.Base, id: 0x79, name: "WaterTankLevelMonitoring" } as const; + + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster(Base); + + /** + * This alias specializes the semantics of {@link ResourceMonitoring.Base}. + * + * WaterTankLevelMonitoringCluster supports optional features that you can enable with the + * WaterTankLevelMonitoringCluster.with() factory method. + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + + /** + * This cluster supports all WaterTankLevelMonitoring features. It may support illegal feature combinations. + * + * If you use this cluster you must manually specify which features are active and ensure the set of active + * features is legal per the Matter specification. + */ + export const CompleteInstance = MutableCluster({ + ...ResourceMonitoring.Complete, + id: 0x79, + name: "WaterTankLevelMonitoring" + }); + + export interface Complete extends Identity {} + export const Complete: Complete = CompleteInstance; +} + +export type WaterTankLevelMonitoringCluster = WaterTankLevelMonitoring.Cluster; +export const WaterTankLevelMonitoringCluster = WaterTankLevelMonitoring.Cluster; +ClusterRegistry.register(WaterTankLevelMonitoring.Complete); diff --git a/packages/types/src/clusters/wi-fi-network-diagnostics.ts b/packages/types/src/clusters/wi-fi-network-diagnostics.ts index 29582ddf2b..763f0b0f63 100644 --- a/packages/types/src/clusters/wi-fi-network-diagnostics.ts +++ b/packages/types/src/clusters/wi-fi-network-diagnostics.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -185,9 +185,8 @@ export namespace WiFiNetworkDiagnostics { /** * The Status field shall be set to the Status Code value that was present in the last frame related to - * association where Status Code was not equal to zero and which caused the failure of a last trial - * - * attempt, if this last failure was due to one of the following Management frames: + * association where Status Code was not equal to zero and which caused the failure of a last trial attempt, if + * this last failure was due to one of the following Management frames: * * • Association Response (Type 0, Subtype 1) * @@ -292,11 +291,10 @@ export namespace WiFiNetworkDiagnostics { export const PacketCountsComponent = MutableCluster.Component({ attributes: { /** - * The BeaconRxCount attribute shall indicate the count of the number of received beacons. The - * - * total number of expected beacons that could have been received during the interval since association - * SHOULD match the sum of BeaconRxCount and BeaconLostCount. If the Node does not have an ability to - * report count of beacons received, this value may remain set to zero. + * The BeaconRxCount attribute shall indicate the count of the number of received beacons. The total number + * of expected beacons that could have been received during the interval since association SHOULD match the + * sum of BeaconRxCount and BeaconLostCount. If the Node does not have an ability to report count of + * beacons received, this value may remain set to zero. * * @see {@link MatterSpecification.v13.Core} § 11.15.6.7 */ diff --git a/packages/types/src/clusters/wi-fi-network-management.ts b/packages/types/src/clusters/wi-fi-network-management.ts new file mode 100644 index 0000000000..11b39f0b98 --- /dev/null +++ b/packages/types/src/clusters/wi-fi-network-management.ts @@ -0,0 +1,119 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { MutableCluster } from "../cluster/mutation/MutableCluster.js"; +import { Attribute, Command } from "../cluster/Cluster.js"; +import { TlvByteString } from "../tlv/TlvString.js"; +import { TlvNullable } from "../tlv/TlvNullable.js"; +import { TlvUInt64 } from "../tlv/TlvNumber.js"; +import { AccessLevel } from "#model"; +import { TlvNoArguments } from "../tlv/TlvNoArguments.js"; +import { Identity } from "#general"; +import { ClusterRegistry } from "../cluster/ClusterRegistry.js"; + +export namespace WiFiNetworkManagement { + /** + * @see {@link Cluster} + */ + export const ClusterInstance = MutableCluster({ + id: 0x451, + name: "WiFiNetworkManagement", + revision: 1, + + attributes: { + /** + * Indicates the SSID of the primary Wi-Fi network provided by this device. + * + * A value of null shall indicate that no primary Wi-Fi network is available (e.g. because the Wi-Fi + * network has not yet been configured by the user). + * + * NOTE + * + * The SSID in Wi-Fi is a collection of 1-32 bytes, the text encoding of which is not specified. + * Implementations must be careful to support transferring these byte strings without requiring a + * particular encoding. The most common encoding is UTF-8, however this is just a convention. Some + * configurations may use Latin-1 or other character sets. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.2.4.1 + */ + ssid: Attribute( + 0x0, + TlvNullable(TlvByteString.bound({ minLength: 1, maxLength: 32 })), + { persistent: true, default: null } + ), + + /** + * This attribute shall contain an arbitrary numeric value; this value shall increase whenever the + * passphrase or PSK associated with the primary Wi-Fi network provided by this device changes. + * + * A value of null shall indicate that no primary Wi-Fi network is available. + * + * Clients can subscribe to this attribute or compare its value to a locally cached copy to detect if a + * cached passphrase value has become stale. + * + * It is recommended that servers implement this attribute as either a timestamp or a counter. When + * implemented as a counter it SHOULD be initialized with a random value. + * + * NOTE + * + * The passphrase itself is not exposed as an attribute to avoid its unintentional retrieval or caching by + * clients that use wildcard reads or otherwise routinely read all available attributes. It can be + * retrieved using the NetworkPassphraseRequest + * + * command. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.2.4.2 + */ + passphraseSurrogate: Attribute( + 0x1, + TlvNullable(TlvUInt64), + { persistent: true, default: null, readAcl: AccessLevel.Manage, writeAcl: AccessLevel.Manage } + ) + }, + + commands: { + /** + * This command is used to request the current WPA-Personal passphrase or PSK associated with the Wi-Fi + * network provided by this device. + * + * If the command is not executed via a CASE session, the command shall be rejected with a status of + * UNSUPPORTED_ACCESS. + * + * If no primary Wi-Fi network is available (the SSID attribute is null), the command shall be rejected + * with a status of INVALID_IN_STATE. + * + * Otherwise a NetworkPassphraseResponse shall be generated. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.2.5.1 + */ + networkPassphraseRequest: Command( + 0x0, + TlvNoArguments, + 0x1, + TlvNoArguments, + { invokeAcl: AccessLevel.Manage } + ) + } + }); + + /** + * This cluster provides an interface for getting information about the Wi-Fi network that a Network Infrastructure + * Manager device type provides. Privileged nodes within the same fabric as a Network Infrastructure Manager can + * use these interfaces to request information related to the Wi-Fi Network such as SSID and Passphrase. + * + * @see {@link MatterSpecification.v13.Cluster} § 10.2 + */ + export interface Cluster extends Identity {} + + export const Cluster: Cluster = ClusterInstance; + export const Complete = Cluster; +} + +export type WiFiNetworkManagementCluster = WiFiNetworkManagement.Cluster; +export const WiFiNetworkManagementCluster = WiFiNetworkManagement.Cluster; +ClusterRegistry.register(WiFiNetworkManagement.Complete); diff --git a/packages/types/src/clusters/window-covering.ts b/packages/types/src/clusters/window-covering.ts index f6b9919509..be84551a90 100644 --- a/packages/types/src/clusters/window-covering.ts +++ b/packages/types/src/clusters/window-covering.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -229,9 +229,6 @@ export namespace WindowCovering { */ operational: BitFlag(0), - /** - * Deprecated and reserved. - */ onlineReserved: BitFlag(1), /** @@ -631,7 +628,7 @@ export namespace WindowCovering { * Indicates the maximum possible encoder position possible (Unit cm, centimeters) to position the height * of the window covering lift. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.3 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.2 */ physicalClosedLimitLift: OptionalFixedAttribute(0x1, TlvUInt16, { default: 0 }), @@ -639,7 +636,7 @@ export namespace WindowCovering { * Indicates the actual lift position (Unit cm, centimeters) of the window covering from the fully-open * position. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.5 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.4 */ currentPositionLift: OptionalAttribute(0x3, TlvNullable(TlvUInt16), { persistent: true, default: null }), @@ -647,7 +644,7 @@ export namespace WindowCovering { * Indicates the open limit for lifting the window covering whether position (in centimeters) is encoded or * timed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.18 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.17 */ installedOpenLimitLift: Attribute(0x10, TlvUInt16.bound({ max: 65534 }), { persistent: true, default: 0 }), @@ -655,7 +652,7 @@ export namespace WindowCovering { * Indicates the closed limit for lifting the window covering whether position (in centimeters) is encoded * or timed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.19 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.18 */ installedClosedLimitLift: Attribute( 0x11, @@ -675,7 +672,7 @@ export namespace WindowCovering { * Indicates the maximum possible encoder position possible (Unit 0.1°, tenths of a degree) to position the * angle of the window covering tilt. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.4 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.3 */ physicalClosedLimitTilt: OptionalFixedAttribute(0x2, TlvUInt16, { default: 0 }), @@ -683,7 +680,7 @@ export namespace WindowCovering { * Indicates the actual tilt position (Unit 0.1°, tenths of a degree) of the window covering from the * fully-open position. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.6 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.5 */ currentPositionTilt: OptionalAttribute(0x4, TlvNullable(TlvUInt16), { persistent: true, default: null }), @@ -691,7 +688,7 @@ export namespace WindowCovering { * Indicates the open limit for tilting the window covering whether position (in tenth of a degree) is * encoded or timed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.20 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.19 */ installedOpenLimitTilt: Attribute(0x12, TlvUInt16.bound({ max: 65534 }), { persistent: true, default: 0 }), @@ -699,7 +696,7 @@ export namespace WindowCovering { * Indicates the closed limit for tilting the window covering whether position (in tenth of a degree) is * encoded or timed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.21 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.20 */ installedClosedLimitTilt: Attribute( 0x13, @@ -718,7 +715,7 @@ export namespace WindowCovering { * Indicates the total number of lift/slide actuations applied to the window covering since the device was * installed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.7 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.6 */ numberOfActuationsLift: OptionalAttribute(0x5, TlvUInt16, { persistent: true, default: 0 }) }, @@ -756,7 +753,7 @@ export namespace WindowCovering { * Indicates the total number of tilt actuations applied to the window covering since the device was * installed. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.8 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.7 */ numberOfActuationsTilt: OptionalAttribute(0x6, TlvUInt16, { persistent: true, default: 0 }) }, @@ -794,30 +791,26 @@ export namespace WindowCovering { * Indicates the actual position as a percentage from 0% to 100% with 1% default step. This attribute is * equal to CurrentPositionLiftPercent100ths attribute divided by 100. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.12 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.11 */ currentPositionLiftPercentage: OptionalAttribute( 0x8, TlvNullable(TlvPercent), - { scene: true, persistent: true, default: null } + { persistent: true, default: null } ), /** * Indicates the position where the window covering lift will go or is moving to as a percentage (Unit * 0.01%). * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.14 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.13 */ - targetPositionLiftPercent100ths: Attribute( - 0xb, - TlvNullable(TlvPercent100ths), - { scene: true, default: null } - ), + targetPositionLiftPercent100ths: Attribute(0xb, TlvNullable(TlvPercent100ths), { default: null }), /** * Indicates the actual position as a percentage with a minimal step of 0.01%. E.g Max 10000 equals 100.00%. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.10 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.9 */ currentPositionLiftPercent100ths: Attribute( 0xe, @@ -859,30 +852,26 @@ export namespace WindowCovering { * Indicates the actual position as a percentage from 0% to 100% with 1% default step. This attribute is * equal to CurrentPositionTiltPercent100ths attribute divided by 100. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.13 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.12 */ currentPositionTiltPercentage: OptionalAttribute( 0x9, TlvNullable(TlvPercent), - { scene: true, persistent: true, default: null } + { persistent: true, default: null } ), /** * Indicates the position where the window covering tilt will go or is moving to as a percentage (Unit * 0.01%). * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.15 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.14 */ - targetPositionTiltPercent100ths: Attribute( - 0xc, - TlvNullable(TlvPercent100ths), - { scene: true, default: null } - ), + targetPositionTiltPercent100ths: Attribute(0xc, TlvNullable(TlvPercent100ths), { default: null }), /** * Indicates the actual position as a percentage with a minimal step of 0.01%. E.g Max 10000 equals 100.00%. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.11 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.10 */ currentPositionTiltPercent100ths: Attribute( 0xf, @@ -1000,7 +989,7 @@ export namespace WindowCovering { /** * This attribute shall identify the type of window covering. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.2 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.1 */ type: FixedAttribute(0x0, TlvEnum(), { default: WindowCoveringType.Rollershade }), @@ -1010,14 +999,14 @@ export namespace WindowCovering { * To change settings, devices shall write to the Mode attribute. The behavior causing the setting or * clearing of each bit is vendor specific. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.9 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.8 */ configStatus: Attribute(0x7, TlvBitmap(TlvUInt8, ConfigStatus), { persistent: true }), /** * Indicates the currently ongoing operations and applies to all type of devices. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.16 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.15 */ operationalStatus: Attribute(0xa, TlvBitmap(TlvUInt8, OperationalStatus)), @@ -1027,7 +1016,7 @@ export namespace WindowCovering { * * The table below helps to match the EndProductType attribute with the Type attribute. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.17 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.16 */ endProductType: FixedAttribute(0xd, TlvEnum(), { default: EndProductType.RollerShade }), @@ -1041,7 +1030,7 @@ export namespace WindowCovering { * write interaction to the Mode attribute, with an unsupported mode bit or any out of bounds bits set, * must be ignored and a response containing the status of CONSTRAINT_ERROR will be returned. * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.22 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.21 */ mode: WritableAttribute( 0x17, @@ -1054,7 +1043,7 @@ export namespace WindowCovering { * movements. By default for nominal operation all flags are cleared (0). A device might support none, one * or several bit flags from this attribute (all optional). * - * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.23 + * @see {@link MatterSpecification.v13.Cluster} § 5.3.6.22 */ safetyStatus: OptionalAttribute(0x1a, TlvBitmap(TlvUInt16, SafetyStatus)) }, diff --git a/packages/types/src/globals/AtomicAttributeStatus.ts b/packages/types/src/globals/AtomicAttributeStatus.ts new file mode 100644 index 0000000000..b483916ca6 --- /dev/null +++ b/packages/types/src/globals/AtomicAttributeStatus.ts @@ -0,0 +1,41 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { TlvField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvAttributeId } from "../datatype/AttributeId.js"; +import { Status } from "./Status.js"; +import { TlvEnum } from "../tlv/TlvNumber.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; + +/** + * This struct indicates the status of an attribute during an atomic write. + * + * @see {@link MatterSpecification.v13.Core} § 7.15.5 + */ +export const TlvAtomicAttributeStatus = TlvObject({ + /** + * This field shall indicate the ID of the attribute with the associated StatusCode. + * + * @see {@link MatterSpecification.v13.Core} § 7.15.5.1 + */ + attributeId: TlvField(0, TlvAttributeId), + + /** + * This field shall indicate the atomic status of an attribute. + * + * @see {@link MatterSpecification.v13.Core} § 7.15.5.2 + */ + statusCode: TlvField(1, TlvEnum()) +}); + +/** + * This struct indicates the status of an attribute during an atomic write. + * + * @see {@link MatterSpecification.v13.Core} § 7.15.5 + */ +export interface AtomicAttributeStatus extends TypeFromSchema {} diff --git a/packages/types/src/globals/AtomicRequestType.ts b/packages/types/src/globals/AtomicRequestType.ts new file mode 100644 index 0000000000..0bb475bcfa --- /dev/null +++ b/packages/types/src/globals/AtomicRequestType.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +/** + * @see {@link MatterSpecification.v13.Core} § 7.15.4 + */ +export enum AtomicRequestType { + /** + * Begin an atomic write + */ + BeginWrite = 0, + + /** + * Commit an atomic write + */ + CommitWrite = 1, + + /** + * Rollback an atomic write, discarding any pending changes + */ + RollbackWrite = 2 +} diff --git a/packages/types/src/globals/Locationdesc.ts b/packages/types/src/globals/Locationdesc.ts new file mode 100644 index 0000000000..7399099b82 --- /dev/null +++ b/packages/types/src/globals/Locationdesc.ts @@ -0,0 +1,88 @@ +/** + * @license + * Copyright 2022-2025 Matter.js Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +/*** THIS FILE IS GENERATED, DO NOT EDIT ***/ + +import { TlvField, TlvObject } from "../tlv/TlvObject.js"; +import { TlvString } from "../tlv/TlvString.js"; +import { TlvInt16, TlvUInt8 } from "../tlv/TlvNumber.js"; +import { TlvNullable } from "../tlv/TlvNullable.js"; +import { TypeFromSchema } from "../tlv/TlvSchema.js"; + +/** + * Location Descriptor + * + * This data type shall be represented by the following structure: + * + * @see {@link MatterSpecification.v13.Core} § 7.19.2.45 + */ +export const TlvLocationdesc = TlvObject({ + /** + * This field shall indicate the name of the location. For example, "blue room". + * + * If the location name is not user provided, the logic that generates it (clients, devices etc.) SHOULD utilize + * synthesized user-friendly, understandable, names for the location, rather than opaque values such as "private" + * or "2fe7c241-a50a-4863-896e-c5878da5ed68". + * + * @see {@link MatterSpecification.v13.Core} § 7.19.2.45.1 + */ + locationName: TlvField(0, TlvString.bound({ maxLength: 128 })), + + /** + * This field shall indicate the level number. Negative values correspond to basement levels. + * + * Value zero indicates this is the main floor, which typically includes the main entrance to the user’s home. For + * a building with multiple levels, it is the client’s responsibility to map each level to/from a FloorNumber tag + * value, using the level numbering convention of the region where the client operates. For example, if the client + * operates in Europe, building level 1, which is one level up from the street level, SHOULD be mapped to + * FloorNumber tag value 0x1. If the client operates in North America, building level 1, which is at street level, + * SHOULD be mapped to FloorNumber tag value 0x0. + * + * A null value indicates that this information is not available. + * + * When the clients present the level information for user selection, they SHOULD use the operating region to + * determine how to render and map this data. For example, if the client operates in North America it SHOULD + * present the user a list that includes entries labeled "basement", "first", "second", and internally mapped to + * floor numbers -1, 0, and 1. If operating in Europe, the client SHOULD present a list that includes entries + * labeled "basement", "ground", "first", internally mapped to floor numbers -1, 0, and 1. + * + * The floor number information is expected to be mostly useful to the clients, rather than the devices, such as + * for grouping devices that are located on the same level. For example, an automation may be defined for all + * devices located at the basement level (floor number -1). + * + * NOTE + * + * Handling complex level situations, such as half levels (side split houses), or the levels from an apartment + * building, is up to the client and/or user. + * + * @see {@link MatterSpecification.v13.Core} § 7.19.2.45.2 + */ + floorNumber: TlvField(1, TlvNullable(TlvInt16)), + + /** + * This field shall be the ID of an area semantic tag, located within the Common Area Namespace. For example, this + * tag may indicate that the location refers to a bedroom. + * + * If this field is null, that indicates that the area type information is not available. + * + * NOTE + * + * This field only indicates the type of the area. Multiple areas of the same type, such as bedrooms, may exist in + * a user’s home. + * + * @see {@link MatterSpecification.v13.Core} § 7.19.2.45.3 + */ + areaType: TlvField(2, TlvNullable(TlvUInt8)) +}); + +/** + * Location Descriptor + * + * This data type shall be represented by the following structure: + * + * @see {@link MatterSpecification.v13.Core} § 7.19.2.45 + */ +export interface Locationdesc extends TypeFromSchema {} diff --git a/packages/types/src/globals/MeasurementAccuracy.ts b/packages/types/src/globals/MeasurementAccuracy.ts index 4b22bb2ff5..a026ca33bd 100644 --- a/packages/types/src/globals/MeasurementAccuracy.ts +++ b/packages/types/src/globals/MeasurementAccuracy.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/globals/MeasurementAccuracyRange.ts b/packages/types/src/globals/MeasurementAccuracyRange.ts index 9ff66a0c94..54cb9185aa 100644 --- a/packages/types/src/globals/MeasurementAccuracyRange.ts +++ b/packages/types/src/globals/MeasurementAccuracyRange.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/globals/MeasurementType.ts b/packages/types/src/globals/MeasurementType.ts index 8e945d0327..c7acbf6ebd 100644 --- a/packages/types/src/globals/MeasurementType.ts +++ b/packages/types/src/globals/MeasurementType.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/globals/Priority.ts b/packages/types/src/globals/Priority.ts index c5786c521b..1b34bcd2e3 100644 --- a/packages/types/src/globals/Priority.ts +++ b/packages/types/src/globals/Priority.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -13,7 +13,7 @@ * particular ordering among the values. Specific uses of the data type may assign semantics to the values that imply * an ordering relationship. * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.17 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.17 */ export enum Priority { /** diff --git a/packages/types/src/globals/Semtag.ts b/packages/types/src/globals/Semtag.ts index 6c9b2b0cd0..7241f71629 100644 --- a/packages/types/src/globals/Semtag.ts +++ b/packages/types/src/globals/Semtag.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -18,7 +18,7 @@ import { TypeFromSchema } from "../tlv/TlvSchema.js"; * * This data type shall be represented by the following structure: * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.42 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.42 */ export const TlvSemtag = TlvObject({ /** @@ -32,7 +32,7 @@ export const TlvSemtag = TlvObject({ * * If MfgCode is null, the NamespaceID field shall indicate a standard namespace. * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.42.1 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.42.1 */ mfgCode: TlvField(0, TlvNullable(TlvVendorId)), @@ -41,7 +41,7 @@ export const TlvSemtag = TlvObject({ * * The common and device-specific semantic tag namespaces are listed in StandardNamespaces. * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.42.2 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.42.2 */ namespaceId: TlvField(1, TlvUInt8), @@ -51,7 +51,7 @@ export const TlvSemtag = TlvObject({ * A device may expose tags from the common or device-specific namespaces and from manufacturer-specific namespaces * in a single TagList. * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.42.3 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.42.3 */ tag: TlvField(2, TlvUInt8), @@ -64,7 +64,7 @@ export const TlvSemtag = TlvObject({ * "room" in a location namespace, would require the a label string to qualify the type of room, such as "1", "2b", * "Bathroom", etc. * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.42.4 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.42.4 */ label: TlvOptionalField(3, TlvNullable(TlvString.bound({ maxLength: 64 }))) }) @@ -74,6 +74,6 @@ export const TlvSemtag = TlvObject({ * * This data type shall be represented by the following structure: * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.42 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.42 */ export interface Semtag extends TypeFromSchema {} diff --git a/packages/types/src/globals/SoftwareVersionCertificationStatus.ts b/packages/types/src/globals/SoftwareVersionCertificationStatus.ts index 829f3620ea..bc386240eb 100644 --- a/packages/types/src/globals/SoftwareVersionCertificationStatus.ts +++ b/packages/types/src/globals/SoftwareVersionCertificationStatus.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -10,7 +10,7 @@ * The values 0 through 2 shall correspond to the values 0 through 2 used in certification_type in the Certification * Declaration. * - * @see {@link MatterSpecification.v13.Core} § 11.23.7.2 + * @see {@link MatterSpecification.v13.Core} § 11.23.8.2 */ export enum SoftwareVersionCertificationStatus { /** diff --git a/packages/types/src/globals/Status.ts b/packages/types/src/globals/Status.ts index b96af6e02c..160e05d4c0 100644 --- a/packages/types/src/globals/Status.ts +++ b/packages/types/src/globals/Status.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -22,7 +22,7 @@ * * Status codes in an undefined range, or status codes undefined within a range are reserved and shall NOT be indicated. * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.18 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.18 */ export enum Status { /** @@ -168,6 +168,13 @@ export enum Status { */ Busy = 156, + /** + * The access to the action or command by the sender is permitted by the ACL but restricted by the ARL. + * + * @see {@link MatterSpecification.v13.Core} § 8.10.1 + */ + AccessRestricted = 157, + /** * The cluster indicated is not supported on the endpoint. * @@ -231,5 +238,20 @@ export enum Status { * * @see {@link MatterSpecification.v13.Core} § 8.10.1 */ - NoCommandResponse = 204 + NoCommandResponse = 204, + + /** + * The node requires updated TC acceptance. The user MAY be directed to visit the EnhancedSetupFlowMaintenanceUrl + * to complete this. + * + * @see {@link MatterSpecification.v13.Core} § 8.10.1 + */ + TermsAndConditionsChanged = 205, + + /** + * The node requires the user to visit the EnhancedSetupFlowMaintenanceUrl for instructions on further action. + * + * @see {@link MatterSpecification.v13.Core} § 8.10.1 + */ + MaintenanceRequired = 206 } diff --git a/packages/types/src/globals/Tod.ts b/packages/types/src/globals/Tod.ts index a6dde22832..de96dde3d8 100644 --- a/packages/types/src/globals/Tod.ts +++ b/packages/types/src/globals/Tod.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ @@ -15,7 +15,7 @@ import { TypeFromSchema } from "../tlv/TlvSchema.js"; * * Represents time without a date component. * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.3 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.3 */ export const TlvTod = TlvObject({ /** @@ -44,6 +44,6 @@ export const TlvTod = TlvObject({ * * Represents time without a date component. * - * @see {@link MatterSpecification.v13.Core} § 7.18.2.3 + * @see {@link MatterSpecification.v13.Core} § 7.19.2.3 */ export interface Tod extends TypeFromSchema {} diff --git a/packages/types/src/globals/WildcardPathFlags.ts b/packages/types/src/globals/WildcardPathFlags.ts index 6cd6ac9161..7161f2decc 100644 --- a/packages/types/src/globals/WildcardPathFlags.ts +++ b/packages/types/src/globals/WildcardPathFlags.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ diff --git a/packages/types/src/globals/index.ts b/packages/types/src/globals/index.ts index e2f7bab45b..bbb85ac706 100644 --- a/packages/types/src/globals/index.ts +++ b/packages/types/src/globals/index.ts @@ -1,16 +1,19 @@ /** * @license - * Copyright 2022-2024 Matter.js Authors + * Copyright 2022-2025 Matter.js Authors * SPDX-License-Identifier: Apache-2.0 */ /*** THIS FILE IS GENERATED, DO NOT EDIT ***/ +export * from "./AtomicAttributeStatus.js"; +export * from "./AtomicRequestType.js"; export * from "./MeasurementAccuracyRange.js"; export * from "./MeasurementAccuracy.js"; export * from "./MeasurementType.js"; export * from "./SoftwareVersionCertificationStatus.js"; export * from "./WildcardPathFlags.js"; +export * from "./Locationdesc.js"; export * from "./Priority.js"; export * from "./Semtag.js"; export * from "./Status.js"; diff --git a/packages/types/src/schema/QrCodeSchema.ts b/packages/types/src/schema/QrCodeSchema.ts index cc04806060..6292af9854 100644 --- a/packages/types/src/schema/QrCodeSchema.ts +++ b/packages/types/src/schema/QrCodeSchema.ts @@ -156,7 +156,7 @@ export class QrCodeSchema extends Schema { //qrCode.forEach((line, x) => line.forEach((_v, y) => qrCode[x][y] = 1)) - // Gererate the bit string + // Generate the bit string const bitString = bitStringBuilder.join(""); // Xor the bits @@ -181,7 +181,10 @@ export class QrCodeSchema extends Schema { if (y === 20 || qrCode[y + 1][x] === 1) { result.push("▄"); } else { - result.push(" "); + result.push( + // Use a braille blank rather than a space to ensure no wrapping/whitespace collapsing + "\u2800", + ); } } else { if (y === 20 || qrCode[y + 1][x] === 1) { @@ -193,7 +196,9 @@ export class QrCodeSchema extends Schema { } result.push("█\n"); } + result.push("▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\n"); + return result.join(""); } diff --git a/packages/types/src/tsconfig.json b/packages/types/src/tsconfig.json index 462287ef5a..853c8cf099 100644 --- a/packages/types/src/tsconfig.json +++ b/packages/types/src/tsconfig.json @@ -15,6 +15,9 @@ }, { "path": "../../testing/src" + }, + { + "path": "../../tools/src" } ] } \ No newline at end of file diff --git a/packages/types/test/schema/QrCodeSchemaTest.ts b/packages/types/test/schema/QrCodeSchemaTest.ts index 5cb8cb5d07..aab8368232 100644 --- a/packages/types/test/schema/QrCodeSchemaTest.ts +++ b/packages/types/test/schema/QrCodeSchemaTest.ts @@ -8,16 +8,16 @@ import { QrCode } from "#schema/QrCodeSchema.js"; const QR_CODE = [ "▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄", - "█ ▄▄▄▄▄ ██▀▄▀▄█ ▄▄▄▄▄ █", - "█ █ █ █▄▀▄▀▄█ █ █ █", - "█ █▄▄▄█ ██ ▀▀▄█ █▄▄▄█ █", - "█▄▄▄▄▄▄▄█ █ ▀▄█▄▄▄▄▄▄▄█", - "█▄▄ ▀▄▄▄▄ ▀ █ ▄▀██ █▀█", - "█▀▄▀▄ ▄▄ ▀▀█ ▀ ▀ ▀█▀█", - "█▄▄▄██▄▄▄█▀▄▀ ▀▄▄ █▄▄▀█", - "█ ▄▄▄▄▄ █ █▄█▄▀█▀ █ █", - "█ █ █ █▄▀▄█▄ ▄▀▄▀▀▀██", - "█ █▄▄▄█ █ █▀█▄█ ▀▄▀▀ █", + "█⠀▄▄▄▄▄⠀██▀▄▀▄█⠀▄▄▄▄▄⠀█", + "█⠀█⠀⠀⠀█⠀█▄▀▄▀▄█⠀█⠀⠀⠀█⠀█", + "█⠀█▄▄▄█⠀██⠀▀▀▄█⠀█▄▄▄█⠀█", + "█▄▄▄▄▄▄▄█⠀█⠀▀▄█▄▄▄▄▄▄▄█", + "█▄▄⠀▀▄▄▄▄⠀▀⠀█⠀⠀▄▀██⠀█▀█", + "█▀▄▀▄⠀▄▄⠀▀▀█⠀▀⠀▀⠀⠀⠀▀█▀█", + "█▄▄▄██▄▄▄█▀▄▀⠀▀▄▄⠀█▄▄▀█", + "█⠀▄▄▄▄▄⠀█⠀⠀⠀█▄█▄▀█▀⠀█⠀█", + "█⠀█⠀⠀⠀█⠀█▄▀▄█▄⠀▄▀▄▀▀▀██", + "█⠀█▄▄▄█⠀█⠀█▀█▄█⠀⠀▀▄▀▀⠀█", "█▄▄▄▄▄▄▄█▄█▄█▄████▄▄█▄█", "▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀", "", diff --git a/packages/types/test/schema/SpecificationVersionSchemaTest.ts b/packages/types/test/schema/SpecificationVersionSchemaTest.ts index 7b2f44f20a..1f43bc773f 100644 --- a/packages/types/test/schema/SpecificationVersionSchemaTest.ts +++ b/packages/types/test/schema/SpecificationVersionSchemaTest.ts @@ -22,7 +22,7 @@ describe("SpecificationVersionSchema", () => { it("decode our encoded version", () => { expect(SpecificationVersion.decode(Specification.SPECIFICATION_VERSION)).to.deep.equal({ major: 1, - minor: 3, + minor: 4, patch: 0, reserved: 0, });