Skip to main content
Flows are a named group of Channels where the data is sent together. Flows offer a mechanism to send more data per request in the context of a gRPC stream. The formal definition of a flow can be found in its protocol buffer documentation. Here is the flow definition, along with ChannelConfig:
message FlowConfig {
  string name = 1 [(google.api.field_behavior) = REQUIRED];
  repeated ChannelConfig channels = 2;
}
message ChannelConfig {
  string name = 1 [(google.api.field_behavior) = REQUIRED];
  string component = 2;
  string unit = 3;
  string description = 4;
  sift.common.type.v1.ChannelDataType data_type = 5 [(google.api.field_behavior) = REQUIRED];
  repeated sift.common.type.v1.ChannelEnumType enum_types = 6;
  repeated sift.common.type.v1.ChannelBitFieldElement bit_field_elements = 7;
}
A FlowConfig defines the flow to create, while a ChannelConfig defines the Channel to create.

Channel ordering

When defining your flow configuration to use as part of your ingestion config, maintain the order of Channels that exist in the channels list.
The exact order must be preserved when providing data values to the IngestWithConfigDataStreamRequest, otherwise errors might occur during streaming.

Example

Consider the following pseudo-code that creates a flow called reading with one double Channel and one string Channel:
def flow_configs() -> List[FlowConfig] {
    return [
        FlowConfig {
            name: "reading"
            channels: [
                ChannelConfig {
                    name: "mainmotor.velocity",
                    unit: "km/hr",
                    description: "vehicle speed",
                    data_type: ChannelDataType::Double,
                },
                ChannelConfig {
                    name: "log",
                    description: "logs",
                    data_type: ChannelDataType::String,
                },
            ],
        },
    ]
}
When creating your IngestWithConfigDataStreamRequest to send for the reading flow, Sift identifies which Channel to attribute each data point to based on the order of the values in the request.
IngestWithConfigDataStreamRequest {
    ingestion_config_id: ingestion_config.ingestion_config_id,
    run_id: run.run_id,
    flow: "reading"
    timestamp: now(),
    channel_values: [
        // velocity Channel
        IngestWithConfigDataChannelValue {
            type: Some(Type::Double(10.0)),
        },
        // log Channel
        IngestWithConfigDataChannelValue {
            type: Some(Type::String("example log")),
        },
    ],
}
Failure to respect the ordering might result either in an error or data being attributed to the wrong Channel.

Empty values

For the same example above, if there is data for the velocity Channel but none for the log Channel, we can still send data for the reading flow by sending a google.protobuf.Empty value.