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:
This module provides queries for enums.
This module provides queries for typedefs.
+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.