Everything within the C3 AI Suite is managed through or exists as a C3 Type. Broadly speaking, a Type is a Java class-like concept which combines 'fields' and 'methods' with a concept of inheritance. Once you understand how types are defined, you will be able to write you own Types to extend the C3 AI Suite with new functionality perfect for your use case.

All C3 Types must be defined within a .c3typ file stored within the 'src' directory of a C3 Package. (We'll get to C3 Packages a little later). All .c3typ files must contain the definition of a single C3 Type.

First, we'll introduce the C3 Package to download for this example. Then we will discuss the syntax, special keywords, fields, Methods, and Inheritance structure of C3 Types. Finally, we'll end with some examples.

lightbulbAD C3 Package

For this Guide, we use the lightbulbAD C3 package. If you want to follow along with source code, please download the source code for this package following the instructions available here: C3 lightbulbAD Package

Syntax

To start this discussion of syntax, Let's look at the definition of the 'SmartBulb' Type in the lightbulbAD C3 Package:

/*
 * Copyright 2009-2019 C3 (www.c3.ai). All Rights Reserved.
 * This material, including without limitation any software, is the confidential trade secret and proprietary
 * information of C3 and its licensors. Reproduction, use and/or distribution of this material in any form is
 * strictly prohibited except as set forth in a written license agreement with C3 and/or its authorized distributors.
 * This material may be covered by one or more patents or pending patent applications.
 */

/**
 * A single light bulb capable of measuring various properties, including power consumption, light output, etc.
 */
entity type SmartBulb extends LightBulb mixes MetricEvaluatable, NLEvaluatable type key "SMRT_BLB" {

  /**
   * This bulb's historical measurements.
   */
  bulbMeasurements: [SmartBulbMeasurementSeries](smartBulb)

  /**
   * This bulb's historical predictions.
   */
  @db(order='descending(timestamp)')
  bulbPredictions: [SmartBulbPrediction](smartBulb)

  /**
   * This bulb's latest prediction.
   */
  currentPrediction: SmartBulbPrediction stored calc "bulbPredictions[0]"

  /**
   * This bulb's historical events.
   */
  bulbEvents: [SmartBulbEvent](smartBulb)

  /**
   * The latitude of this bulb.
   */
  latitude: double

  /**
   * The longitude of this bulb.
   */
  longitude: double

  /**
   * The unit of measurement used for this bulb's light output measurements.
   */
  lumensUOM: Unit

  /**
   * The unit of measurement used for this bulb's power consumption measurements.
   */
  powerUOM: Unit

  /**
   * The unit of measurement used for this bulb's temperature measurements.
   */
  temperatureUOM: Unit

  /**
   * The unit of measurement used for this bulb's voltage measurements.
   */
  voltageUOM: Unit

  /**
   * A SmartBulb is associated to a {@link Fixture} through a SmartBulbToFixtureRelation.
   */
  @db(order='descending(start), descending(end)')
  fixtureHistory: [SmartBulbToFixtureRelation](from)

  /**
   * The current Fixture to which this bulb is attached.
   */
  currentFixture: Fixture stored calc 'fixtureHistory[0].(end == null).to'

  /**
   * Method to determine the expected lumens of a light bulb
   */
  expectedLumens: function(wattage: !decimal, bulbType: !string): double js server

  /**
   * Returns the life span of this smartBulb
   */
  lifeSpanInYears: function(bulbId: string): double js server

  /**
   * Returns the average life span of all smartBulbs.
   */
  averageLifeSpan: function(): double js server

  /**
   * Returns the id of the smart bulb with the shortest recorded life span to date.
   */
  shortestLifeSpanBulb: function(): string js server

  /**
   * Returns the id of the smart bulb with the longest recorded life span to date.
   */
  longestLifeSpanBulb: function(): string js server

}

We can see the general structure of the .c3typ file at a glance

From a high level, the signature of a C3 Type definition looks like this: (originally from official C3.ai type documentation here: https://developer.c3.ai/docs/7.12.17/topic/mda-types

[remix, extendable] [entity] type TypeName [extends, mixes AnotherType] {
	/* comments */
	[field declaration]
	[method declaration]
}

Everything within square brackets '[]' is optional.

Keywords

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

Fields

Each field of a C3 Type is defined by first giving the field name followed by a colon ':' followed by a Type.

Types can be

Methods

Each method of a C3 Type is defined by first giving the 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 Type, along with a language and environment sp

Function Signatures

Return Types

Environments

Inheritance

Polymorphism

Examples