Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

In this section we will describe the package to download for this tutorial then we will discuss the syntax, special keywords, fields, methods, and inheritance structure of C3 Types. Finally, we will review some examples.

lightbulbAD Package

In this tutorial we will use the lightbulbAD package. To download the source code for this package, please follow the instructions available here: Guide to download C3 lightbulbAD Package.

Syntax

 To help familiarize yourself with the syntax for a C3 Type, let's look at how the 'SmartBulb' Type is defined in the lightbulbAD package:

...

Note: Everything within square brackets '[]' is optional.

Additional Resources

Keywords

A C3 Type definition is introduced with a series of keywords. These keywords tell the C3 AI Suite how to construct this Type, store it internally, and whether it inherits fields and methods from other already defined C3 Types.

  • type: All .c3typ files have the keyword 'type'. This keyword tells the C3 AI Suite that this file defines a C3 Type. 
  • entity: The keyword 'entity' keyword indicates the C3 Type is a 'Persistable' (i.e., needs to be stored in a database in the C3 AI Suite). Since a large majority of C3 Types are Persistable, 'entity' is an important keyword to include in .c3typ files. 
  • mixes: Adding the keyword `mixes <AnotherType>`, a C3 Type inherits the properties (e.g., fields, methods) of `<AnotherType>'. A C3 Type can mix-in multiple Types. 
  • remixes: Adding the keyword`remix <AType>` allows a developer to modify an existing C3 Type (e.g., add new fields or methods, update existing fields or methods). Re-mixing is useful when you don't have access to the original .c3typ file for a particular C3 Type, but wish to edit that C3 Type. 
  • extends: Developers often add the keyword `extends <AnotherType>` to define a subclass of a particular C3 Type (e.g., SmartBulb extends Lightbulb). The extension Type (i.e., Smartbulb) inherits all the fields and methods of the original Type (i.e., Lightbulb). Additionally, data associated with the extension and original C3 Types are stored in the same database table. Therefore, you must specify a `type key`on the extension Type so the C3 AI Suite can distinguish data associated with the extension and original C3 Types. Please note a C3 Type can only extend ONE other Type. 
  • extendable: All extended Types (i.e., Lightbulb) MUST be marked with the keyword "extendable".  Under the covers, the keyword "extendable" tells the C3 AI Suite to add a field (called 'key') to the database table storing the extended (or base) C3 Type. This 'key' field is used to distinguish data associated with different varieties of the extended C3 Type.
  • type key: All extension Types (i.e., Smartbulb) MUST BE marked with the keyword 'type key <VALUE>' (e.g., "type key SMRT_BLB").
  • schema name: A set of keywords indicating the name of the database table used to store data for a Persistable C3 Type. Developers specify a schema name to customize database table names.

Additional Resources

C3 Types 

There are many categories of C3 Types. 

...

  • Primitive Types 
  • Persistable Types 
  • Generic (Parametric) Types 
  • Abstract Types 

Primitive Types

Like many programming languages, the C3 AI Suite has primitives. Primitives define the units (or data types) of fields on a C3 Type (e.g., "int", "double", "float"). The C3 AI Suite includes a number of primitives, listed below for reference. Adding new primitives will require support from the C3 AI engineering team, however, most DTI researchers should be able to progress their research projects with the C3 AI Suite's existing primitives. 

  • binary
  • boolean
  • byte
  • char
  • datetime
  • decimal
  • double
  • float
  • int
  • json
  • long int
  • string

Additional Resources

Persistable Types

The most common C3 Type you will define is a 'Persistable' Type. Persistable Types store data in a C3 AI Suite database. By default, all Persistable Types are stored in Postgres though they can also be stored in file systems (e.g., Azure Blob) or key-value stores (e.g., Cassandra), by adding an annotation to your .c3typ file (discussed below). 

...

  1. entity: The keyword 'entity' keyword tells the C3 AI Suite this is a 'Persistable' Type.
  2. schema name: The schema names is the name of the database table where the C3 Type's data are stored. When defining a new Persistable Type, you need to add the keywords 'schema name' followed by your chosen table name, in your .c3typ file. (e.g., in the C3 Type LightBulb, we have 'schema name "LGHT_BLB"').
    Note: Extended C3 Types DO NOT NEED a scheme name and Schema names CANNOT exceed 30 characters. 

Additional Resources

Generic (Parametric) Types

Like a Java or C++ Class, C3 Types can be parameterized (or genericized). In fact, the C3 AI Suite uses the exact same syntax as Java and C++ to define a Type's parameters (i.e., angle brackets '<>' ). When defining a Generic (Parametric) Type, your Type name will be followed by angle brackets and a comma-separated list of parameters (usually other C3 Types).  For example:

...

If your C3 Types will be heavily re-used by other developers you should consider using Parametric (Generic) Types.

Additional Resources

Fields

As discussed above, a C3 Type mainly consists of two components: fields and methods.

...

  • Primitive Fields 
  • Reference Fields 
  • Collection Fields 
  • Calculated Fields 

Primitive Fields

Like many other programming languages the C3 AI Suite has primitive fields (e.g., int, boolean, byte, double, datetime, string, longstring). For example:

...

Primitive fields are stored in a particular C3 Type's database table.

Reference Fields

Reference fields point (or refer) to other C3 Types. Reference fields link (or join) two C3 Types together. Under the covers, the Reference field stores a pointer (i.e., foreign key reference or ID) to record of another C3 Type. To define a Reference field, use the following syntax: field name, followed by colon ':', followed by Type Name (e.g., "building: Building"). For example:

refField: AnotherType

Collection Fields

Collection fields contain a list of values or records. There are four categories of collections fields:

...

Please see the 'Foreign Key Collection and Schema Names" section in the following C3 AI Develop Documentation for more details: https://developer.c3.ai/docs/7.12.25/topic/mda-fields

Calculated Fields

Calculated fields are derived from other fields on a C3 Type. Calculated fields typically included either JavaScript code or C3 AI ExpressionEngineFunctions and are specified as follows:

...

  1. Simple calculated fields: The values of these fields are calculated at runtime and not stored. To define a simple calculated field use the following syntax: keyword `calc`, followed by an expression formula.
  2. Stored calculated fields: The values of these fields are stored in the C3 Type's database table. To define a stored calculated field use the following syntax: keywords `stored calc`, followed by an expression formula (e.g, in the SmartBulb example above, 'stored calc fixtureHistory[0].(end == null).to').

Additional Resources

Methods

At a high-level, methods are pieces of code that take in arguments or parameters and return new values. To define a method on a C3 Type, use the following syntax, method name followed by a colon ':' followed by a function signature, (e.g., function() or function(wattage: !decimal, bulbType: !string)), followed by a colon ':', followed by a return parameter, along with an implementation language and execution location

Function Signatures

Here's the syntax for a method's function signature:

...

The function itself is NOT implemented in the .c3typ file, rather in a separate .js (JavaScript), .py (Python) or .r (R) files stored in the same directory as the .c3typ file. 

Return Parameter

Following the function signature is a return parameter. Return parameters must be a C3 Type. 

Implementation Language/Execution Location

Finally, let's discuss the implementation language and execution location.

...

Additionally, for Python, we need to specify a valid 'ActionRuntime' for python function to be executed in. ActionRuntimes are defined in C3 AI Suite and new ActionRuntimes can be defined in a package and are essentially conda environments. For example, 'server' will use the 'py-server' ActionRuntime.

Function Definitions

As mentioned above, the function itself is defined in a different file from the .c3typ file. The name of this file should be the same as the .c3typ file where the method is defined (e.g., SmartBulb.js and SmartBulb.c3typ), but have a different extension, per the function's implementation language (e.g., 'py' for Python, 'js' for JavaScript, 'r' for R). The function names in this file must exactly match the method names in the .c3typ file. For example, we define a C3 Type as such: 

...

Code Block
function funcB(num, name='default') {
    ...
}

Additional Resources

Inheritance

Like a Java or C++ Class, a C3 Type can inherit fields and methods from other C3 Types. The keywords`mixes` and `extends` signal inheritance. These keywords follow the new C3 Type's name in your .c3typ file.

...

In this example, ParentType is an extendable Persistable type stored in the table 'PRT_TYP'. ChildType extends ParentType and is also stored in the table 'PRT_TYP'.  Records associated with ChildType have 'type key' == 'CHLD' to distinguish them from ParentType's data.

Additional Resources

Annotations

With annotations you can further configure a C3 Type. Annotations can appear before Type definitions, field declarations, and method declarations. As example, annotations can be used to specify the database technology used to store a C3 Type (e.g., Cassandra, Azure Blob), mark the ActionRuntime in which to run a particular method, deprecate a field or method, specify how time-series data should be treated, and specify how to trigger analytics or DFEs (DataFlow Events).

...

With the `@ts(treatment = 'avg') annotation, the value of the lumens field for a given SmartBulb is the average of all that Smartbulb's lumens data. 

Additional Resources

Final Types

Types, methods, and fields can be made final using the 'final' keyword. The fields and methods of a Final Type cannot be modified or overridden (via 'mixes' or 'exends').

Code Block
type FinalType {
    final method: function(): string
}

Additional Resources

Abstract Types

The C3 AI Suite also supports abstract types. To define an Abstract Type, add the keyword 'abstract' before the Type definition. Abstract Types cannot be instantiated and must mix-in to another concrete Type. This provides a great way to standardize interfaces. Here's an example:

Code Block
abstract type Interace {
	field1: int
    method1: function(double): int
}

Additional Resources

Examples

To see more examples of C3 Types, check out the .c3typ files in the lightbulbAD package: Guide to download C3 lightbulbAD Package