diff --git a/docs/api.md b/docs/api.md index e9ccfedd37..bf3c2e0394 100644 --- a/docs/api.md +++ b/docs/api.md @@ -102,6 +102,9 @@ inside a single session. Things like:
DB API: zcl database access

This module provides queries for enums.

+
DB API: zcl database typedef access
+

This module provides queries for typedefs.

+
DB API: zcl database access

This module provides a place for creating generic queries which are common across different query files.

@@ -887,6 +890,7 @@ This module provides cache for commonly used static database queries. * [~selectStructClusters(db, structId)](#module_DB API_ zcl database access..selectStructClusters) ⇒ * [~selectEnumClusters(db, enumId)](#module_DB API_ zcl database access..selectEnumClusters) ⇒ * [~selectBitmapClusters(db, bitmapId)](#module_DB API_ zcl database access..selectBitmapClusters) ⇒ + * [~selectTypedefClusters(db, typeDefId)](#module_DB API_ zcl database access..selectTypedefClusters) ⇒ * [~selectClusterStructsWithItems(db)](#module_DB API_ zcl database access..selectClusterStructsWithItems) ⇒ * [~selectAllStructsWithItems(db)](#module_DB API_ zcl database access..selectAllStructsWithItems) ⇒ * [~selectStructsWithItemsImpl(db, packageIds, clusterId)](#module_DB API_ zcl database access..selectStructsWithItemsImpl) ⇒ @@ -1360,6 +1364,19 @@ Returns an array of clusters that bitmap belongs to. | db | \* | | bitmapId | \* | + + +### DB API: zcl database access~selectTypedefClusters(db, typeDefId) ⇒ +Returns an array of clusters that the typedef belongs to. + +**Kind**: inner method of [DB API: zcl database access](#module_DB API_ zcl database access) +**Returns**: clusters + +| Param | Type | +| --- | --- | +| db | \* | +| typeDefId | \* | + ### DB API: zcl database access~selectClusterStructsWithItems(db) ⇒ @@ -1691,6 +1708,7 @@ This module provides queries for atomic type queries. * [~selectStructClusters(db, structId)](#module_DB API_ zcl database access..selectStructClusters) ⇒ * [~selectEnumClusters(db, enumId)](#module_DB API_ zcl database access..selectEnumClusters) ⇒ * [~selectBitmapClusters(db, bitmapId)](#module_DB API_ zcl database access..selectBitmapClusters) ⇒ + * [~selectTypedefClusters(db, typeDefId)](#module_DB API_ zcl database access..selectTypedefClusters) ⇒ * [~selectClusterStructsWithItems(db)](#module_DB API_ zcl database access..selectClusterStructsWithItems) ⇒ * [~selectAllStructsWithItems(db)](#module_DB API_ zcl database access..selectAllStructsWithItems) ⇒ * [~selectStructsWithItemsImpl(db, packageIds, clusterId)](#module_DB API_ zcl database access..selectStructsWithItemsImpl) ⇒ @@ -2164,6 +2182,19 @@ Returns an array of clusters that bitmap belongs to. | db | \* | | bitmapId | \* | + + +### DB API: zcl database access~selectTypedefClusters(db, typeDefId) ⇒ +Returns an array of clusters that the typedef belongs to. + +**Kind**: inner method of [DB API: zcl database access](#module_DB API_ zcl database access) +**Returns**: clusters + +| Param | Type | +| --- | --- | +| db | \* | +| typeDefId | \* | + ### DB API: zcl database access~selectClusterStructsWithItems(db) ⇒ @@ -2490,6 +2521,7 @@ This module provides queries for enums. * [~selectStructClusters(db, structId)](#module_DB API_ zcl database access..selectStructClusters) ⇒ * [~selectEnumClusters(db, enumId)](#module_DB API_ zcl database access..selectEnumClusters) ⇒ * [~selectBitmapClusters(db, bitmapId)](#module_DB API_ zcl database access..selectBitmapClusters) ⇒ + * [~selectTypedefClusters(db, typeDefId)](#module_DB API_ zcl database access..selectTypedefClusters) ⇒ * [~selectClusterStructsWithItems(db)](#module_DB API_ zcl database access..selectClusterStructsWithItems) ⇒ * [~selectAllStructsWithItems(db)](#module_DB API_ zcl database access..selectAllStructsWithItems) ⇒ * [~selectStructsWithItemsImpl(db, packageIds, clusterId)](#module_DB API_ zcl database access..selectStructsWithItemsImpl) ⇒ @@ -2963,6 +2995,19 @@ Returns an array of clusters that bitmap belongs to. | db | \* | | bitmapId | \* | + + +### DB API: zcl database access~selectTypedefClusters(db, typeDefId) ⇒ +Returns an array of clusters that the typedef belongs to. + +**Kind**: inner method of [DB API: zcl database access](#module_DB API_ zcl database access) +**Returns**: clusters + +| Param | Type | +| --- | --- | +| db | \* | +| typeDefId | \* | + ### DB API: zcl database access~selectClusterStructsWithItems(db) ⇒ @@ -3925,6 +3970,7 @@ This module provides queries for ZCL loading * [~insertBitmapFields(db, packageId, knownPackages, data)](#module_DB API_ zcl loading queries..insertBitmapFields) * [~insertStruct(db, packageIds, data)](#module_DB API_ zcl loading queries..insertStruct) * [~insertStructItems(db, packageIds, data)](#module_DB API_ zcl loading queries..insertStructItems) + * [~insertTypedef(db, packageIds, data)](#module_DB API_ zcl loading queries..insertTypedef) @@ -4603,6 +4649,19 @@ Insert all Struct items into the Struct Item Table. | packageIds | \* | | data | \* | + + +### DB API: zcl loading queries~insertTypedef(db, packageIds, data) +Insert all typedefs into the TypeDef Table. + +**Kind**: inner method of [DB API: zcl loading queries](#module_DB API_ zcl loading queries) + +| Param | Type | +| --- | --- | +| db | \* | +| packageIds | \* | +| data | \* | + ## DB API: zcl database number access @@ -4733,6 +4792,7 @@ inside a single session. Things like: * [~selectStructClusters(db, structId)](#module_DB API_ zcl database access..selectStructClusters) ⇒ * [~selectEnumClusters(db, enumId)](#module_DB API_ zcl database access..selectEnumClusters) ⇒ * [~selectBitmapClusters(db, bitmapId)](#module_DB API_ zcl database access..selectBitmapClusters) ⇒ + * [~selectTypedefClusters(db, typeDefId)](#module_DB API_ zcl database access..selectTypedefClusters) ⇒ * [~selectClusterStructsWithItems(db)](#module_DB API_ zcl database access..selectClusterStructsWithItems) ⇒ * [~selectAllStructsWithItems(db)](#module_DB API_ zcl database access..selectAllStructsWithItems) ⇒ * [~selectStructsWithItemsImpl(db, packageIds, clusterId)](#module_DB API_ zcl database access..selectStructsWithItemsImpl) ⇒ @@ -5206,6 +5266,19 @@ Returns an array of clusters that bitmap belongs to. | db | \* | | bitmapId | \* | + + +### DB API: zcl database access~selectTypedefClusters(db, typeDefId) ⇒ +Returns an array of clusters that the typedef belongs to. + +**Kind**: inner method of [DB API: zcl database access](#module_DB API_ zcl database access) +**Returns**: clusters + +| Param | Type | +| --- | --- | +| db | \* | +| typeDefId | \* | + ### DB API: zcl database access~selectClusterStructsWithItems(db) ⇒ @@ -5578,6 +5651,7 @@ This module provides queries for enums. * [~selectStructClusters(db, structId)](#module_DB API_ zcl database access..selectStructClusters) ⇒ * [~selectEnumClusters(db, enumId)](#module_DB API_ zcl database access..selectEnumClusters) ⇒ * [~selectBitmapClusters(db, bitmapId)](#module_DB API_ zcl database access..selectBitmapClusters) ⇒ + * [~selectTypedefClusters(db, typeDefId)](#module_DB API_ zcl database access..selectTypedefClusters) ⇒ * [~selectClusterStructsWithItems(db)](#module_DB API_ zcl database access..selectClusterStructsWithItems) ⇒ * [~selectAllStructsWithItems(db)](#module_DB API_ zcl database access..selectAllStructsWithItems) ⇒ * [~selectStructsWithItemsImpl(db, packageIds, clusterId)](#module_DB API_ zcl database access..selectStructsWithItemsImpl) ⇒ @@ -6051,6 +6125,19 @@ Returns an array of clusters that bitmap belongs to. | db | \* | | bitmapId | \* | + + +### DB API: zcl database access~selectTypedefClusters(db, typeDefId) ⇒ +Returns an array of clusters that the typedef belongs to. + +**Kind**: inner method of [DB API: zcl database access](#module_DB API_ zcl database access) +**Returns**: clusters + +| Param | Type | +| --- | --- | +| db | \* | +| typeDefId | \* | + ### DB API: zcl database access~selectClusterStructsWithItems(db) ⇒ @@ -6330,6 +6417,89 @@ Get endpoint type events from the given endpoint type ID. | db | \* | | endpointTypeId | \* | + + +## DB API: zcl database typedef access +This module provides queries for typedefs. + + +* [DB API: zcl database typedef access](#module_DB API_ zcl database typedef access) + * [~selectAllTypedefs(db, packageId)](#module_DB API_ zcl database typedef access..selectAllTypedefs) ⇒ + * [~selectClusterTypedefs(db, packageId, clusterId)](#module_DB API_ zcl database typedef access..selectClusterTypedefs) ⇒ + * [~selectTypedefById(db, id)](#module_DB API_ zcl database typedef access..selectTypedefById) ⇒ + * [~selectTypedefByName(db, name, packageIds, clusterName)](#module_DB API_ zcl database typedef access..selectTypedefByName) ⇒ + * [~selectTypedefByNameAndClusterId(db, name, clusterId, packageIds)](#module_DB API_ zcl database typedef access..selectTypedefByNameAndClusterId) ⇒ + + + +### DB API: zcl database typedef access~selectAllTypedefs(db, packageId) ⇒ +Retrieves all the typedefs in the database. + +**Kind**: inner method of [DB API: zcl database typedef access](#module_DB API_ zcl database typedef access) +**Returns**: Promise that resolves with the rows of typedefs. + +| Param | Type | +| --- | --- | +| db | \* | +| packageId | \* | + + + +### DB API: zcl database typedef access~selectClusterTypedefs(db, packageId, clusterId) ⇒ +Retrieves all the typedefs with cluster references in the database. + +**Kind**: inner method of [DB API: zcl database typedef access](#module_DB API_ zcl database typedef access) +**Returns**: Promise that resolves with the rows of typedefs. + +| Param | Type | +| --- | --- | +| db | \* | +| packageId | \* | +| clusterId | \* | + + + +### DB API: zcl database typedef access~selectTypedefById(db, id) ⇒ +Select a typedef matched by its primary key. + +**Kind**: inner method of [DB API: zcl database typedef access](#module_DB API_ zcl database typedef access) +**Returns**: an typedef or underfined if not found + +| Param | Type | +| --- | --- | +| db | \* | +| id | \* | + + + +### DB API: zcl database typedef access~selectTypedefByName(db, name, packageIds, clusterName) ⇒ +Select a typedef matched by name. + +**Kind**: inner method of [DB API: zcl database typedef access](#module_DB API_ zcl database typedef access) +**Returns**: typedef or undefined + +| Param | Type | Default | +| --- | --- | --- | +| db | \* | | +| name | \* | | +| packageIds | \* | | +| clusterName | \* | | + + + +### DB API: zcl database typedef access~selectTypedefByNameAndClusterId(db, name, clusterId, packageIds) ⇒ +Select a typedef matched by name and clusterId. + +**Kind**: inner method of [DB API: zcl database typedef access](#module_DB API_ zcl database typedef access) +**Returns**: typedef information or undefined + +| Param | Type | +| --- | --- | +| db | \* | +| name | \* | +| clusterId | \* | +| packageIds | \* | + ## DB API: zcl database access @@ -6373,6 +6543,7 @@ across different query files. * [~selectStructClusters(db, structId)](#module_DB API_ zcl database access..selectStructClusters) ⇒ * [~selectEnumClusters(db, enumId)](#module_DB API_ zcl database access..selectEnumClusters) ⇒ * [~selectBitmapClusters(db, bitmapId)](#module_DB API_ zcl database access..selectBitmapClusters) ⇒ + * [~selectTypedefClusters(db, typeDefId)](#module_DB API_ zcl database access..selectTypedefClusters) ⇒ * [~selectClusterStructsWithItems(db)](#module_DB API_ zcl database access..selectClusterStructsWithItems) ⇒ * [~selectAllStructsWithItems(db)](#module_DB API_ zcl database access..selectAllStructsWithItems) ⇒ * [~selectStructsWithItemsImpl(db, packageIds, clusterId)](#module_DB API_ zcl database access..selectStructsWithItemsImpl) ⇒ @@ -6846,6 +7017,19 @@ Returns an array of clusters that bitmap belongs to. | db | \* | | bitmapId | \* | + + +### DB API: zcl database access~selectTypedefClusters(db, typeDefId) ⇒ +Returns an array of clusters that the typedef belongs to. + +**Kind**: inner method of [DB API: zcl database access](#module_DB API_ zcl database access) +**Returns**: clusters + +| Param | Type | +| --- | --- | +| db | \* | +| typeDefId | \* | + ### DB API: zcl database access~selectClusterStructsWithItems(db) ⇒ @@ -7167,6 +7351,7 @@ This module provides queries for ZCL static queries. * [~selectStructClusters(db, structId)](#module_DB API_ zcl database access..selectStructClusters) ⇒ * [~selectEnumClusters(db, enumId)](#module_DB API_ zcl database access..selectEnumClusters) ⇒ * [~selectBitmapClusters(db, bitmapId)](#module_DB API_ zcl database access..selectBitmapClusters) ⇒ + * [~selectTypedefClusters(db, typeDefId)](#module_DB API_ zcl database access..selectTypedefClusters) ⇒ * [~selectClusterStructsWithItems(db)](#module_DB API_ zcl database access..selectClusterStructsWithItems) ⇒ * [~selectAllStructsWithItems(db)](#module_DB API_ zcl database access..selectAllStructsWithItems) ⇒ * [~selectStructsWithItemsImpl(db, packageIds, clusterId)](#module_DB API_ zcl database access..selectStructsWithItemsImpl) ⇒ @@ -7640,6 +7825,19 @@ Returns an array of clusters that bitmap belongs to. | db | \* | | bitmapId | \* | + + +### DB API: zcl database access~selectTypedefClusters(db, typeDefId) ⇒ +Returns an array of clusters that the typedef belongs to. + +**Kind**: inner method of [DB API: zcl database access](#module_DB API_ zcl database access) +**Returns**: clusters + +| Param | Type | +| --- | --- | +| db | \* | +| typeDefId | \* | + ### DB API: zcl database access~selectClusterStructsWithItems(db) ⇒ @@ -11854,12 +12052,15 @@ This module contains the API for templating. For more detailed instructions, rea * [~zcl_bitmaps(options)](#module_Templating API_ static zcl helpers..zcl_bitmaps) ⇒ * [~zcl_bitmap_items(options)](#module_Templating API_ static zcl helpers..zcl_bitmap_items) * [~zcl_enums(options)](#module_Templating API_ static zcl helpers..zcl_enums) ⇒ + * [~zcl_typedefs(options)](#module_Templating API_ static zcl helpers..zcl_typedefs) ⇒ * [~zcl_structs(options)](#module_Templating API_ static zcl helpers..zcl_structs) ⇒ * [~zcl_enum_items(options)](#module_Templating API_ static zcl helpers..zcl_enum_items) * [~first_unused_enum_value(options)](#module_Templating API_ static zcl helpers..first_unused_enum_value) ⇒ * [~zcl_struct_items(options)](#module_Templating API_ static zcl helpers..zcl_struct_items) ⇒ * [~zcl_struct_items_by_struct_name(name, options)](#module_Templating API_ static zcl helpers..zcl_struct_items_by_struct_name) ⇒ * [~zcl_struct_items_by_struct_and_cluster_name(name, clusterName, options)](#module_Templating API_ static zcl helpers..zcl_struct_items_by_struct_and_cluster_name) ⇒ + * [~zcl_typedef_by_typedef(name, options)](#module_Templating API_ static zcl helpers..zcl_typedef_by_typedef) ⇒ + * [~zcl_typedef_by_typedef_and_cluster_name(name, clusterName, options)](#module_Templating API_ static zcl helpers..zcl_typedef_by_typedef_and_cluster_name) ⇒ * [~zcl_device_types(options)](#module_Templating API_ static zcl helpers..zcl_device_types) ⇒ * [~zcl_device_type_clusters(options)](#module_Templating API_ static zcl helpers..zcl_device_type_clusters) ⇒ * [~zcl_device_type_cluster_commands(options)](#module_Templating API_ static zcl helpers..zcl_device_type_cluster_commands) ⇒ @@ -11889,6 +12090,7 @@ This module contains the API for templating. For more detailed instructions, rea * [~zcl_command_arguments(options)](#module_Templating API_ static zcl helpers..zcl_command_arguments) ⇒ * [~zcl_event_fields(options)](#module_Templating API_ static zcl helpers..zcl_event_fields) * [~zcl_command_argument_data_type(typeName, options)](#module_Templating API_ static zcl helpers..zcl_command_argument_data_type) + * [~asResolvedUnderlyingZclType()](#module_Templating API_ static zcl helpers..asResolvedUnderlyingZclType) * [~asUnderlyingZclType(typeName, options)](#module_Templating API_ static zcl helpers..asUnderlyingZclType) * [~zcl_string_type_return(type, options)](#module_Templating API_ static zcl helpers..zcl_string_type_return) * [~is_zcl_string(type)](#module_Templating API_ static zcl helpers..is_zcl_string) @@ -11902,6 +12104,7 @@ This module contains the API for templating. For more detailed instructions, rea * [~if_is_bitmap(type)](#module_Templating API_ static zcl helpers..if_is_bitmap) ⇒ * [~if_is_enum(type)](#module_Templating API_ static zcl helpers..if_is_enum) ⇒ * [~if_is_struct(type)](#module_Templating API_ static zcl helpers..if_is_struct) ⇒ + * [~if_is_typedef(type)](#module_Templating API_ static zcl helpers..if_is_typedef) ⇒ * [~isClient(side)](#module_Templating API_ static zcl helpers..isClient) ⇒ * [~isServer(side)](#module_Templating API_ static zcl helpers..isServer) ⇒ * [~isStrEqual(str1, str2)](#module_Templating API_ static zcl helpers..isStrEqual) ⇒ @@ -11973,6 +12176,21 @@ enums belonging to a cluster. | --- | --- | | options | \* | + + +### Templating API: static zcl helpers~zcl\_typedefs(options) ⇒ +Block helper iterating over all typedefs. +If existing independently, it iterates over ALL the typedefs. +Within a context of a cluster, it iterates only over the +typedefs belonging to a cluster. + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) +**Returns**: Promise of content. + +| Param | Type | +| --- | --- | +| options | \* | + ### Templating API: static zcl helpers~zcl\_structs(options) ⇒ @@ -12056,6 +12274,36 @@ ignored), or a struct associated with the given cluster. | clusterName | | options | + + +### Templating API: static zcl helpers~zcl\_typedef\_by\_typedef(name, options) ⇒ +Block helper for getting information for a typedef with a given name. + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) +**Returns**: Promise of content. + +| Param | +| --- | +| name | +| options | + + + +### Templating API: static zcl helpers~zcl\_typedef\_by\_typedef\_and\_cluster\_name(name, clusterName, options) ⇒ +Block helper for expanding a typedef. The typedef will be those that correspond to that +typedef name being used within the given cluster. That means the typedef name +must be either a global (in which case the cluster name is just +ignored), or a typedef associated with the given cluster. + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) +**Returns**: Promise of content. + +| Param | +| --- | +| name | +| clusterName | +| options | + ### Templating API: static zcl helpers~zcl\_device\_types(options) ⇒ @@ -12429,6 +12677,12 @@ Helper that deals with the type of the argument. | typeName | \* | | options | \* | + + +### Templating API: static zcl helpers~asResolvedUnderlyingZclType() +Helper that behaves like asUnderlyingZclType, but resolves typedefs. + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) ### Templating API: static zcl helpers~asUnderlyingZclType(typeName, options) @@ -12654,6 +12908,25 @@ type is not struct | --- | | type | + + +### Templating API: static zcl helpers~if\_is\_typedef(type) ⇒ +If helper that checks if a type is a typedef + +* example: +{{#if_is_typedef type}} +type is typedef +{{else}} +type is not a typedef +{{/if_is_typedef}} + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) +**Returns**: Promise of content. + +| Param | +| --- | +| type | + ### Templating API: static zcl helpers~isClient(side) ⇒ @@ -18955,6 +19228,7 @@ This module provides the API to access various zcl utilities. * [~dataTypeCharacterFormatter(db, packageIds, type, options, resType)](#module_REST API_ various zcl utilities..dataTypeCharacterFormatter) * [~isEnum(db, enum_name, packageIds)](#module_REST API_ various zcl utilities..isEnum) ⇒ * [~isStruct(db, struct_name, packageIds)](#module_REST API_ various zcl utilities..isStruct) ⇒ + * [~isTypedef(db, typedef_name, packageIds)](#module_REST API_ various zcl utilities..isTypedef) ⇒ * [~isEvent(db, event_name, packageId)](#module_REST API_ various zcl utilities..isEvent) ⇒ * [~isBitmap(db, bitmap_name, packageIds)](#module_REST API_ various zcl utilities..isBitmap) ⇒ * [~defaultMessageForTypeConversion(fromType, toType, noWarning)](#module_REST API_ various zcl utilities..defaultMessageForTypeConversion) @@ -19169,6 +19443,20 @@ Local function that checks if a struct by the name exists | struct_name | \* | | packageIds | \* | + + +### REST API: various zcl utilities~isTypedef(db, typedef_name, packageIds) ⇒ +Local function that checks if a typedef by the name exists + +**Kind**: inner method of [REST API: various zcl utilities](#module_REST API_ various zcl utilities) +**Returns**: Promise of content. + +| Param | Type | +| --- | --- | +| db | \* | +| typedef_name | \* | +| packageIds | \* | + ### REST API: various zcl utilities~isEvent(db, event_name, packageId) ⇒ @@ -20136,6 +20424,8 @@ This module provides the APIs for dotdot Loading * [~prepareStruct(a, dataType)](#module_Loader API_ Loader APIs..prepareStruct) ⇒ * [~processStruct(db, filePath, packageId, knownPackages, data)](#module_Loader API_ Loader APIs..processStruct) ⇒ * [~processStructItems(db, filePath, packageIds, data)](#module_Loader API_ Loader APIs..processStructItems) ⇒ + * [~prepareTypedef(a, dataType)](#module_Loader API_ Loader APIs..prepareTypedef) ⇒ + * [~processTypedef(db, filePath, packageId, knownPackages, data)](#module_Loader API_ Loader APIs..processTypedef) ⇒ * [~prepareDeviceType(deviceType)](#module_Loader API_ Loader APIs..prepareDeviceType) ⇒ Object * [~processDeviceTypes(db, filePath, packageId, data, context)](#module_Loader API_ Loader APIs..processDeviceTypes) ⇒ Promise * [~processParsedZclData(db, argument)](#module_Loader API_ Loader APIs..processParsedZclData) ⇒ @@ -21477,6 +21767,35 @@ Processes the struct Items. | packageIds | \* | | data | \* | + + +### Loader API: Loader APIs~prepareTypedef(a, dataType) ⇒ +Prepare the typedef for database table insertion. + +**Kind**: inner method of [Loader API: Loader APIs](#module_Loader API_ Loader APIs) +**Returns**: An Object + +| Param | Type | +| --- | --- | +| a | \* | +| dataType | \* | + + + +### Loader API: Loader APIs~processTypedef(db, filePath, packageId, knownPackages, data) ⇒ +Processes the typedef. + +**Kind**: inner method of [Loader API: Loader APIs](#module_Loader API_ Loader APIs) +**Returns**: A promise of inserted typedefs. + +| Param | Type | +| --- | --- | +| db | \* | +| filePath | \* | +| packageId | \* | +| knownPackages | \* | +| data | \* | + ### Loader API: Loader APIs~prepareDeviceType(deviceType) ⇒ Object @@ -21970,6 +22289,8 @@ This module provides the APIs for for common functionality related to loading. * [~prepareStruct(a, dataType)](#module_Loader API_ Loader APIs..prepareStruct) ⇒ * [~processStruct(db, filePath, packageId, knownPackages, data)](#module_Loader API_ Loader APIs..processStruct) ⇒ * [~processStructItems(db, filePath, packageIds, data)](#module_Loader API_ Loader APIs..processStructItems) ⇒ + * [~prepareTypedef(a, dataType)](#module_Loader API_ Loader APIs..prepareTypedef) ⇒ + * [~processTypedef(db, filePath, packageId, knownPackages, data)](#module_Loader API_ Loader APIs..processTypedef) ⇒ * [~prepareDeviceType(deviceType)](#module_Loader API_ Loader APIs..prepareDeviceType) ⇒ Object * [~processDeviceTypes(db, filePath, packageId, data, context)](#module_Loader API_ Loader APIs..processDeviceTypes) ⇒ Promise * [~processParsedZclData(db, argument)](#module_Loader API_ Loader APIs..processParsedZclData) ⇒ @@ -23311,6 +23632,35 @@ Processes the struct Items. | packageIds | \* | | data | \* | + + +### Loader API: Loader APIs~prepareTypedef(a, dataType) ⇒ +Prepare the typedef for database table insertion. + +**Kind**: inner method of [Loader API: Loader APIs](#module_Loader API_ Loader APIs) +**Returns**: An Object + +| Param | Type | +| --- | --- | +| a | \* | +| dataType | \* | + + + +### Loader API: Loader APIs~processTypedef(db, filePath, packageId, knownPackages, data) ⇒ +Processes the typedef. + +**Kind**: inner method of [Loader API: Loader APIs](#module_Loader API_ Loader APIs) +**Returns**: A promise of inserted typedefs. + +| Param | Type | +| --- | --- | +| db | \* | +| filePath | \* | +| packageId | \* | +| knownPackages | \* | +| data | \* | + ### Loader API: Loader APIs~prepareDeviceType(deviceType) ⇒ Object @@ -23804,6 +24154,8 @@ This module provides the APIs for new data model loading * [~prepareStruct(a, dataType)](#module_Loader API_ Loader APIs..prepareStruct) ⇒ * [~processStruct(db, filePath, packageId, knownPackages, data)](#module_Loader API_ Loader APIs..processStruct) ⇒ * [~processStructItems(db, filePath, packageIds, data)](#module_Loader API_ Loader APIs..processStructItems) ⇒ + * [~prepareTypedef(a, dataType)](#module_Loader API_ Loader APIs..prepareTypedef) ⇒ + * [~processTypedef(db, filePath, packageId, knownPackages, data)](#module_Loader API_ Loader APIs..processTypedef) ⇒ * [~prepareDeviceType(deviceType)](#module_Loader API_ Loader APIs..prepareDeviceType) ⇒ Object * [~processDeviceTypes(db, filePath, packageId, data, context)](#module_Loader API_ Loader APIs..processDeviceTypes) ⇒ Promise * [~processParsedZclData(db, argument)](#module_Loader API_ Loader APIs..processParsedZclData) ⇒ @@ -25145,6 +25497,35 @@ Processes the struct Items. | packageIds | \* | | data | \* | + + +### Loader API: Loader APIs~prepareTypedef(a, dataType) ⇒ +Prepare the typedef for database table insertion. + +**Kind**: inner method of [Loader API: Loader APIs](#module_Loader API_ Loader APIs) +**Returns**: An Object + +| Param | Type | +| --- | --- | +| a | \* | +| dataType | \* | + + + +### Loader API: Loader APIs~processTypedef(db, filePath, packageId, knownPackages, data) ⇒ +Processes the typedef. + +**Kind**: inner method of [Loader API: Loader APIs](#module_Loader API_ Loader APIs) +**Returns**: A promise of inserted typedefs. + +| Param | Type | +| --- | --- | +| db | \* | +| filePath | \* | +| packageId | \* | +| knownPackages | \* | +| data | \* | + ### Loader API: Loader APIs~prepareDeviceType(deviceType) ⇒ Object @@ -25638,6 +26019,8 @@ This module provides the APIs for ZCL/Data-Model loading. * [~prepareStruct(a, dataType)](#module_Loader API_ Loader APIs..prepareStruct) ⇒ * [~processStruct(db, filePath, packageId, knownPackages, data)](#module_Loader API_ Loader APIs..processStruct) ⇒ * [~processStructItems(db, filePath, packageIds, data)](#module_Loader API_ Loader APIs..processStructItems) ⇒ + * [~prepareTypedef(a, dataType)](#module_Loader API_ Loader APIs..prepareTypedef) ⇒ + * [~processTypedef(db, filePath, packageId, knownPackages, data)](#module_Loader API_ Loader APIs..processTypedef) ⇒ * [~prepareDeviceType(deviceType)](#module_Loader API_ Loader APIs..prepareDeviceType) ⇒ Object * [~processDeviceTypes(db, filePath, packageId, data, context)](#module_Loader API_ Loader APIs..processDeviceTypes) ⇒ Promise * [~processParsedZclData(db, argument)](#module_Loader API_ Loader APIs..processParsedZclData) ⇒ @@ -26979,6 +27362,35 @@ Processes the struct Items. | packageIds | \* | | data | \* | + + +### Loader API: Loader APIs~prepareTypedef(a, dataType) ⇒ +Prepare the typedef for database table insertion. + +**Kind**: inner method of [Loader API: Loader APIs](#module_Loader API_ Loader APIs) +**Returns**: An Object + +| Param | Type | +| --- | --- | +| a | \* | +| dataType | \* | + + + +### Loader API: Loader APIs~processTypedef(db, filePath, packageId, knownPackages, data) ⇒ +Processes the typedef. + +**Kind**: inner method of [Loader API: Loader APIs](#module_Loader API_ Loader APIs) +**Returns**: A promise of inserted typedefs. + +| Param | Type | +| --- | --- | +| db | \* | +| filePath | \* | +| packageId | \* | +| knownPackages | \* | +| data | \* | + ### Loader API: Loader APIs~prepareDeviceType(deviceType) ⇒ Object diff --git a/docs/helpers.md b/docs/helpers.md index c86404f8f9..6d3aabc106 100644 --- a/docs/helpers.md +++ b/docs/helpers.md @@ -3322,12 +3322,15 @@ This module contains the API for templating. For more detailed instructions, rea * [~zcl_bitmaps(options)](#module_Templating API_ static zcl helpers..zcl_bitmaps) ⇒ * [~zcl_bitmap_items(options)](#module_Templating API_ static zcl helpers..zcl_bitmap_items) * [~zcl_enums(options)](#module_Templating API_ static zcl helpers..zcl_enums) ⇒ + * [~zcl_typedefs(options)](#module_Templating API_ static zcl helpers..zcl_typedefs) ⇒ * [~zcl_structs(options)](#module_Templating API_ static zcl helpers..zcl_structs) ⇒ * [~zcl_enum_items(options)](#module_Templating API_ static zcl helpers..zcl_enum_items) * [~first_unused_enum_value(options)](#module_Templating API_ static zcl helpers..first_unused_enum_value) ⇒ * [~zcl_struct_items(options)](#module_Templating API_ static zcl helpers..zcl_struct_items) ⇒ * [~zcl_struct_items_by_struct_name(name, options)](#module_Templating API_ static zcl helpers..zcl_struct_items_by_struct_name) ⇒ * [~zcl_struct_items_by_struct_and_cluster_name(name, clusterName, options)](#module_Templating API_ static zcl helpers..zcl_struct_items_by_struct_and_cluster_name) ⇒ + * [~zcl_typedef_by_typedef(name, options)](#module_Templating API_ static zcl helpers..zcl_typedef_by_typedef) ⇒ + * [~zcl_typedef_by_typedef_and_cluster_name(name, clusterName, options)](#module_Templating API_ static zcl helpers..zcl_typedef_by_typedef_and_cluster_name) ⇒ * [~zcl_device_types(options)](#module_Templating API_ static zcl helpers..zcl_device_types) ⇒ * [~zcl_device_type_clusters(options)](#module_Templating API_ static zcl helpers..zcl_device_type_clusters) ⇒ * [~zcl_device_type_cluster_commands(options)](#module_Templating API_ static zcl helpers..zcl_device_type_cluster_commands) ⇒ @@ -3357,6 +3360,7 @@ This module contains the API for templating. For more detailed instructions, rea * [~zcl_command_arguments(options)](#module_Templating API_ static zcl helpers..zcl_command_arguments) ⇒ * [~zcl_event_fields(options)](#module_Templating API_ static zcl helpers..zcl_event_fields) * [~zcl_command_argument_data_type(typeName, options)](#module_Templating API_ static zcl helpers..zcl_command_argument_data_type) + * [~asResolvedUnderlyingZclType()](#module_Templating API_ static zcl helpers..asResolvedUnderlyingZclType) * [~asUnderlyingZclType(typeName, options)](#module_Templating API_ static zcl helpers..asUnderlyingZclType) * [~zcl_string_type_return(type, options)](#module_Templating API_ static zcl helpers..zcl_string_type_return) * [~is_zcl_string(type)](#module_Templating API_ static zcl helpers..is_zcl_string) @@ -3370,6 +3374,7 @@ This module contains the API for templating. For more detailed instructions, rea * [~if_is_bitmap(type)](#module_Templating API_ static zcl helpers..if_is_bitmap) ⇒ * [~if_is_enum(type)](#module_Templating API_ static zcl helpers..if_is_enum) ⇒ * [~if_is_struct(type)](#module_Templating API_ static zcl helpers..if_is_struct) ⇒ + * [~if_is_typedef(type)](#module_Templating API_ static zcl helpers..if_is_typedef) ⇒ * [~isClient(side)](#module_Templating API_ static zcl helpers..isClient) ⇒ * [~isServer(side)](#module_Templating API_ static zcl helpers..isServer) ⇒ * [~isStrEqual(str1, str2)](#module_Templating API_ static zcl helpers..isStrEqual) ⇒ @@ -3441,6 +3446,21 @@ enums belonging to a cluster. | --- | --- | | options | \* | + + +### Templating API: static zcl helpers~zcl\_typedefs(options) ⇒ +Block helper iterating over all typedefs. +If existing independently, it iterates over ALL the typedefs. +Within a context of a cluster, it iterates only over the +typedefs belonging to a cluster. + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) +**Returns**: Promise of content. + +| Param | Type | +| --- | --- | +| options | \* | + ### Templating API: static zcl helpers~zcl\_structs(options) ⇒ @@ -3524,6 +3544,36 @@ ignored), or a struct associated with the given cluster. | clusterName | | options | + + +### Templating API: static zcl helpers~zcl\_typedef\_by\_typedef(name, options) ⇒ +Block helper for getting information for a typedef with a given name. + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) +**Returns**: Promise of content. + +| Param | +| --- | +| name | +| options | + + + +### Templating API: static zcl helpers~zcl\_typedef\_by\_typedef\_and\_cluster\_name(name, clusterName, options) ⇒ +Block helper for expanding a typedef. The typedef will be those that correspond to that +typedef name being used within the given cluster. That means the typedef name +must be either a global (in which case the cluster name is just +ignored), or a typedef associated with the given cluster. + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) +**Returns**: Promise of content. + +| Param | +| --- | +| name | +| clusterName | +| options | + ### Templating API: static zcl helpers~zcl\_device\_types(options) ⇒ @@ -3897,6 +3947,12 @@ Helper that deals with the type of the argument. | typeName | \* | | options | \* | + + +### Templating API: static zcl helpers~asResolvedUnderlyingZclType() +Helper that behaves like asUnderlyingZclType, but resolves typedefs. + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) ### Templating API: static zcl helpers~asUnderlyingZclType(typeName, options) @@ -4122,6 +4178,25 @@ type is not struct | --- | | type | + + +### Templating API: static zcl helpers~if\_is\_typedef(type) ⇒ +If helper that checks if a type is a typedef + +* example: +{{#if_is_typedef type}} +type is typedef +{{else}} +type is not a typedef +{{/if_is_typedef}} + +**Kind**: inner method of [Templating API: static zcl helpers](#module_Templating API_ static zcl helpers) +**Returns**: Promise of content. + +| Param | +| --- | +| type | + ### Templating API: static zcl helpers~isClient(side) ⇒ diff --git a/src-electron/db/db-mapping.js b/src-electron/db/db-mapping.js index 81eed3840d..af09247739 100644 --- a/src-electron/db/db-mapping.js +++ b/src-electron/db/db-mapping.js @@ -425,6 +425,19 @@ exports.map = { } }, + typedef: (x) => { + if (x == null) return undefined + return { + id: x.TYPEDEF_ID, + label: x.NAME, + name: x.NAME, + type: x.TYPE, + typeId: x.TYPE_ID, + caption: `Typedef, mapping to {@x.TYPE}`, + typedefClusterCount: x.TYPEDEF_CLUSTER_COUNT + } + }, + deviceType: (x) => { if (x == null) return undefined return { diff --git a/src-electron/db/query-data-type.js b/src-electron/db/query-data-type.js index d297737c58..54178fec50 100644 --- a/src-electron/db/query-data-type.js +++ b/src-electron/db/query-data-type.js @@ -239,6 +239,11 @@ async function selectSizeFromType(db, packageIds, value) { dataType.discriminatorName.toLowerCase() == dbEnum.zclType.string ) { return null + } else if ( + dataType && + dataType.discriminatorName.toLowerCase() == dbEnum.zclType.typedef + ) { + return await selectSizeFromType(db, packageIds, dataType.typeId) } else { return null } diff --git a/src-electron/db/query-loader.js b/src-electron/db/query-loader.js index 47e05882f9..99649ba6d2 100644 --- a/src-electron/db/query-loader.js +++ b/src-electron/db/query-loader.js @@ -2321,6 +2321,58 @@ async function insertStructItems(db, packageIds, data) { ) } +/** + * Insert all typedefs into the TypeDef Table. + * + * @param {*} db + * @param {*} packageIds + * @param {*} data + */ +async function insertTypedef(db, packageIds, data) { + return dbApi.dbMultiInsert( + db, + ` +INSERT INTO + TYPEDEF (TYPEDEF_ID, DATA_TYPE_REF) +VALUES ( + (SELECT + CASE + WHEN + (${SELECT_CLUSTER_SPECIFIC_DATA_TYPE} AND PACKAGE_REF IN (${dbApi.toInClause( + packageIds + )})) + IS + NULL + THEN + (${SELECT_GENERIC_DATA_TYPE} AND PACKAGE_REF IN (${dbApi.toInClause( + packageIds + )})) + ELSE + (${SELECT_CLUSTER_SPECIFIC_DATA_TYPE} AND PACKAGE_REF IN (${dbApi.toInClause( + packageIds + )})) + END AS DATA_TYPE_ID), + (SELECT + DATA_TYPE_ID + FROM + DATA_TYPE + WHERE + DATA_TYPE.PACKAGE_REF IN (${dbApi.toInClause(packageIds)}) + AND DATA_TYPE.NAME = ?))`, + data.map((at) => [ + at.name, + at.discriminator_ref, + at.cluster_code ? parseInt(at.cluster_code[0].$.code, 16) : null, + at.name, + at.discriminator_ref, + at.name, + at.discriminator_ref, + at.cluster_code ? parseInt(at.cluster_code[0].$.code, 16) : null, + at.type + ]) + ) +} + exports.insertGlobals = insertGlobals exports.insertClusterExtensions = insertClusterExtensions exports.insertClusters = insertClusters @@ -2346,6 +2398,7 @@ exports.insertBitmap = insertBitmap exports.insertBitmapFields = insertBitmapFields exports.insertStruct = insertStruct exports.insertStructItems = insertStructItems +exports.insertTypedef = insertTypedef exports.updateDataTypeClusterReferences = updateDataTypeClusterReferences exports.insertAttributeMappings = insertAttributeMappings exports.insertEndpointComposition = insertEndpointComposition diff --git a/src-electron/db/query-typedef.js b/src-electron/db/query-typedef.js new file mode 100644 index 0000000000..19d02bf438 --- /dev/null +++ b/src-electron/db/query-typedef.js @@ -0,0 +1,230 @@ +/** + * + * Copyright (c) 2024 Silicon Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * This module provides queries for typedefs. + * + * @module DB API: zcl database typedef access + */ + +const dbApi = require('./db-api') +const dbCache = require('./db-cache') +const dbMapping = require('./db-mapping') +const queryUtil = require('./query-util') + +/** + * Retrieves all the typedefs in the database. + * + * @export + * @param {*} db + * @param {*} packageId + * @returns Promise that resolves with the rows of typedefs. + */ +async function selectAllTypedefs(db, packageId) { + return dbApi + .dbAll( + db, + ` +SELECT + T.TYPEDEF_ID, + DATA_TYPE.NAME, + DATA_TYPE.DISCRIMINATOR_REF, + (SELECT COUNT(1) FROM DATA_TYPE_CLUSTER WHERE DATA_TYPE_CLUSTER.DATA_TYPE_REF = T.TYPEDEF_ID) AS TYPEDEF_CLUSTER_COUNT, + (SELECT DATA_TYPE.NAME FROM DATA_TYPE WHERE DATA_TYPE.DATA_TYPE_ID = T.DATA_TYPE_REF) AS TYPE, + T.DATA_TYPE_REF as TYPE_ID +FROM + TYPEDEF AS T +INNER JOIN DATA_TYPE ON + T.TYPEDEF_ID = DATA_TYPE.DATA_TYPE_ID +WHERE + DATA_TYPE.PACKAGE_REF = ? +ORDER BY DATA_TYPE.NAME`, + [packageId] + ) + .then((rows) => rows.map(dbMapping.map.typedef)) +} + +/** + * Retrieves all the typedefs with cluster references in the database. + * + * @export + * @param {*} db + * @param {*} packageId + * @param {*} clusterId + * @returns Promise that resolves with the rows of typedefs. + */ +async function selectClusterTypedefs(db, packageIds, clusterId) { + return dbApi + .dbAll( + db, + ` +SELECT + T.TYPEDEF_ID, + DT.NAME, + (SELECT COUNT(1) FROM DATA_TYPE_CLUSTER WHERE DATA_TYPE_CLUSTER.DATA_TYPE_REF = T.TYPEDEF_ID) AS TYPEDEF_CLUSTER_COUNT, + (SELECT DATA_TYPE.NAME FROM DATA_TYPE WHERE DATA_TYPE.DATA_TYPE_ID = T.DATA_TYPE_REF) AS TYPE, + T.DATA_TYPE_REF as TYPE_ID +FROM + TYPEDEF AS T +INNER JOIN + DATA_TYPE AS DT +ON + DT.DATA_TYPE_ID = T.TYPEDEF_ID +INNER JOIN + DATA_TYPE_CLUSTER +ON + DT.DATA_TYPE_ID = DATA_TYPE_CLUSTER.DATA_TYPE_REF +WHERE + DT.PACKAGE_REF IN (${dbApi.toInClause(packageIds)}) + AND DATA_TYPE_CLUSTER.CLUSTER_REF = ? +ORDER BY DT.NAME`, + [clusterId] + ) + .then((rows) => rows.map(dbMapping.map.typedef)) +} + +/** + * Select a typedef matched by its primary key. + * @param {*} db + * @param {*} id + * @returns an typedef or underfined if not found + */ +async function selectTypedefById(db, id) { + return dbApi + .dbGet( + db, + ` +SELECT + T.TYPEDEF_ID, + DATA_TYPE.NAME, + (SELECT DATA_TYPE.NAME FROM DATA_TYPE WHERE DATA_TYPE.DATA_TYPE_ID = T.DATA_TYPE_REF) AS TYPE, + T.DATA_TYPE_REF as TYPE_ID +FROM + TYPEDEF AS T +INNER JOIN + DATA_TYPE +ON + T.TYPEDEF_ID = DATA_TYPE.DATA_TYPE_ID +WHERE + TYPEDEF_ID = ?`, + [id] + ) + .then(dbMapping.map.typedef) +} + +/** + * Select a typedef matched by name. + * + * @param {*} db + * @param {*} name + * @param {*} packageIds + * @param {*} clusterName + * @returns typedef or undefined + */ +async function selectTypedefByName(db, name, packageIds, clusterName = null) { + let clusterJoinQuery = '' + let clusterWhereQuery = '' + if (clusterName) { + clusterJoinQuery = ` + INNER JOIN + DATA_TYPE_CLUSTER + ON + DATA_TYPE_CLUSTER.DATA_TYPE_REF = DT.DATA_TYPE_ID + INNER JOIN + CLUSTER + ON + DATA_TYPE_CLUSTER.CLUSTER_REF = CLUSTER.CLUSTER_ID + ` + clusterWhereQuery = ` + AND + CLUSTER.NAME = "${clusterName}" + ` + } + return dbApi + .dbGet( + db, + ` +SELECT + T.TYPEDEF_ID, + DT.NAME AS NAME, + (SELECT COUNT(1) FROM DATA_TYPE_CLUSTER WHERE DATA_TYPE_CLUSTER.DATA_TYPE_REF = T.TYPEDEF_ID) AS TYPEDEF_CLUSTER_COUNT, + (SELECT DATA_TYPE.NAME FROM DATA_TYPE WHERE DATA_TYPE.DATA_TYPE_ID = T.DATA_TYPE_REF) AS TYPE, + T.DATA_TYPE_REF as TYPE_ID +FROM + TYPEDEF AS T +INNER JOIN + DATA_TYPE AS DT +ON + T.TYPEDEF_ID = DT.DATA_TYPE_ID + ${clusterJoinQuery} +WHERE + (DT.NAME = ? OR DT.NAME = ?) AND DT.PACKAGE_REF IN (${dbApi.toInClause( + packageIds + )}) + ${clusterWhereQuery} +ORDER BY NAME`, + [name, name.toLowerCase()] + ) + .then(dbMapping.map.typedef) +} + +/** + * Select a typedef matched by name and clusterId. + * + * @param {*} db + * @param {*} name + * @param {*} clusterId + * @param {*} packageIds + * @returns typedef information or undefined + */ +async function selectTypedefByNameAndClusterId( + db, + name, + clusterId, + packageIds +) { + let queryWithoutClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId( + 'typedef', + null, + packageIds + ) + let queryWithClusterId = queryUtil.sqlQueryForDataTypeByNameAndClusterId( + 'typedef', + clusterId, + packageIds + ) + let res = await dbApi + .dbAll(db, queryWithoutClusterId, [name, name.toLowerCase()]) + .then((rows) => rows.map(dbMapping.map.typedef)) + + if (res && res.length == 1) { + return res[0] + } else { + return dbApi + .dbGet(db, queryWithClusterId, [name, name.toLowerCase(), clusterId]) + .then(dbMapping.map.typedef) + } +} + +// exports +exports.selectAllTypedefs = selectAllTypedefs +exports.selectTypedefByName = dbCache.cacheQuery(selectTypedefByName) +exports.selectTypedefByNameAndClusterId = dbCache.cacheQuery( + selectTypedefByNameAndClusterId +) +exports.selectTypedefById = selectTypedefById +exports.selectClusterTypedefs = selectClusterTypedefs diff --git a/src-electron/db/query-zcl.js b/src-electron/db/query-zcl.js index 2af9d92e4f..463cecace3 100644 --- a/src-electron/db/query-zcl.js +++ b/src-electron/db/query-zcl.js @@ -31,6 +31,7 @@ const queryDataType = require('./query-data-type') const queryNumber = require('./query-number') const queryString = require('./query-string') const queryDiscriminator = require('./query-data-type-discriminator') +const queryTypedef = require('./query-typedef') /** * Retrieves all the bitmaps that are associated with a cluster. @@ -291,6 +292,47 @@ ORDER BY C.CODE `, .then((rows) => rows.map(dbMapping.map.cluster)) } +/** + * Returns an array of clusters that the typedef belongs to. + * @param {*} db + * @param {*} typeDefId + * @returns clusters + */ +async function selectTypedefClusters(db, typeDefId) { + return dbApi + .dbAll( + db, + ` +SELECT + C.CLUSTER_ID, + C.CODE, + C.MANUFACTURER_CODE, + C.NAME, + C.DESCRIPTION, + C.DEFINE, + C.DOMAIN_NAME, + C.IS_SINGLETON, + C.REVISION, + C.API_MATURITY +FROM + CLUSTER AS C +INNER JOIN + DATA_TYPE_CLUSTER AS DTC +ON + DTC.CLUSTER_REF = C.CLUSTER_ID +INNER JOIN + TYPEDEF AS T +ON + T.TYPEDEF_ID = DTC.DATA_TYPE_REF +WHERE + T.TYPEDEF_ID = ? +ORDER BY C.CODE + `, + [typeDefId] + ) + .then((rows) => rows.map(dbMapping.map.cluster)) +} + /** * Retrieves all the cluster-related structs in the database with the items. * @@ -1307,6 +1349,7 @@ exports.selectEndpointTypeEventsByEndpointId = exports.selectEnumClusters = selectEnumClusters exports.selectStructClusters = selectStructClusters exports.selectBitmapClusters = selectBitmapClusters +exports.selectTypedefClusters = selectTypedefClusters // Forwarded exports so we don't break API. exports.selectAllAtomics = queryAtomic.selectAllAtomics @@ -1321,6 +1364,13 @@ exports.selectEnumById = queryEnum.selectEnumById exports.selectEnumByName = queryEnum.selectEnumByName exports.selectEnumByNameAndClusterId = queryEnum.selectEnumByNameAndClusterId +exports.selectAllTypedefs = queryTypedef.selectAllTypedefs +exports.selectClusterTypedefs = queryTypedef.selectClusterTypedefs +exports.selectTypedefByName = queryTypedef.selectTypedefByName +exports.selectTypedefById = queryTypedef.selectTypedefById +exports.selectTypedefByNameAndClusterId = + queryTypedef.selectTypedefByNameAndClusterId + exports.selectStructById = queryStruct.selectStructById exports.selectStructByName = queryStruct.selectStructByName exports.selectStructByNameAndClusterId = diff --git a/src-electron/db/zap-schema.sql b/src-electron/db/zap-schema.sql index 870783920a..13a4334b47 100644 --- a/src-electron/db/zap-schema.sql +++ b/src-electron/db/zap-schema.sql @@ -655,6 +655,18 @@ CREATE TABLE IF NOT EXISTS "ENUM_ITEM" ( FOREIGN KEY (ENUM_REF) REFERENCES "ENUM"(ENUM_ID) ON DELETE CASCADE ON UPDATE CASCADE UNIQUE(ENUM_REF, FIELD_IDENTIFIER) ); + +/* + TYPEDEF table contains typedefs directly loaded from packages. + */ +DROP TABLE IF EXISTS "TYPEDEF"; +CREATE TABLE IF NOT EXISTS "TYPEDEF" ( + TYPEDEF_ID integer NOT NULL PRIMARY KEY, + DATA_TYPE_REF integer NOT NULL, + FOREIGN KEY (TYPEDEF_ID) REFERENCES DATA_TYPE(DATA_TYPE_ID) ON DELETE CASCADE ON UPDATE CASCADE, + FOREIGN KEY (DATA_TYPE_REF) REFERENCES DATA_TYPE(DATA_TYPE_ID) ON DELETE CASCADE ON UPDATE CASCADE +); + /* STRUCT table contains structs directly loaded from packages. */ @@ -1320,7 +1332,7 @@ CREATE TRIGGER UPDATE_MULTIPROTOCOL_ATTRIBUTES_ACROSS_ENDPOINT_TYPES AFTER UPDATE ON ENDPOINT_TYPE_ATTRIBUTE -WHEN +WHEN ( ( SELECT @@ -1385,7 +1397,7 @@ BEGIN IN ( SELECT - CASE + CASE WHEN new.ENDPOINT_TYPE_ATTRIBUTE_ID = ETA1.ENDPOINT_TYPE_ATTRIBUTE_ID THEN ETA2.ENDPOINT_TYPE_ATTRIBUTE_ID WHEN new.ENDPOINT_TYPE_ATTRIBUTE_ID = ETA2.ENDPOINT_TYPE_ATTRIBUTE_ID THEN ETA1.ENDPOINT_TYPE_ATTRIBUTE_ID END AS ENDPOINT_TYPE_ATTRIBUTE_ID @@ -3397,13 +3409,13 @@ WHERE SESSION_ID = OLD.SESSION_REF; END; /* -____ _ _ ____ ___ ____ _ _ _ _ _ _ _ ___ ____ _ ____ ____ ____ ____ ____ -| | | [__ | | | |\/| \/ |\/| | | |__/ | | __ | __ |___ |__/ [__ -|___ |__| ___] | |__| | | _/\_ | | |___ | | \ | |__] |__] |___ | \ ___] +____ _ _ ____ ___ ____ _ _ _ _ _ _ _ ___ ____ _ ____ ____ ____ ____ ____ +| | | [__ | | | |\/| \/ |\/| | | |__/ | | __ | __ |___ |__/ [__ +|___ |__| ___] | |__| | | _/\_ | | |___ | | \ | |__] |__] |___ | \ ___] Custom XML specific triggers -*/ - +*/ + /* Triggers that deal with code conflicts in custom xml */ /* Trigger that deals with code conflicts in clusters when new session package is inserted */ @@ -4096,9 +4108,9 @@ BEGIN 0 FROM COMMAND_ARG a - INNER JOIN + INNER JOIN COMMAND c - ON + ON a.COMMAND_REF = c.COMMAND_ID INNER JOIN PACKAGE p @@ -4180,9 +4192,9 @@ BEGIN 0 FROM COMMAND_ARG a - INNER JOIN + INNER JOIN COMMAND c - ON + ON a.COMMAND_REF = c.COMMAND_ID INNER JOIN PACKAGE p @@ -4264,7 +4276,7 @@ BEGIN EVENT_FIELD f INNER JOIN EVENT e - ON + ON f.EVENT_REF = e.EVENT_ID INNER JOIN PACKAGE p @@ -4348,7 +4360,7 @@ BEGIN EVENT_FIELD f INNER JOIN EVENT e - ON + ON f.EVENT_REF = e.EVENT_ID INNER JOIN PACKAGE p diff --git a/src-electron/generator/generation-engine.js b/src-electron/generator/generation-engine.js index a8e6032f9d..5f6f4481cb 100644 --- a/src-electron/generator/generation-engine.js +++ b/src-electron/generator/generation-engine.js @@ -841,6 +841,7 @@ async function generateSingleTemplate( } else { genFunction = templateEngine.produceContent } + genResult.sources[singleTemplatePkg.category] = singleTemplatePkg.path try { let resultArray = await genFunction( hb, @@ -899,6 +900,7 @@ async function generate( content: {}, stats: {}, errors: {}, + sources: {}, hasErrors: false, generatorOptions: templateGeneratorOptions, templatePath: path.dirname(pkg.path) diff --git a/src-electron/generator/helper-zcl.js b/src-electron/generator/helper-zcl.js index 23d4d23f8e..902aeb859a 100644 --- a/src-electron/generator/helper-zcl.js +++ b/src-electron/generator/helper-zcl.js @@ -117,6 +117,40 @@ async function zcl_enums(options) { return templateUtil.templatePromise(this.global, promise) } +/** + * Block helper iterating over all typedefs. + * If existing independently, it iterates over ALL the typedefs. + * Within a context of a cluster, it iterates only over the + * typedefs belonging to a cluster. + * + * @param {*} options + * @returns Promise of content. + */ +async function zcl_typedefs(options) { + let packageIds = await templateUtil.ensureZclPackageIds(this) + let tds + if (this.id != null) { + tds = await queryZcl.selectClusterTypedefs( + this.global.db, + packageIds, + this.id + ) + } else { + tds = await Promise.all( + packageIds.map((packageId) => + queryZcl.selectAllTypedefs(this.global.db, packageId) + ) + ).then((x) => x.flat()) + } + tds.forEach((td) => { + td.has_no_clusters = td.typedefClusterCount < 1 + td.has_one_cluster = td.typedefClusterCount == 1 + td.has_more_than_one_cluster = td.typedefClusterCount > 1 + }) + let promise = templateUtil.collectBlocks(tds, options, this) + return templateUtil.templatePromise(this.global, promise) +} + /** * Block helper iterating over all structs. * If existing independently, it iterates over ALL the structs. @@ -362,6 +396,53 @@ async function zcl_struct_items_by_struct_and_cluster_name( .then((st) => templateUtil.collectBlocks(st, options, this)) return templateUtil.templatePromise(this.global, promise) } +/** + * Block helper for getting information for a typedef with a given name. + * + * @param name + * @param options + * @returns Promise of content. + */ +async function zcl_typedef_by_typedef(name, options) { + let packageIds = await templateUtil.ensureZclPackageIds(this) + let promise = queryZcl + .selectTypedefByName(this.global.db, name, packageIds) + .then((td) => templateUtil.collectBlocks([td], options, this)) + return templateUtil.templatePromise(this.global, promise) +} + +/** + * Block helper for expanding a typedef. The typedef will be those that correspond to that + * typedef name being used within the given cluster. That means the typedef name + * must be either a global (in which case the cluster name is just + * ignored), or a typedef associated with the given cluster. + * + * @param name + * @param clusterName + * @param options + * @returns Promise of content. + */ +async function zcl_typedef_by_typedef_and_cluster_name( + name, + clusterName, + options +) { + let packageIds = await templateUtil.ensureZclPackageIds(this) + // Check for a global typedef first. + const typedefObj = await queryZcl.selectTypedefByName( + this.global.db, + name, + packageIds + ) + if (typedefObj.typedefClusterCount == 0) { + // Just ignore the cluster name. + return zcl_typedef_by_typedef.call(this, name, options) + } + let promise = queryZcl + .selectTypedefByName(this.global.db, name, packageIds, clusterName) + .then((td) => templateUtil.collectBlocks([td], options, this)) + return templateUtil.templatePromise(this.global, promise) +} /** * Block helper iterating over all deviceTypes. @@ -1249,7 +1330,8 @@ function zcl_command_argument_data_type(type, options) { Promise.all([ zclUtil.isEnum(this.global.db, type, packageIds), zclUtil.isStruct(this.global.db, type, packageIds), - zclUtil.isBitmap(this.global.db, type, packageIds) + zclUtil.isBitmap(this.global.db, type, packageIds), + zclUtil.isTypedef(this.global.db, type, packageIds) ]) .then( (res) => @@ -1277,6 +1359,12 @@ function zcl_command_argument_data_type(type, options) { type, packageIds ) + case dbEnum.zclType.typedef: + return helperC.data_type_for_typedef( + this.global.db, + type, + packageIds + ) case dbEnum.zclType.struct: return options.hash.struct case dbEnum.zclType.atomic: @@ -1297,6 +1385,26 @@ function zcl_command_argument_data_type(type, options) { return templateUtil.templatePromise(this.global, promise) } +/** + * Helper that behaves like asUnderlyingZclType, but resolves typedefs. + */ +async function asResolvedUnderlyingZclType(type, options) { + const packageIds = await templateUtil.ensureZclPackageIds(this) + let typedef = await queryZcl.selectTypedefByName( + this.global.db, + type, + packageIds + ) + let resolvedType = typedef ? typedef.type : type + let promise = zclUtil + .asUnderlyingZclTypeWithPackageId(resolvedType, options, packageIds, this) + .catch((err) => { + env.logError(err) + throw err + }) + return templateUtil.templatePromise(this.global, promise) +} + /** * Helper that deals with the type of the argument. * @@ -1696,6 +1804,34 @@ async function if_is_struct(type, options) { return templateUtil.templatePromise(this.global, promise) } +/** + * If helper that checks if a type is a typedef + * + * * example: + * {{#if_is_typedef type}} + * type is typedef + * {{else}} + * type is not a typedef + * {{/if_is_typedef}} + * + * @param type + * @returns Promise of content. + */ +async function if_is_typedef(type, options) { + let promise = templateUtil + .ensureZclPackageIds(this) + .then((packageIds) => + type && typeof type === 'string' + ? queryZcl.selectTypedefByName(this.global.db, type, packageIds) + : null + ) + .then((res) => + res ? res : queryZcl.selectTypedefById(this.global.db, type) + ) + .then((res) => (res ? options.fn(this) : options.inverse(this))) + return templateUtil.templatePromise(this.global, promise) +} + /** * Checks if the side is client or not * @@ -2945,6 +3081,7 @@ exports.zcl_structs = zcl_structs exports.zcl_struct_items = zcl_struct_items exports.zcl_struct_items_by_struct_name = zcl_struct_items_by_struct_name exports.zcl_clusters = zcl_clusters +exports.zcl_typedefs = zcl_typedefs exports.zcl_device_types = zcl_device_types exports.zcl_device_type_clusters = zcl_device_type_clusters exports.zcl_device_type_cluster_commands = zcl_device_type_cluster_commands @@ -2997,6 +3134,10 @@ exports.as_underlying_zcl_type = asUnderlyingZclType exports.asUnderlyingZclType = dep(asUnderlyingZclType, { to: 'as_underlying_zcl_type' }) +exports.as_resolved_underlying_zcl_type = asResolvedUnderlyingZclType +exports.asResolvedUnderlyingZclType = dep(asResolvedUnderlyingZclType, { + to: 'as_resolved_underlying_zcl_type' +}) exports.if_is_bitmap = if_is_bitmap @@ -3011,6 +3152,9 @@ exports.isStruct = dep(zclUtil.isStruct, { to: 'is_struct' }) exports.is_enum = zclUtil.isEnum exports.isEnum = dep(zclUtil.isEnum, { to: 'is_enum' }) +exports.is_typedef = zclUtil.isTypedef +exports.isTypedef = dep(zclUtil.isTypedef, { to: 'is_typedef' }) + exports.is_event = zclUtil.isEvent exports.isEvent = dep(zclUtil.isEvent, { to: 'is_event' }) @@ -3085,6 +3229,7 @@ exports.as_underlying_zcl_type_ca_always_present_with_presentif = dep( 'as_underlying_zcl_type_ca_always_present_with_presentif has been deprecated. Use as_underlying_zcl_type and if_command_arg_always_present_with_presentif instead.' ) exports.if_is_struct = if_is_struct +exports.if_is_typedef = if_is_typedef exports.if_mfg_specific_cluster = if_mfg_specific_cluster exports.first_unused_enum_value = first_unused_enum_value exports.zcl_commands_with_cluster_info = zcl_commands_with_cluster_info @@ -3104,5 +3249,7 @@ exports.if_compare = if_compare exports.if_is_data_type_signed = if_is_data_type_signed exports.as_zcl_data_type_size = as_zcl_data_type_size exports.zcl_command_responses = zcl_command_responses +exports.zcl_typedef_by_typedef_and_cluster_name = + zcl_typedef_by_typedef_and_cluster_name exports.zcl_struct_items_by_struct_and_cluster_name = zcl_struct_items_by_struct_and_cluster_name diff --git a/src-electron/generator/matter/app/zap-templates/templates/app/helper.js b/src-electron/generator/matter/app/zap-templates/templates/app/helper.js index 1989ffe43b..3623aae216 100644 --- a/src-electron/generator/matter/app/zap-templates/templates/app/helper.js +++ b/src-electron/generator/matter/app/zap-templates/templates/app/helper.js @@ -437,7 +437,7 @@ function chip_endpoint_data_version_count() { async function asNativeType(type) { function fn(pkgId) { const options = { hash: {} }; - return zclHelper.asUnderlyingZclType + return zclHelper.asResolvedUnderlyingZclType .call(this, type, options) .then((zclType) => { return ChipTypesHelper.asBasicType(zclType); @@ -453,7 +453,6 @@ async function asNativeType(type) { }); return templateUtil.templatePromise(this.global, promise); } - async function asTypedExpression(value, type) { const valueIsANumber = !isNaN(value); if (!value || valueIsANumber) { @@ -680,7 +679,8 @@ async function zapTypeToClusterObjectType(type, isDecodable, options) { isEnum: await typeChecker('isEnum'), isBitmap: await typeChecker('isBitmap'), isEvent: await typeChecker('isEvent'), - isStruct: await typeChecker('isStruct') + isStruct: await typeChecker('isStruct'), + isTypedef: await typeChecker('isTypedef') }; const typesCount = Object.values(types).filter((isType) => isType).length; @@ -751,6 +751,20 @@ async function zapTypeToClusterObjectType(type, isDecodable, options) { ); } + if (types.isTypedef) { + const typedefObj = await zclQuery.selectTypedefByName( + this.global.db, + type, + pkgId + ); + + const ns = nsValueToNamespace( + options.hash.ns, + typedefObj.typedefClusterCount + ); + return ns + asUpperCamelCase.call(this, type, options); + } + if (types.isEvent) { passByReference = true; // There are no global events, so just pass 1 for cluster count. @@ -861,6 +875,21 @@ async function _zapTypeToPythonClusterObjectType(type, options) { return ns + '.Structs.' + type; } + if (await typeChecker('isTypedef')) { + const typedefObj = await zclQuery.selectTypedefByName( + this.global.db, + type, + pkgId + ); + + const ns = nsValueToPythonNamespace( + options.hash.ns, + typedefObj.structClusterCount + ); + + return ns + '.Typedefs.' + type; + } + if (StringHelper.isCharString(type)) { return 'str'; } @@ -890,7 +919,7 @@ async function _zapTypeToPythonClusterObjectType(type, options) { return 'uint'; } - let resolvedType = await zclHelper.asUnderlyingZclType.call( + let resolvedType = await zclHelper.asResolvedUnderlyingZclType.call( { global: this.global }, type, options @@ -961,6 +990,15 @@ async function _getPythonFieldDefault(type, options) { return 'field(default_factory=lambda: ' + ns + '.Structs.' + type + '())'; } + if (await typeChecker('isTypedef')) { + const typedefObj = await zclQuery.selectTypedefByName( + this.global.db, + type, + pkgId + ); + return _getPythonFieldDefault.call(this, typedefObj.type, options); + } + if (StringHelper.isCharString(type)) { return '""'; } @@ -986,7 +1024,7 @@ async function _getPythonFieldDefault(type, options) { return '0'; } - let resolvedType = await zclHelper.asUnderlyingZclType.call( + let resolvedType = await zclHelper.asResolvedUnderlyingZclType.call( { global: this.global }, type, options diff --git a/src-electron/generator/matter/app/zap-templates/templates/chip/helper.js b/src-electron/generator/matter/app/zap-templates/templates/chip/helper.js index 2f9df06146..3271ec2d48 100644 --- a/src-electron/generator/matter/app/zap-templates/templates/chip/helper.js +++ b/src-electron/generator/matter/app/zap-templates/templates/chip/helper.js @@ -665,7 +665,21 @@ async function if_chip_complex(options) { if (checkResult != 'unknown') { result = options.fn(this); } else { - result = options.inverse(this); + let typedefResult = await zclHelper.isTypedef( + this.global.db, + this.type, + pkgIds + ); + if (typedefResult != 'unknown') { + result = options.fn(this); + } else { + try { + result = options.inverse(this); + } catch (err) { + console.log('Failure processing ${this.type}'); + throw err; + } + } } return templateUtil.templatePromise(this.global, result); } diff --git a/src-electron/generator/matter/chip-tool/templates/helper.js b/src-electron/generator/matter/chip-tool/templates/helper.js index 15202a08e2..60a5adafdd 100644 --- a/src-electron/generator/matter/chip-tool/templates/helper.js +++ b/src-electron/generator/matter/chip-tool/templates/helper.js @@ -32,7 +32,7 @@ function asTypeMinValue(type) { function fn(pkgId) { const options = { hash: {} }; this.isArray = false; - return zclHelper.asUnderlyingZclType + return zclHelper.asResolvedUnderlyingZclType .call(this, type, options) .then((zclType) => { const basicType = ChipTypesHelper.asBasicType(zclType); diff --git a/src-electron/generator/matter/controller/java/templates/helper.js b/src-electron/generator/matter/controller/java/templates/helper.js index ceaa81a472..0526f62d12 100644 --- a/src-electron/generator/matter/controller/java/templates/helper.js +++ b/src-electron/generator/matter/controller/java/templates/helper.js @@ -48,7 +48,7 @@ function convertBasicCTypeToJavaType(cType) { case 'double': return 'double'; default: - error = 'Unhandled type ' + cType; + let error = 'Unhandled type in convertBasicCTypeToJavaType ' + cType; throw error; } } @@ -66,7 +66,7 @@ function convertBasicCTypeToJniType(cType) { case 'double': return 'jdouble'; default: - error = 'Unhandled type ' + cType; + let error = 'Unhandled type in convertBasicCTypeToJniType ' + cType; throw error; } } @@ -84,12 +84,12 @@ function convertBasicCTypeToJavaBoxedType(cType) { case 'double': return 'Double'; default: - error = 'Unhandled type ' + cType; + let error = 'Unhandled type in convertBasicCTypeToJavaBoxedType ' + cType; throw error; } } -function asJavaBoxedType(type, zclType) { +async function asJavaBoxedType(type, zclType) { if (StringHelper.isOctetString(type)) { return 'byte[]'; } else if (StringHelper.isCharString(type)) { @@ -118,7 +118,7 @@ function asJniBasicType(type, useBoxedTypes) { } function fn(pkgId) { const options = { hash: {} }; - return zclHelper.asUnderlyingZclType + return zclHelper.asResolvedUnderlyingZclType .call(this, type, options) .then((zclType) => { return convertBasicCTypeToJniType( @@ -141,7 +141,7 @@ function asJniBasicType(type, useBoxedTypes) { function asJniSignatureBasic(type, useBoxedTypes) { function fn(pkgId) { const options = { hash: {} }; - return zclHelper.asUnderlyingZclType + return zclHelper.asResolvedUnderlyingZclType .call(this, type, options) .then((zclType) => { return convertCTypeToJniSignature( @@ -191,7 +191,11 @@ function convertCTypeToJniSignature(cType, useBoxedTypes) { case 'Float': return 'Ljava/lang/Float;'; default: - error = 'Unhandled Java type ' + javaType + ' for C type ' + cType; + let error = + 'Unhandled Java type in convertCTypeToJniSignature ' + + javaType + + ' for C type ' + + cType; throw error; } } @@ -278,7 +282,7 @@ async function as_underlying_java_zcl_type_util( } else if (characterStringTypes.includes(type.toUpperCase())) { return isBoxedJavaType ? 'String' : 'CharString'; } else { - let error = 'Unhandled type ' + type; + let error = 'Unhandled type in as_underlying_java_zcl_type_util ' + type; if (isBoxedJavaType) { return 'Object'; } else { @@ -307,7 +311,11 @@ async function as_underlying_java_zcl_type(type, clusterId, options) { async function asUnderlyingBasicType(type) { const options = { hash: {} }; - let zclType = await zclHelper.asUnderlyingZclType.call(this, type, options); + let zclType = await zclHelper.asResolvedUnderlyingZclType.call( + this, + type, + options + ); return ChipTypesHelper.asBasicType(zclType); } @@ -321,6 +329,13 @@ async function asJavaType(type, zclType, cluster, options) { .isStruct(this.global.db, type, pkgIds) .then((zclType) => zclType != 'unknown'); + let typedef = await queryZcl.selectStructByNameAndClusterId( + this.global.db, + type, + cluster, + pkgIds + ); + let classType = ''; if (StringHelper.isOctetString(type)) { @@ -331,6 +346,8 @@ async function asJavaType(type, zclType, cluster, options) { classType += `ChipStructs.${appHelper.asUpperCamelCase( cluster )}Cluster${appHelper.asUpperCamelCase(type)}`; + } else if (typedef) { + return asJavaType(typedef.type, null, cluster, options); } else { let javaBoxedType = asJavaBoxedType(type, zclType); if (javaBoxedType == 'Object' && options.hash.clusterId) { diff --git a/src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js b/src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js index b986e1e880..c7b55015a8 100644 --- a/src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js +++ b/src-electron/generator/matter/darwin/Framework/CHIP/templates/helper.js @@ -83,7 +83,7 @@ async function asTypedExpressionFromObjectiveC(value, type) { function asObjectiveCNumberType(label, type, asLowerCased) { function fn(pkgId) { const options = { hash: {} }; - return zclHelper.asUnderlyingZclType + return zclHelper.asResolvedUnderlyingZclType .call(this, type, options) .then((zclType) => { const basicType = ChipTypesHelper.asBasicType(zclType); diff --git a/src-electron/generator/template-util.js b/src-electron/generator/template-util.js index 8a2f83f7b1..abb88f97d4 100644 --- a/src-electron/generator/template-util.js +++ b/src-electron/generator/template-util.js @@ -88,8 +88,13 @@ async function collectBlocks(resultArray, options, context) { count: resultArray.length, ...element } - let block = options.fn(newContext) - promises.push(block) + try { + let block = options.fn(newContext) + promises.push(block) + } catch (err) { + console.log(`Failure processing ${this.type}`) + throw err + } }) // The else block gets executed if the list is empty. diff --git a/src-electron/main-process/startup.js b/src-electron/main-process/startup.js index 9ac9b51219..e08bd82a9f 100644 --- a/src-electron/main-process/startup.js +++ b/src-electron/main-process/startup.js @@ -873,7 +873,9 @@ async function generateSingleFile( if (genResult.hasErrors) { console.log(JSON.stringify(genResult.errors)) - throw new Error(`Generation failed: ${zapFile}`) + throw new Error( + `Generation failed: ${zapFile} ${JSON.stringify(genResult.sources)}` + ) } genResults.push(genResult) } diff --git a/src-electron/util/zcl-util.js b/src-electron/util/zcl-util.js index a540f5553e..8be54a4fbb 100644 --- a/src-electron/util/zcl-util.js +++ b/src-electron/util/zcl-util.js @@ -512,6 +512,22 @@ function isStruct(db, struct_name, packageIds) { .then((st) => (st ? dbEnum.zclType.struct : dbEnum.zclType.unknown)) } +/** + * Local function that checks if a typedef by the name exists + * + * @param {*} db + * @param {*} typedef_name + * @param {*} packageIds + * @returns Promise of content. + */ +function isTypedef(db, typedef_name, packageIds) { + return queryZcl + .selectTypedefByName(db, typedef_name, packageIds) + .then((typedefs) => + typedefs ? dbEnum.zclType.typedef : dbEnum.zclType.unknown + ) +} + /** * Function that checks if a given thing is an avent. * @param {*} db @@ -627,6 +643,16 @@ function dataTypeHelper( } else { return type } + case dbEnum.zclType.typedef: + if ('typedef' in options.hash) { + return defaultMessageForTypeConversion( + `${type}`, + options.hash.typedef, + options.hash.no_warning + ) + } else { + return type + } case dbEnum.zclType.atomic: case dbEnum.zclType.unknown: default: @@ -665,7 +691,7 @@ async function asUnderlyingZclTypeWithPackageId( actualType = numberType.name } - return Promise.all([ + let res = await Promise.all([ new Promise((resolve, reject) => { if ('isArray' in currentInstance && currentInstance.isArray) resolve(dbEnum.zclType.array) @@ -673,44 +699,38 @@ async function asUnderlyingZclTypeWithPackageId( }), isEnum(currentInstance.global.db, actualType, packageIds), isStruct(currentInstance.global.db, actualType, packageIds), - isBitmap(currentInstance.global.db, actualType, packageIds) + isBitmap(currentInstance.global.db, actualType, packageIds), + isTypedef(currentInstance.global.db, actualType, packageIds) ]) - .then( - (res) => - new Promise((resolve, reject) => { - for (let i = 0; i < res.length; i++) { - if (res[i] != 'unknown') { - resolve(res[i]) - return - } - } - resolve(dbEnum.zclType.unknown) - }) - ) - .then((resType) => { - if (dbEnum.zclType.zclCharFormatter in options.hash) { - return dataTypeCharacterFormatter( - currentInstance.global.db, - packageIds, - actualType, - options, - resType - ) - } else { - return dataTypeHelper( - actualType, - options, - packageIds, - currentInstance.global.db, - resType, - currentInstance.global.overridable - ) + + let resType = await new Promise((resolve, reject) => { + for (let i = 0; i < res.length; i++) { + if (res[i] != 'unknown') { + resolve(res[i]) + return } - }) - .catch((err) => { - env.logError(err) - throw err - }) + } + resolve(dbEnum.zclType.unknown) + }) + + if (dbEnum.zclType.zclCharFormatter in options.hash) { + return dataTypeCharacterFormatter( + currentInstance.global.db, + packageIds, + actualType, + options, + resType + ) + } else { + return dataTypeHelper( + actualType, + options, + packageIds, + currentInstance.global.db, + resType, + currentInstance.global.overridable + ) + } } /** @@ -753,6 +773,13 @@ async function determineType(db, type, packageIds) { atomicType: null } + let typedef = await queryZcl.selectTypedefByName(db, type, packageIds) + if (typedef != null) + return { + type: dbEnum.zclType.typedef, + atomicType: (await determineType(db, typedef.type, packageIds)).atomicType + } + let theBitmap = await queryZcl.selectBitmapByName(db, packageIds, type) if (theBitmap != null) { let size = theBitmap.size @@ -873,6 +900,16 @@ async function zcl_data_type_size_and_sign( packageIds ) result = en.size + } else if ( + dataType.discriminatorName.toLowerCase() == dbEnum.zclType.typedef + ) { + let en = await queryZcl.selectTypeDefByNameAndClusterId( + context.global.db, + dataType.name, + clusterId, + packageIds + ) + result = en.size } else if ( dataType.discriminatorName.toLowerCase() == dbEnum.zclType.number ) { @@ -899,6 +936,7 @@ exports.isEnum = isEnum exports.isBitmap = isBitmap exports.isStruct = isStruct exports.isEvent = isEvent +exports.isTypedef = isTypedef exports.asUnderlyingZclTypeWithPackageId = asUnderlyingZclTypeWithPackageId exports.determineType = determineType exports.dataTypeCharacterFormatter = dataTypeCharacterFormatter diff --git a/src-electron/zcl/zcl-loader-silabs.js b/src-electron/zcl/zcl-loader-silabs.js index 518ab91c68..12ecf8a29f 100644 --- a/src-electron/zcl/zcl-loader-silabs.js +++ b/src-electron/zcl/zcl-loader-silabs.js @@ -143,7 +143,8 @@ async function collectDataFromJsonFile(metadataFile, data) { 'ENUM', 'NUMBER', 'STRING', - 'STRUCT' + 'STRUCT', + 'TYPEDEF' ] } @@ -1075,6 +1076,11 @@ function prepareDataType(a, dataType, typeMap) { a.$.name.toLowerCase().includes(dbEnum.zclType.struct) ) { dataTypeRef = typeMap.get(dbEnum.zclType.struct) + } else if ( + !dataType && + a.$.name.toLowerCase().includes(dbEnum.zclType.typedef) + ) { + dataTypeRef = typeMap.get(dbEnum.zclType.typedef) } else if (!dataType) { dataTypeRef = typeMap.get(dbEnum.zclType.number) } @@ -1156,6 +1162,15 @@ async function processDataType( prepareDataType(x, typeMap.get(dbEnum.zclType.string), typeMap) ) ) + } else if (dataType == dbEnum.zclType.typedef) { + env.logDebug(`${filePath}, ${packageId}: ${data.length} Typedef Types.`) + return queryLoader.insertDataType( + db, + packageId, + data.map((x) => + prepareDataType(x, typeMap.get(dbEnum.zclType.typedef), typeMap) + ) + ) } else { env.logError( 'Could not find the discriminator for the data type: ' + dataType @@ -1642,6 +1657,44 @@ async function processStructItems(db, filePath, packageIds, data, context) { return queryLoader.insertStructItems(db, packageIds, structItems) } +/** + * Prepare the typedef for database table insertion. + * + * @param {*} a + * @param {*} dataType + * @returns An Object + */ +function prepareTypedef(a, dataType) { + return { + name: a.$.name, + cluster_code: a.cluster ? a.cluster : null, + discriminator_ref: dataType, + type: + a.$.type == a.$.type.toUpperCase() && a.$.type.length > 1 + ? a.$.type.toLowerCase() + : a.$.type + } +} +/** + * Processes the typedef. + * + * @param {*} db + * @param {*} filePath + * @param {*} packageId + * @param {*} knownPackages + * @param {*} data + * @returns A promise of inserted typedefs. + */ +async function processTypedef(db, filePath, packageId, knownPackages, data) { + env.logDebug(`${filePath}, ${packageId}: ${data.length} Typedef Types.`) + let typeMap = await zclLoader.getDiscriminatorMap(db, knownPackages) + return queryLoader.insertTypedef( + db, + knownPackages, + data.map((x) => prepareTypedef(x, typeMap.get(dbEnum.zclType.typedef))) + ) +} + /** * Prepares a device type object by extracting and transforming its properties. * @@ -1907,6 +1960,18 @@ async function processParsedZclData( ) ) } + if (dbEnum.zclType.typedef in toplevel) { + batch3.push( + processDataType( + db, + filePath, + packageId, + knownPackages, + toplevel.typedef, + dbEnum.zclType.typedef + ) + ) + } await Promise.all(batch3) // Batch4 and Batch5: Loads the inidividual tables per data type from @@ -1951,6 +2016,11 @@ async function processParsedZclData( processBitmap(db, filePath, packageId, knownPackages, toplevel.bitmap) ) } + if (dbEnum.zclType.typedef in toplevel) { + Batch5.push( + processTypedef(db, filePath, packageId, knownPackages, toplevel.typedef) + ) + } // Treating features in a cluster as a bitmap if (featureClusters.length > 0) { featureClusters.forEach((fc) => { @@ -2310,7 +2380,7 @@ function parseConformanceFromXML(operand) { */ function parseConformanceRecursively(operand, depth = 0, parentJoinChar = '') { if (depth > 200) { - throw new Error(`Maximum recursion depth exceeded + throw new Error(`Maximum recursion depth exceeded when parsing conformance: ${JSON.stringify(operand)}`) } const baseLevelTerms = ['feature', 'condition', 'attribute', 'command'] diff --git a/src-shared/db-enum.js b/src-shared/db-enum.js index eb70e43f79..d192a03411 100644 --- a/src-shared/db-enum.js +++ b/src-shared/db-enum.js @@ -98,7 +98,8 @@ exports.zclType = { array: 'array', zclCharFormatter: 'zclCharFormatter', string: 'string', - number: 'number' + number: 'number', + typedef: 'typedef' } exports.sessionKey = { diff --git a/test/gen-meta.test.js b/test/gen-meta.test.js index cfbe462109..ee2c40c942 100644 --- a/test/gen-meta.test.js +++ b/test/gen-meta.test.js @@ -149,6 +149,17 @@ test( } } + const typedefs = await queryZcl.selectAllTypedefs(db, zclContext.packageId) + for (const t of typedefs) { + let clusters = await queryZcl.selectTypedefClusters(db, t.id) + if (t.name == 'TestID') { + expect(clusters.length).toBe(1) + expect(clusters[0].code).toBe(0xabcd) + } else { + expect(clusters.length).toBe(0) + } + } + const ops = await queryAccess.selectAccessOperations( db, zclContext.packageId diff --git a/test/gen-template/matter-api-maturity/codegen_test.zapt b/test/gen-template/matter-api-maturity/codegen_test.zapt index 50c89e943f..5f6fb4bb88 100644 --- a/test/gen-template/matter-api-maturity/codegen_test.zapt +++ b/test/gen-template/matter-api-maturity/codegen_test.zapt @@ -15,6 +15,10 @@ cluster {{asUpperCamelCase name}} = {{code}} bitmap {{asUpperCamelCase name preserveAcronyms=true}} : BITMAP{{multiply size 8}}; {{/zcl_bitmaps}} + {{#zcl_typedefs}} + typedef {{asUpperCamelCase name preserveAcronyms=true}} : {{type}}; + + {{/zcl_typedefs}} {{#zcl_events}} {{priority}} event {{asUpperCamelCase name preserveAcronyms=true}} = {{code}} { {{#zcl_event_fields}} @@ -45,7 +49,7 @@ cluster {{asUpperCamelCase name}} = {{code}} {{! ensure indent ~}} {{#if isOptional~}} optional {{/if~}} {{~#unless isWritableAttribute~}} readonly {{/unless~}} - {{~#if isNullable~}} nullable {{/if~}} + {{~#if isNullable~}} nullable {{/if~}} {{type}} attribute {{asLowerCamelCase name~}} {{~#if isArray~}} [] {{~/if}} = {{code~}} {{~#if apiMaturity}} ({{apiMaturity}}) {{~/if~}}; {{/unless}} diff --git a/test/gen-template/zigbee/zap-type.zapt b/test/gen-template/zigbee/zap-type.zapt index 5478028a39..48d0c2707e 100644 --- a/test/gen-template/zigbee/zap-type.zapt +++ b/test/gen-template/zigbee/zap-type.zapt @@ -37,6 +37,12 @@ typedef enum { {{/zcl_bitmap_items}} {{/zcl_bitmaps}} +// ZCL typedefs + +{{#zcl_typedefs}} +using {{as_type label}} = {{asUnderlyingType type}}; +{{/zcl_typedefs}} + // ZCL Structs {{#zcl_structs}} @@ -68,7 +74,7 @@ typedef struct { sl_zigbee_af_cluster_id_t matterClusterId; sl_zigbee_af_cluster_id_t matterMfgClusterId; sl_matter_af_cluster_id_t zigbeeClusterId; - sl_matter_af_cluster_id_t zigbeeMfgClusterId; + sl_matter_af_cluster_id_t zigbeeMfgClusterId; sl_matter_af_attribute_id_t matterAttributeId; sl_matter_af_attribute_id_t matterMfgAttributeId; sl_zigbee_af_attribute_id_t zigbeeAttributeId; @@ -76,4 +82,4 @@ typedef struct { } sl_zigbee_matter_af_multi_protocol_attribute_metadata_t; {{/if_multi_protocol_attributes_enabled}} -#endif \ No newline at end of file +#endif diff --git a/test/gen-template/zigbee/zcl-test.zapt b/test/gen-template/zigbee/zcl-test.zapt index 7d9590c98d..0c46bd86d4 100644 --- a/test/gen-template/zigbee/zcl-test.zapt +++ b/test/gen-template/zigbee/zcl-test.zapt @@ -8,6 +8,16 @@ Label count: {{count}} This is output only if there are no enums. {{/zcl_enums}} +/******************/ +{{#zcl_typedefs}} +// {{index}}/{{count}}: label=>{{label}} caption=>{{caption}} +{{#last}} +Label count: {{count}} +{{/last}} +{{else}} +This is output only if there are no typedefs. +{{/zcl_typedefs}} + /******************/ {{#zcl_structs}} diff --git a/test/gen-template/zigbee2/zap-type.zapt b/test/gen-template/zigbee2/zap-type.zapt index 4f9d1dc8d3..9556f28a3f 100644 --- a/test/gen-template/zigbee2/zap-type.zapt +++ b/test/gen-template/zigbee2/zap-type.zapt @@ -65,4 +65,10 @@ typedef uint8_t {{as_type parent.label}}; {{/zcl_struct_items}} {{/zcl_structs}} +// ZCL typedefs + +{{#zcl_typedefs}} +using {{as_type label}} = {{asUnderlyingType type}}; +{{/zcl_typedefs}} + #endif diff --git a/test/helpers.test.js b/test/helpers.test.js index 7f0fab1ee9..ce6d23fbed 100644 --- a/test/helpers.test.js +++ b/test/helpers.test.js @@ -230,6 +230,13 @@ test( zclHelper.isStruct(db, 'Protocol', zclContext.packageId).then((result) => { expect(result).toBe(dbEnum.zclType.struct) }) + + zclHelper.isTypedef(db, 'patate', zclContext.packageId).then((result) => { + expect(result).toBe(dbEnum.zclType.unknown) + }) + zclHelper.isTypedef(db, 'ZoneID', zclContext.packageId).then((result) => { + expect(result).toBe(dbEnum.zclType.typedef) + }) }, testUtil.timeout.short() ) diff --git a/test/resource/meta/types.xml b/test/resource/meta/types.xml index d7b5c7cd73..af0b32eeff 100644 --- a/test/resource/meta/types.xml +++ b/test/resource/meta/types.xml @@ -112,14 +112,14 @@ limitations under the License. - + - + @@ -162,4 +162,8 @@ limitations under the License. + + + + diff --git a/test/resource/meta/zcl.json b/test/resource/meta/zcl.json index 5b3995eff5..6d375f8232 100644 --- a/test/resource/meta/zcl.json +++ b/test/resource/meta/zcl.json @@ -31,5 +31,13 @@ "indexFieldName": "IndexForFabricField", "indexType": "int8u" }, - "ZCLDataTypes": ["ARRAY", "BITMAP", "ENUM", "NUMBER", "STRING", "STRUCT"] + "ZCLDataTypes": [ + "ARRAY", + "BITMAP", + "ENUM", + "NUMBER", + "STRING", + "STRUCT", + "TYPEDEF" + ] } diff --git a/test/resource/old-matter/test-cluster.xml b/test/resource/old-matter/test-cluster.xml index ddea69d10e..0a2c7e25b2 100644 --- a/test/resource/old-matter/test-cluster.xml +++ b/test/resource/old-matter/test-cluster.xml @@ -49,6 +49,10 @@ limitations under the License. + + + + @@ -59,6 +63,7 @@ limitations under the License. + @@ -128,7 +133,7 @@ limitations under the License. - + @@ -136,7 +141,7 @@ limitations under the License. - + CHIP Test Cluster diff --git a/test/zcl-loader-consecutive.test.js b/test/zcl-loader-consecutive.test.js index 52eb6cbf17..0d17eea88c 100644 --- a/test/zcl-loader-consecutive.test.js +++ b/test/zcl-loader-consecutive.test.js @@ -25,6 +25,7 @@ const queryStruct = require('../src-electron/db/query-struct.js') const queryDeviceType = require('../src-electron/db/query-device-type') const queryCommand = require('../src-electron/db/query-command') const queryPackage = require('../src-electron/db/query-package') +const queryTypedef = require('../src-electron/db/query-typedef.js') const zclLoader = require('../src-electron/zcl/zcl-loader') const env = require('../src-electron/util/env') const testUtil = require('./test-util') @@ -133,7 +134,7 @@ test( expect(x.length).toEqual(129) x = await queryZcl.selectAllDataTypes(db, zigbeePackageId) - expect(x.length).toEqual(440) + expect(x.length).toEqual(441) x = await queryZcl.selectAllNumbers(db, zigbeePackageId) expect(x.length).toEqual(41) @@ -176,6 +177,9 @@ test( x = await queryZcl.selectAllBitmaps(db, dotdotPackageId) expect(x.length).toEqual(69) + x = await queryTypedef.selectAllTypedefs(db, zigbeePackageId) + expect(x.length).toEqual(1) + x = await queryZcl.selectAllStrings(db, dotdotPackageId) x = x.map((item) => item.name) strings = ['octstr', 'string', 'octstr16', 'string16'] diff --git a/zcl-builtin/shared/schema/zcl.xsd b/zcl-builtin/shared/schema/zcl.xsd index 504532f3e7..c5af94bb1a 100644 --- a/zcl-builtin/shared/schema/zcl.xsd +++ b/zcl-builtin/shared/schema/zcl.xsd @@ -140,6 +140,7 @@ This schema describes the format of the XML files, that describe the ZCL specifi + @@ -365,6 +366,16 @@ This schema describes the format of the XML files, that describe the ZCL specifi + + + + + + + + + + diff --git a/zcl-builtin/silabs/types.xml b/zcl-builtin/silabs/types.xml index a14758793b..686b37b993 100644 --- a/zcl-builtin/silabs/types.xml +++ b/zcl-builtin/silabs/types.xml @@ -1094,4 +1094,5 @@ limitations under the License. + diff --git a/zcl-builtin/silabs/zcl.json b/zcl-builtin/silabs/zcl.json index b5130f039d..83746a0156 100644 --- a/zcl-builtin/silabs/zcl.json +++ b/zcl-builtin/silabs/zcl.json @@ -54,7 +54,15 @@ "zigbeeEnforceCommonCluster": true } }, - "ZCLDataTypes": ["ARRAY", "BITMAP", "ENUM", "NUMBER", "STRING", "STRUCT"], + "ZCLDataTypes": [ + "ARRAY", + "BITMAP", + "ENUM", + "NUMBER", + "STRING", + "STRUCT", + "TYPEDEF" + ], "uiOptions": { "showProfileId": true },