Skip to content

Block Data Types

This page describes the interface specs for all block types.

The block type ID may vary slightly from the type name displayed in the UI.

Block data is serialized as JSON, and will not include classes, functions, or other non-serializable types.

The TypeScript interface syntax is used to define types, with the exception of enums, for which the typescript-string-enums library is used.

Block (base type)

Block is the base type for all blocks. The shared fields are defined here, and each block type extends this interface with more specific typings for type and data.

ts
export interface Block {
  id: string;
  nid?: number;
  serviceId: string;
  type: BlockType;
  data: { [k: string]: any };
  meta?: { [k: string]: any };
}

Block interfaces

Blocks may implement one or more interface types. Links within blocks can declare an interface type instead of a block type. All blocks that implement said interface are valid targets for the link.

Some of these interfaces dictate the presence of fields in block data, but not all.

ts
export interface IoChannel {
  id: number;
  capabilities: Readonly<ChannelCapabilities>;
  claimedBy: Readonly<Link>;
}

export interface IoArrayInterfaceBlock extends Block {
  data: {
    channels: IoChannel[];
  };
}

export interface IoDriverInterfaceBlock extends Block {
  data: {
    hwDevice: Link;
    channel: number;
  };
}
ts
export interface EnablerInterfaceBlock extends Block {
  data: {
    enabled: boolean;
  };
}
ts
export interface ClaimableInterfaceBlock extends Block {
  data: {
    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
ts
export const COMPATIBLE_TYPES: Record<BlockIntfType, BlockType[]> = {
  Any: Enum.values(BlockType),
  ProcessValueInterface: [
    BlockType.ActuatorAnalogMock,
    BlockType.ActuatorOffset,
    BlockType.ActuatorPwm,
    BlockType.FastPwm,
    BlockType.SetpointSensorPair,
  ],
  TempSensorInterface: [
    BlockType.TempSensorCombi,
    BlockType.TempSensorExternal,
    BlockType.TempSensorMock,
    BlockType.TempSensorOneWire,
  ],
  SetpointSensorPairInterface: [BlockType.SetpointSensorPair],
  ActuatorAnalogInterface: [
    BlockType.ActuatorAnalogMock,
    BlockType.ActuatorOffset,
    BlockType.ActuatorPwm,
    BlockType.FastPwm,
  ],
  ActuatorDigitalInterface: [BlockType.DigitalActuator, BlockType.MotorValve],
  DigitalInterface: [
    BlockType.DigitalActuator,
    BlockType.MotorValve,
    BlockType.DigitalInput,
  ],
  BalancerInterface: [BlockType.Balancer],
  MutexInterface: [BlockType.Mutex],
  OneWireBusInterface: [BlockType.OneWireGpioModule],
  OneWireDeviceInterface: [
    BlockType.TempSensorOneWire,
    BlockType.DS2408,
    BlockType.DS2413,
  ],
  IoModuleInterface: [],
  IoArrayInterface: [
    BlockType.DS2408,
    BlockType.DS2413,
    BlockType.Spark2Pins,
    BlockType.Spark3Pins,
    BlockType.OneWireGpioModule,
    BlockType.MockPins,
  ],
  IoDriverInterface: [
    BlockType.DigitalActuator,
    BlockType.MotorValve,
    BlockType.FastPwm,
    BlockType.DigitalInput,
  ],
  DS2408Interface: [BlockType.DS2408],
  EnablerInterface: [
    BlockType.ActuatorAnalogMock,
    BlockType.ActuatorOffset,
    BlockType.ActuatorLogic,
    BlockType.Pid,
    BlockType.Sequence,
    BlockType.ActuatorPwm,
    BlockType.FastPwm,
    BlockType.SetpointSensorPair,
    BlockType.SetpointProfile,
    BlockType.TempSensorExternal,
  ],
  ClaimableInterface: [
    BlockType.ActuatorAnalogMock,
    BlockType.ActuatorOffset,
    BlockType.ActuatorPwm,
    BlockType.DigitalActuator,
    BlockType.FastPwm,
    BlockType.MotorValve,
    BlockType.SetpointSensorPair,
  ],
};

BloxField (typed objects)

Some block fields require metadata to be interpreted. They are serialized as typed objects so that clients can automatically recognize and parse this metadata.

BloxField objects are identified by having the __bloxtype field. The value for this field identifies the subtype.

Brewblox currently supports two subtypes: Quantity, and Link.

Quantity objects have a value and unit. When reading data, the value is converted to the user's preferred unit. When writing data, the value is converted to the controller's preferred unit.

Link objects are fields in block data that refer to other blocks. Each link field has a fixed type. This can be a block type (Pid), but also a block interface type (TempSensorInterface).

ts
export interface BloxField {
  __bloxtype: string;
}

export interface Quantity extends BloxField {
  __bloxtype: 'Quantity';
  value: number | null;
  unit: string;
  readonly?: boolean;
}

export interface Link extends BloxField {
  __bloxtype: 'Link';
  id: string | null;
  type: BlockOrIntfType | null;
}

DateString (datetime handling)

Datetime fields are serialized to JSON using the ISO 8601 format.

JSON-wise, this is just a string. For block data types, we added the DateString alias to make it obvious that a given field will always contain an ISO 8601 formatted date.

When writing block data, dates with non-UTC timezones can be used, but the controller will always return dates with UTC timezones.

ts
export type DateString = string;

IoChannel

An IoChannel is the software representation of a group of IO pins. Channels are provided by blocks that implement IoArray, and are used by digital actuators.

DS2408, DS2413, Spark2Pins, Spark3Pins, MockPins, OneWireGpioModule all implement IoArray.

By default, channels are constant and cannot be modified. There are two exceptions:

  • OneWireGpioModule channels are completely user-defined
  • DS2408 will report different channels based on the value of its connectMode field (valve or actuator).

DigitalActuator, MotorValve, and FastPwm blocks use channels as output. They all implement the IoDriverInterface interface, and have hwDevice and channel fields.

ts
export interface IoChannel {
  id: number;
  capabilities: Readonly<ChannelCapabilities>;
  claimedBy: Readonly<Link>;
}

export interface IoArrayInterfaceBlock extends Block {
  data: {
    channels: IoChannel[];
  };
}

export interface IoDriverInterfaceBlock extends Block {
  data: {
    hwDevice: Link;
    channel: number;
  };
}

IoChannel capabilities

Not every channel supports all possible uses. OneWire expansion boards do not support Fast PWM. Input, power, or GND channels in OneWireGpioModule do not support output at all. This is declared in the channel capabilities field.

The ChannelCapabilities enum is a numeric representation of bitwise flags. For example, a channel may support digital output and bidirectional output.
The value of capabilities would be CHAN_SUPPORTS_DIGITAL_OUTPUT | CHAN_SUPPORTS_BIDIRECTIONAL, making the numeric value (1 << 0 | 1 << 5) == (1 | 32) == 33

ts
export enum ChannelCapabilities {
  CHAN_SUPPORTS_NONE = 0,
  CHAN_SUPPORTS_DIGITAL_OUTPUT = 1 << 0,
  CHAN_SUPPORTS_PWM_80HZ = 1 << 1,
  CHAN_SUPPORTS_PWM_100HZ = 1 << 2,
  CHAN_SUPPORTS_PWM_200HZ = 1 << 3,
  CHAN_SUPPORTS_PWM_2000HZ = 1 << 4,
  CHAN_SUPPORTS_BIDIRECTIONAL = 1 << 5,
  CHAN_SUPPORTS_DIGITAL_INPUT = 1 << 6,
}

Stored, desired, and achieved settings

Analog actuators, Setpoints, and Digital actuators have multiple fields to describe their setting or state.

For the analog actuators and setpoints, four fields are used:

  • storedSetting
  • desiredSetting
  • setting
  • value

storedSetting is the setting as written by the user, either directly (using the UI), or indirecty (using the Sequence block).

desiredSetting is either storedSetting (if the block is not claimed), or the output setting of the claiming block (if the block is claimed). For example, a SetpointProfile block will set the desiredSetting field of its target SetpointSensorPair block.

setting is the desiredSetting after the constraints have had their say. If desiredSetting is 100, and a Max=50 constraint is set, setting will be 50.

value is the measured value as achieved by the system. For a setpoint, value is measured by a sensor. For a PWM, value is the percentage of time that the target digital actuator spent active.

For digital actuators, only three fields are used:

  • storedState
  • desiredState
  • state

The overall use of the fields is the same, but the actual setting and the measured value are combined into state. The pins triggere by a digital actuator don't have a meaningful measured value: either they were set to Active/Inactive correctly, or they weren't.

Constraints

Various types of constraints can be set on blocks to modify their output.

Constraints are split in two groups: digital constraints, and analog constraints.

Digital actuators (DigitalActuator, MotorValve) have digital constraints, and analog actuators (AnalogActuatorMock, ActuatorOffset, ActuatorPwm) have analog constraints.

As mentioned above, actuators have a desiredSetting and a setting field. desiredSetting is the before, and setting is after constraints are evaluated.

ts
export interface DigitalConstraintBase {
  enabled: boolean;
  limiting: Readonly<boolean>;
  remaining: Readonly<Quantity>;
}

export interface DurationConstraint extends DigitalConstraintBase {
  duration: Quantity;
}

export interface MutexedConstraint extends DigitalConstraintBase {
  mutexId: Link;
  extraHoldTime: Quantity;
  hasLock: Readonly<boolean>;
}

export interface DigitalConstraints {
  minOff?: DurationConstraint;
  minOn?: DurationConstraint;
  delayedOff?: DurationConstraint;
  delayedOn?: DurationConstraint;
  mutexed?: MutexedConstraint;
}
ts
export interface AnalogConstraintBase {
  enabled: boolean;
  limiting: Readonly<boolean>;
}

export interface ValueConstraint extends AnalogConstraintBase {
  value: number;
}

export interface BalancedConstraint extends AnalogConstraintBase {
  balancerId: Link;
  granted: Readonly<number>;
}

export interface AnalogConstraints {
  min?: ValueConstraint;
  max?: ValueConstraint;
  balanced?: BalancedConstraint;
}

ActuatorAnalogMock

This block can be used as a dummy replacement for an ActuatorPwm, or as input block for an ActuatorLogic.

ts
export interface ActuatorAnalogMockBlock extends Block {
  type: 'ActuatorAnalogMock';
  data: {
    enabled: boolean;

    storedSetting: number;
    desiredSetting: Readonly<number>;
    setting: Readonly<number>;
    value: Readonly<number>;

    minSetting: number;
    maxSetting: number;
    minValue: number;
    maxValue: number;
    constraints?: AnalogConstraints;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}

ActuatorLogic

Evaluates a boolean expression to get a true/false result. Drives a DigitalActuator - state is set to match the evaluation result.

The expression may contain references to digital or analog comparisons. For a detailed explanation, see the Blocks guide.

All expressions are assigned a letter based on their type and array index.

DigitalCompare objects are lettered a through z, and AnalogCompare objects are lettered A through Z.

If a compare is removed from the array, the letter designation of all subsequent compares will shift.

ts
export interface DigitalCompare {
  id: Link;
  op: DigitalCompareOp;
  rhs: DigitalState;
  result: Readonly<LogicResult>;
}

export interface AnalogCompare {
  id: Link;
  op: AnalogCompareOp;
  rhs: number;
  result: Readonly<LogicResult>;
}

export interface ActuatorLogicBlock extends Block {
  type: 'ActuatorLogic';
  data: {
    enabled: boolean;
    digital: DigitalCompare[]; // a-z
    analog: AnalogCompare[]; // A-Z
    expression: string; // a-zA-Z&|^!()

    result: Readonly<LogicResult>;
    errorPos: Readonly<number>;

    targetId: Link;
  };
}

Referenced enum values:

ts
export const DigitalCompareOp = Enum(
  'OP_VALUE_IS',
  'OP_VALUE_IS_NOT',
  'OP_DESIRED_IS',
  'OP_DESIRED_IS_NOT',
);

export const AnalogCompareOp = Enum(
  'OP_VALUE_LE',
  'OP_VALUE_GE',
  'OP_SETTING_LE',
  'OP_SETTING_GE',
);

export const LogicResult = Enum(
  'RESULT_FALSE',
  'RESULT_TRUE',
  'RESULT_EMPTY',
  'RESULT_EMPTY_SUBSTRING',
  'RESULT_BLOCK_NOT_FOUND',
  'RESULT_INVALID_DIGITAL_OP',
  'RESULT_INVALID_ANALOG_OP',
  'RESULT_UNDEFINED_DIGITAL_COMPARE',
  'RESULT_UNDEFINED_ANALOG_COMPARE',
  'RESULT_UNEXPECTED_OPEN_BRACKET',
  'RESULT_UNEXPECTED_CLOSE_BRACKET',
  'RESULT_UNEXPECTED_CHARACTER',
  'RESULT_UNEXPECTED_COMPARISON',
  'RESULT_UNEXPECTED_OPERATOR',
  'RESULT_MISSING_CLOSE_BRACKET',
);

ActuatorOffset (Setpoint Driver)

The ActuatorOffset sets a target block setting to that of a reference block plus offset. Both target and reference blocks are Setpoints.

Offset is either set manually, or determined by a PID.

All settings are delta temperatures. The desired setting of the target block is the reference setting/value + the value of the setting field.

ts
export interface ActuatorOffsetBlock extends Block {
  type: 'ActuatorOffset';
  data: {
    enabled: boolean;
    targetId: Link;
    referenceId: Link;

    storedSetting: Quantity;
    desiredSetting: Readonly<Quantity>;
    setting: Readonly<Quantity>;
    value: Readonly<Quantity>;

    referenceSettingOrValue: ReferenceKind;
    constraints?: AnalogConstraints;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}

Referenced enum values:

ts
export const ReferenceKind = Enum('REF_SETTING', 'REF_VALUE');

ActuatorPwm

The ActuatorPwm converts an analog 0-100 setting to timed ON/OFF instructions. The percentage of time spent ON will match the analog setting.

It drives a digital actuator, and has analog constraints.

ts
export interface ActuatorPwmBlock extends Block {
  type: 'ActuatorPwm';
  data: {
    enabled: boolean;
    actuatorId: Link;

    storedSetting: number;
    desiredSetting: Readonly<number>;
    setting: Readonly<number>;
    value: Readonly<number>;

    period: Quantity;
    constraints?: AnalogConstraints;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}

Balancer

The Balancer fairly grants output to multiple analog actuators, based on their desired setting.

It is linked to an actuator using the Balanced analog constraint.

ts
export interface BalancedActuator {
  id: Readonly<Link>;
  requested: Readonly<number>;
  granted: Readonly<number>;
}

export interface BalancerBlock extends Block {
  type: 'Balancer';
  data: {
    clients: Readonly<BalancedActuator[]>;
  };
}

DeprecatedObject

DeprecatedObject blocks are stub object: the block itself exists, but the type is no longer supported.

ts
export interface DeprecatedObjectBlock extends Block {
  type: 'DeprecatedObject';
  data: {
    actualId: Readonly<number>;
  };
}

DigitalActuator

Turns an IoChannel ON or OFF.

The actuator itself is typically driven by a PWM, and supports digital constraints.

ts
export interface DigitalActuatorBlock extends Block {
  type: 'DigitalActuator';
  data: {
    hwDevice: Link;
    channel: number;

    storedState: Readonly<DigitalState>;
    desiredState: Readonly<DigitalState | null>;
    state: Readonly<DigitalState | null>;

    invert: boolean;
    constraints?: DigitalConstraints;

    transitionDurationPreset: TransitionDurationPreset;
    transitionDurationSetting: Quantity;
    transitionDurationValue: Readonly<Quantity>;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}

Referenced enum values:

ts
export const DigitalState = Enum(
  'STATE_INACTIVE',
  'STATE_ACTIVE',
  'STATE_UNKNOWN',
  'STATE_REVERSE',
);

DisplaySettings

System object

Controls the Spark LCD screen.

widgets is an array of at most 6 slots. Slots can be set in any order. The pos field determines the on-screen position.

ts
export interface DisplaySlot {
  pos: number; // 1-indexed
  color: string;
  name: string;

  // Value will be one of these
  tempSensor?: Link;
  setpointSensorPair?: Link;
  actuatorAnalog?: Link;
  pid?: Link;
}

export interface DisplaySettingsBlock extends Block {
  type: 'DisplaySettings';
  data: {
    name: string;
    widgets: DisplaySlot[];
  };
}

DS2408

Discovered object

DS2408 provides IoChannel objects for valves or actuators.

Valves and actuators should not be mixed, as they make different use of the available pins. Based on the value of the connectMode field, different IO channels are available.

In actuator mode, channels 1-8 can be used. In valve mode, (start) channels 1 and 5 are available.

ts
export interface DS2408Block extends Block {
  type: 'DS2408';
  data: {
    address: string;
    channels: Readonly<IoChannel[]>;
    connectMode: DS2408ConnectMode;
    connected: Readonly<boolean>;
    oneWireBusId: Readonly<number>;
  };
}

Referenced enum values:

ts
export const DS2408ConnectMode = Enum('CONNECT_VALVE', 'CONNECT_ACTUATOR');

Channel mapping:

ts
export const CHANNEL_NAMES_DS2408 = {
  [DS2408ConnectMode.CONNECT_ACTUATOR]: {
    1: 'A',
    2: 'B',
    3: 'C',
    4: 'D',
    5: 'E',
    6: 'F',
    7: 'G',
    8: 'H',
  },
  [DS2408ConnectMode.CONNECT_VALVE]: {
    1: 'B',
    5: 'A',
  },
} as const;

DS2413

Discovered object

DS2408 provides IoChannel objects for digital actuators.

ts
export interface DS2413Block extends Block {
  type: 'DS2413';
  data: {
    address: string;
    channels: Readonly<IoChannel[]>;
    connected: Readonly<boolean>;
    oneWireBusId: Readonly<number>;
  };
}

Channel mapping:

ts
export const CHANNEL_NAMES_DS2413 = {
  1: 'A',
  2: 'B',
} as const;

FastPwm

The implementation for PWM with sub-second periods. FastPwm directly targets an IoChannel, and not a DigitalActuator.

ts
export interface FastPwmBlock extends Block {
  type: 'FastPwm';
  data: {
    enabled: boolean;

    hwDevice: Link;
    channel: number;

    storedSetting: number;
    desiredSetting: Readonly<number>;
    setting: Readonly<number>;
    value: Readonly<number>;

    invert: boolean;
    frequency: PwmFrequency;
    constraints?: AnalogConstraints;

    transitionDurationPreset: TransitionDurationPreset;
    transitionDurationSetting: Quantity;
    transitionDurationValue: Readonly<Quantity>;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}

InactiveObject

Deprecated

ts
export interface InactiveObjectBlock extends Block {
  type: 'InactiveObject';
  data: {
    actualType: BlockType;
  };
}

MockPins

MockPins provides dummy IoChannel objects for digital actuators.

This is useful for simulator services, but also for use in ActuatorLogic configurations where a digital actuator is only used as input, and is not expected to control hardware.

ts
export interface MockPinsBlock extends Block {
  type: 'MockPins';
  data: {
    channels: Readonly<IoChannel[]>;
  };
}

Channel mapping:

js
{
  1: 'A',
  2: 'B',
  3: 'C',
  4: 'D',
  5: 'E',
  6: 'F',
  7: 'G',
  8: 'H',
}

MotorValve

MotorValve is a special kind of digital actuator.

It must be connected to a DS2408, and technically requires 4 IO channels to function.

The start channel is configured, and it will automatically claim the next three channels. To make this explicit, DS2408 only reports valid start channels when set to valve mode.

The OneWireGpioModule block can also drive motors, but for these, the DigitalActuator block can be used to control them.

ts
export interface MotorValveBlock extends Block {
  type: 'MotorValve';
  data: {
    hwDevice: Link;
    channel: number;

    storedState: DigitalState;
    desiredState: Readonly<DigitalState | null>;
    state: Readonly<DigitalState | null>;
    valveState: Readonly<ValveState | null>;

    constraints?: DigitalConstraints;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}

Referenced enum values:

ts
export const DigitalState = Enum(
  'STATE_INACTIVE',
  'STATE_ACTIVE',
  'STATE_UNKNOWN',
  'STATE_REVERSE',
);
ts
export const ValveState = Enum(
  'VALVE_UNKNOWN',
  'VALVE_OPEN',
  'VALVE_CLOSED',
  'VALVE_OPENING',
  'VALVE_CLOSING',
  'VALVE_HALF_OPEN_IDLE',
  'VALVE_INIT_IDLE',
);

Mutex

Mutex ensures that multiple digital actuators will never be active simultaneously.

It is configured by setting a Mutexed constraint on two or more digital actuators.

If extraHoldTime is set in a mutexed constraint, it will override the differentActuatorWait value.

ts
export interface MutexBlock extends Block {
  type: 'Mutex';
  data: {
    waitRemaining: Readonly<Quantity>;
  };
}

OneWireBus

System object

ts
export interface OneWireBusCommand {
  opcode: number;
  data: number;
}

export interface OneWireBusBlock extends Block {
  type: 'OneWireBus';
  data: {
    command: OneWireBusCommand;
    address: Readonly<string[]>;
  };
}

OneWireGpioModule

Discovered object

OneWireGpioModule is the software representation of a Spark 4 GPIO module. There will be one block per attached module, up to a maximum of 4.

In contrast with other IoArray blocks, all channels are user-defined.

GpioModuleChannel objects define a pin mask to claim 0-8 of the available pins. The number of claimed pins should be either 0, or match the value of GpioModuleChannel.width. Only continuous blocks of pins can be claimed for a single channel, and channels cannot overlap.

If no pins are claimed, the channel is still a valid target for a digital actuator.

The GpioModuleStatus and GpioPins enums are 8-bit masks.

ts
export interface GpioModuleChannel extends IoChannel {
  id: number;
  name: string;
  deviceType: GpioDeviceType;
  pinsMask: GpioPins;
  width: number;
}

export interface OneWireGpioModuleBlock extends Block {
  type: 'OneWireGpioModule';
  data: {
    channels: GpioModuleChannel[];
    modulePosition: number;
    moduleStatus: GpioModuleStatus;
    useExternalPower: boolean;

    pullUpDesired: Readonly<GpioPins>;
    pullUpStatus: Readonly<GpioPins>;
    pullUpWhenActive: Readonly<GpioPins>;
    pullUpWhenInactive: Readonly<GpioPins>;
    pullDownDesired: Readonly<GpioPins>;
    pullDownStatus: Readonly<GpioPins>;
    pullDownWhenActive: Readonly<GpioPins>;
    pullDownWhenInactive: Readonly<GpioPins>;
    overCurrent: Readonly<GpioPins>;
    openLoad: Readonly<GpioPins>;
    faultsHistory5m: GpioModuleStatus;
    faultsHistory60m: GpioModuleStatus;
  };
}

Referenced enum values:

ts
export const GpioDeviceType = Enum(
  'GPIO_DEV_NONE',
  'GPIO_DEV_SSR_2P',
  'GPIO_DEV_SSR_1P',
  'GPIO_DEV_MECHANICAL_RELAY_2P',
  'GPIO_DEV_MECHANICAL_RELAY_1P_HIGH_SIDE',
  'GPIO_DEV_MECHANICAL_RELAY_1P_LOW_SIDE',
  'GPIO_DEV_COIL_2P',
  'GPIO_DEV_COIL_2P_BIDIRECTIONAL',
  'GPIO_DEV_COIL_1P_HIGH_SIDE',
  'GPIO_DEV_COIL_1P_LOW_SIDE',
  'GPIO_DEV_MOTOR_2P',
  'GPIO_DEV_MOTOR_2P_BIDIRECTIONAL',
  'GPIO_DEV_MOTOR_1P_HIGH_SIDE',
  'GPIO_DEV_MOTOR_1P_LOW_SIDE',
  'GPIO_DEV_DETECT_LOW_CURRENT_2P',
  'GPIO_DEV_DETECT_LOW_CURRENT_1P_GND',
  'GPIO_DEV_DETECT_HIGH_CURRENT_1P_POWER',
  'GPIO_DEV_DETECT_HIGH_CURRENT_1P_GND',
  'GPIO_DEV_DETECT_HIGH_CURRENT_2P',
  'GPIO_DEV_POWER_1P',
  'GPIO_DEV_GND_1P',
);

export enum GpioPins {
  NONE = 0,
  PIN_1 = 1 << 0,
  PIN_2 = 1 << 1,
  PIN_3 = 1 << 2,
  PIN_4 = 1 << 3,
  PIN_5 = 1 << 4,
  PIN_6 = 1 << 5,
  PIN_7 = 1 << 6,
  PIN_8 = 1 << 7,
}

export enum GpioModuleStatus {
  NONE = 0,
  POWER_ON_RESET = 1 << 0,
  OVERVOLTAGE = 1 << 1,
  UNDERVOLTAGE_LOCKOUT = 1 << 2,
  OVERCURRENT = 1 << 3,
  OPEN_LOAD = 1 << 4,
  OVERTEMPERATURE_WARNING = 1 << 5,
  OVERTEMPERATURE_SHUTDOWN = 1 << 6,
  SPI_ERROR = 1 << 7,
}

Pid

Pid reads a SetpointSensorPair setting and measured value, and calculates desired output for an analog actuator.

For a more in-depth explanation of how to use it, see the blocks guide.

ts
export interface PidBlock extends Block {
  type: 'Pid';
  data: {
    inputId: Link;
    outputId: Link;

    inputValue: Readonly<Quantity>;
    inputSetting: Readonly<Quantity>;
    outputValue: Readonly<number>;
    outputSetting: Readonly<number>;

    enabled: boolean;
    active: Readonly<boolean>;

    kp: Quantity;
    ti: Quantity;
    td: Quantity;

    p: Readonly<number>;
    i: Readonly<number>;
    d: Readonly<number>;

    error: Readonly<Quantity>;
    integral: Readonly<number>;
    derivative: Readonly<number>;
    derivativeFilter: Readonly<FilterChoice>;

    integralReset: number;

    boilPointAdjust: Quantity;
    boilMinOutput: number;
    boilModeActive: Readonly<boolean>;
  };
}

Referenced enum values:

ts
export const FilterChoice = Enum(
  'FILTER_NONE',
  'FILTER_15s',
  'FILTER_45s',
  'FILTER_90s',
  'FILTER_3m',
  'FILTER_10m',
  'FILTER_30m',
);

Sequence

Sequence implements bare-bones automation behavior, by running a sequential set of instructions. Instructions either set a value, or wait for a condition to be true. Combined, they can be used to to augment the SetpointProfile block or implement if-this-then-that functionality.

The activeInstruction field is readonly unless overrideState is set to true in a write or patch command.

Client-side, sequence instructions are edited using a line protocol. For syntax, and available instructions, see the sequence instructions page.

ts
export interface SequenceBlock extends Block {
  type: 'Sequence';
  data: {
    enabled: boolean;
    overrideState: boolean;
    activeInstruction: number;
    status: Readonly<SequenceStatus>;
    error: Readonly<SequenceError>;
    elapsed: Readonly<Quantity>;
    instructions: string[];
  };
}

Referenced enum values:

ts
export const SequenceStatus = Enum(
  'UNKNOWN',
  'DISABLED',
  'PAUSED',
  'NEXT',
  'WAITING',
  'END',
  'RESTART',
  'ERROR',
);
ts
export const SequenceError = Enum(
  'NONE',
  'INVALID_ARGUMENT',
  'INVALID_TARGET',
  'INACTIVE_TARGET',
  'DISABLED_TARGET',
  'SYSTEM_TIME_NOT_AVAILABLE',
);

SetpointProfile

The SetpointProfile drives a SetpointSensorPair to gradually change its setting over time.

For a more in-depth explanation of how to use it, see the blocks guide.

ts
export interface Setpoint {
  time: Quantity; // offset from start
  temperature: Quantity;
}

export interface SetpointProfileBlock extends Block {
  type: 'SetpointProfile';
  data: {
    start: DateString | null;
    points: Setpoint[];
    enabled: boolean;
    targetId: Link;
    setting: Readonly<Quantity>;
  };
}

SetpointSensorPair

This is the basic Setpoint block: it has a desired setting, and is linked to a temperature sensor.

The storedSetting field contains the last user-set setting. desiredSetting and setting will equal storedSetting unless the Setpoint is claimed.

The measured value is filtered to reduce jitter, but allows setting a step threshold to improve response time if the value has a legitimate sudden change.

ts
export interface SetpointSensorPairBlock extends Block {
  type: 'SetpointSensorPair';
  data: {
    enabled: boolean;
    sensorId: Link;

    storedSetting: Quantity;
    desiredSetting: Readonly<Quantity>;
    setting: Readonly<Quantity>;
    value: Readonly<Quantity>;
    valueUnfiltered: Readonly<Quantity>;

    filter: FilterChoice;
    filterThreshold: Quantity;
    resetFilter: boolean;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}

Referenced enum values:

ts
export const FilterChoice = Enum(
  'FILTER_NONE',
  'FILTER_15s',
  'FILTER_45s',
  'FILTER_90s',
  'FILTER_3m',
  'FILTER_10m',
  'FILTER_30m',
);

Spark2Pins

System object

The Spark2Pins object is only found on Spark 2 controllers, and provides an array of IoChannel objects.

ts
export interface Spark2PinsBlock extends Block {
  type: 'Spark2Pins';
  data: {
    soundAlarm: boolean;
    channels: Readonly<IoChannel[]>;
    hardware: Readonly<Spark2Hardware>;
  };
}

Referenced enum values:

ts
export const Spark2Hardware = Enum('HW_UNKNOWN', 'HW_SPARK1', 'HW_SPARK2');

Channel mapping:

ts
export const CHANNEL_NAMES_SPARK_2 = {
  1: 'Bottom 1',
  2: 'Bottom 2',
  3: 'Bottom 3',
  4: 'Bottom 0',
} as const;

Spark3Pins

System object

The Spark3Pins object is only found on Spark 3 controllers, and provides an array of IoChannel objects, along with settings regulating voltage.

ts
export interface Spark3PinsBlock extends Block {
  type: 'Spark3Pins';
  data: {
    enableIoSupply5V: boolean;
    enableIoSupply12V: boolean;
    soundAlarm: boolean;
    channels: Readonly<IoChannel[]>;
    voltage5: Readonly<number>;
    voltage12: Readonly<number>;
  };
}

Channel mapping:

ts
export const CHANNEL_NAMES_SPARK_3 = {
  1: 'Top 1',
  2: 'Top 2',
  3: 'Top 3',
  4: 'Bottom 1',
  5: 'Bottom 2',
} as const;

SysInfo

System object

Basic device info can be found here.

ts
export interface SysInfoBlock extends Block {
  type: 'SysInfo';
  data: {
    deviceId: Readonly<string>;
    version: Readonly<string>;
    platform: Readonly<SparkPlatform>;
    protocolVersion: Readonly<string>;
    releaseDate: Readonly<string>;
    protocolDate: Readonly<string>;
    ip: Readonly<string>;
    uptime: Readonly<Quantity>;
    updatesPerSecond: Readonly<number>;
    systemTime: DateString;
    timeZone: string;
    tempUnit: DisplayTempUnit;
    displayBrightness: number;
    voltage5: Readonly<number>;
    voltageExternal: Readonly<number>;
    memoryFree: Readonly<number>;
    memoryFreeContiguous: Readonly<number>;
    memoryFreeLowest: Readonly<number>;
  };
}

Referenced enum values:

ts
export const SparkPlatform = Enum(
  'PLATFORM_UNKNOWN',
  'PLATFORM_GCC',
  'PLATFORM_PHOTON',
  'PLATFORM_P1',
  'PLATFORM_ESP',
  'PLATFORM_SIM',
);
ts
export const DisplayTempUnit = Enum('TEMP_CELSIUS', 'TEMP_FAHRENHEIT');

TempSensorCombi

Accepts other temp sensors as input, and sets value to average/min/max of all connected sensors. Disconnected or unknown sensors are ignored.

A maximum of 8 sensors can be set. A TempSensorCombi can use other TempSensorCombi blocks as input.

ts
export interface TempSensorCombiBlock extends Block {
  type: 'TempSensorCombi';
  data: {
    value: Readonly<Quantity>;
    combineFunc: SensorCombiFunc;
    sensors: Link[];
  };
}

Referenced enum values:

ts
export const SensorCombiFunc = Enum(
  'SENSOR_COMBI_FUNC_AVG',
  'SENSOR_COMBI_FUNC_MIN',
  'SENSOR_COMBI_FUNC_MAX',
);

TempSensorExternal

A manually set sensor block, with added safety for unreliable sources. The enabled and timeout fields are persistent, but setting must be written regularly for the sensor to remain valid.

value will become invalid if enabled is false, or more than timeout has elapsed since the last time setting was written.

This timeout behavior can be disabled by setting the timeout field to 0.

ts
export interface TempSensorExternalBlock extends Block {
  type: 'TempSensorExternal';
  data: {
    enabled: boolean;
    timeout: Quantity;
    setting: Quantity;
    lastUpdated: Readonly<DateString | null>;
    value: Readonly<Quantity>;
  };
}

TempSensorMock

Can be used interchangeably with the TempSensorOneWire block, except that its setting is user-defined.

Fluctuations can be configured for improved simulation of real-world conditions.

ts
export interface Fluctuation {
  amplitude: Quantity;
  period: Quantity;
}

export interface TempSensorMockBlock extends Block {
  type: 'TempSensorMock';
  data: {
    connected: boolean;
    setting: Quantity;
    fluctuations: Fluctuation[];
    value: Readonly<Quantity>;
  };
}

TempSensorOneWire

Discovered object

The basic temperature sensor. An offset can be configured for calibration purposes.

ts
export interface TempSensorOneWireBlock extends Block {
  type: 'TempSensorOneWire';
  data: {
    offset: Quantity;
    address: string;
    value: Readonly<Quantity>;
    oneWireBusId: Readonly<Link>;
  };
}

TouchSettings

System object

ts
export interface TouchSettingsBlock extends Block {
  type: 'TouchSettings';
  data: {
    calibrated: TouchCalibrated;
    xOffset: number;
    yOffset: number;
    xBitsPerPixelX16: number;
    yBitsPerPixelX16: number;
  };
}

Referenced enum values:

ts
export const TouchCalibrated = Enum(
  'CALIBRATED_NO',
  'CALIBRATED_YES',
  'CALIBRATED_NEW',
);

Variables

Stores values that can be referenced by Sequence blocks.

ts
import {
  AnalogCompareOp,
  BlockOrIntfType,
  BlockType,
  DS2408ConnectMode,
  DigitalCompareOp,
  DigitalState,
  DisplayTempUnit,
  FilterChoice,
  GpioDeviceType,
  GpioModuleStatus,
  GpioPins,
  LogicResult,
  ReferenceKind,
  SensorCombiFunc,
  SequenceError,
  SequenceStatus,
  Spark2Hardware,
  SparkPlatform,
  TouchCalibrated,
  ValveState,
  WifiCipherType,
  WifiSecurityType,
  TransitionDurationPreset,
  PwmFrequency,
  ChannelCapabilities,
  SettingMode,
  ToggleBehavior,
} from './spark-block-enums';

// #region Block
export interface Block {
  id: string;
  nid?: number;
  serviceId: string;
  type: BlockType;
  data: { [k: string]: any };
  meta?: { [k: string]: any };
}
// #endregion Block

// #region BloxField
export interface BloxField {
  __bloxtype: string;
}

export interface Quantity extends BloxField {
  __bloxtype: 'Quantity';
  value: number | null;
  unit: string;
  readonly?: boolean;
}

export interface Link extends BloxField {
  __bloxtype: 'Link';
  id: string | null;
  type: BlockOrIntfType | null;
}
// #endregion BloxField

// #region DateString
export type DateString = string;
// #endregion DateString

// #region IoChannel
export interface IoChannel {
  id: number;
  capabilities: Readonly<ChannelCapabilities>;
  claimedBy: Readonly<Link>;
}

export interface IoArrayInterfaceBlock extends Block {
  data: {
    channels: IoChannel[];
  };
}

export interface IoDriverInterfaceBlock extends Block {
  data: {
    hwDevice: Link;
    channel: number;
  };
}
// #endregion IoChannel

// #region EnablerInterfaceBlock
export interface EnablerInterfaceBlock extends Block {
  data: {
    enabled: boolean;
  };
}
// #endregion EnablerInterfaceBlock

// #region ClaimableInterfaceBlock
export interface ClaimableInterfaceBlock extends Block {
  data: {
    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
// #endregion ClaimableInterfaceBlock

// #region AnalogConstraints
export interface AnalogConstraintBase {
  enabled: boolean;
  limiting: Readonly<boolean>;
}

export interface ValueConstraint extends AnalogConstraintBase {
  value: number;
}

export interface BalancedConstraint extends AnalogConstraintBase {
  balancerId: Link;
  granted: Readonly<number>;
}

export interface AnalogConstraints {
  min?: ValueConstraint;
  max?: ValueConstraint;
  balanced?: BalancedConstraint;
}
// #endregion AnalogConstraints

// #region DigitalConstraints
export interface DigitalConstraintBase {
  enabled: boolean;
  limiting: Readonly<boolean>;
  remaining: Readonly<Quantity>;
}

export interface DurationConstraint extends DigitalConstraintBase {
  duration: Quantity;
}

export interface MutexedConstraint extends DigitalConstraintBase {
  mutexId: Link;
  extraHoldTime: Quantity;
  hasLock: Readonly<boolean>;
}

export interface DigitalConstraints {
  minOff?: DurationConstraint;
  minOn?: DurationConstraint;
  delayedOff?: DurationConstraint;
  delayedOn?: DurationConstraint;
  mutexed?: MutexedConstraint;
}
// #endregion DigitalConstraints

// #region DeprecatedConstraints
export interface DeprecatedMinConstraint {
  limiting: Readonly<boolean>;
  min: number;
}

export interface DeprecatedMaxConstraint {
  limiting: Readonly<boolean>;
  max: number;
}

export interface DeprecatedBalancedConstraint {
  limiting: Readonly<boolean>;
  balanced: {
    balancerId: Link;
    granted: number;
  };
}

export interface DeprecatedMinOnConstraint {
  remaining: Readonly<Quantity>;
  minOn: Quantity;
}

export interface DeprecatedMinOffConstraint {
  remaining: Readonly<Quantity>;
  minOff: Quantity;
}

export interface DeprecatedMutexedConstraint {
  remaining: Readonly<Quantity>;
  mutexed: {
    mutexId: Link;
    extraHoldTime: Quantity;
    hasLock: boolean;
  };
}

export interface DeprecatedDelayedOnConstraint {
  remaining: Readonly<Quantity>;
  delayedOn: Quantity;
}

export interface DeprecatedDelayedOffConstraint {
  remaining: Readonly<Quantity>;
  delayedOff: Quantity;
}

export type DeprecatedAnalogConstraint =
  | DeprecatedMinConstraint
  | DeprecatedMaxConstraint
  | DeprecatedBalancedConstraint;

export type DeprecatedDigitalConstraint =
  | DeprecatedMutexedConstraint
  | DeprecatedMinOnConstraint
  | DeprecatedMinOffConstraint
  | DeprecatedDelayedOnConstraint
  | DeprecatedDelayedOffConstraint;

export interface DeprecatedAnalogConstraintsObj {
  constraints: DeprecatedAnalogConstraint[];
}

export interface DeprecatedDigitalConstraintsObj {
  constraints: DeprecatedDigitalConstraint[];
}
// #endregion DeprecatedConstraints

// #region ActuatorAnalogMock
export interface ActuatorAnalogMockBlock extends Block {
  type: 'ActuatorAnalogMock';
  data: {
    enabled: boolean;

    storedSetting: number;
    desiredSetting: Readonly<number>;
    setting: Readonly<number>;
    value: Readonly<number>;

    minSetting: number;
    maxSetting: number;
    minValue: number;
    maxValue: number;
    constraints?: AnalogConstraints;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
// #endregion ActuatorAnalogMock

// #region ActuatorLogic
export interface DigitalCompare {
  id: Link;
  op: DigitalCompareOp;
  rhs: DigitalState;
  result: Readonly<LogicResult>;
}

export interface AnalogCompare {
  id: Link;
  op: AnalogCompareOp;
  rhs: number;
  result: Readonly<LogicResult>;
}

export interface ActuatorLogicBlock extends Block {
  type: 'ActuatorLogic';
  data: {
    enabled: boolean;
    digital: DigitalCompare[]; // a-z
    analog: AnalogCompare[]; // A-Z
    expression: string; // a-zA-Z&|^!()

    result: Readonly<LogicResult>;
    errorPos: Readonly<number>;

    targetId: Link;
  };
}
// #endregion ActuatorLogic

// #region ActuatorOffset
export interface ActuatorOffsetBlock extends Block {
  type: 'ActuatorOffset';
  data: {
    enabled: boolean;
    targetId: Link;
    referenceId: Link;

    storedSetting: Quantity;
    desiredSetting: Readonly<Quantity>;
    setting: Readonly<Quantity>;
    value: Readonly<Quantity>;

    referenceSettingOrValue: ReferenceKind;
    constraints?: AnalogConstraints;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
// #endregion ActuatorOffset

// #region ActuatorPwm
export interface ActuatorPwmBlock extends Block {
  type: 'ActuatorPwm';
  data: {
    enabled: boolean;
    actuatorId: Link;

    storedSetting: number;
    desiredSetting: Readonly<number>;
    setting: Readonly<number>;
    value: Readonly<number>;

    period: Quantity;
    constraints?: AnalogConstraints;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
// #endregion ActuatorPwm

// #region Balancer
export interface BalancedActuator {
  id: Readonly<Link>;
  requested: Readonly<number>;
  granted: Readonly<number>;
}

export interface BalancerBlock extends Block {
  type: 'Balancer';
  data: {
    clients: Readonly<BalancedActuator[]>;
  };
}
// #endregion Balancer

// #region DeprecatedObject
export interface DeprecatedObjectBlock extends Block {
  type: 'DeprecatedObject';
  data: {
    actualId: Readonly<number>;
  };
}
// #endregion DeprecatedObject

// #region DigitalActuator
export interface DigitalActuatorBlock extends Block {
  type: 'DigitalActuator';
  data: {
    hwDevice: Link;
    channel: number;

    storedState: Readonly<DigitalState>;
    desiredState: Readonly<DigitalState | null>;
    state: Readonly<DigitalState | null>;

    invert: boolean;
    constraints?: DigitalConstraints;

    transitionDurationPreset: TransitionDurationPreset;
    transitionDurationSetting: Quantity;
    transitionDurationValue: Readonly<Quantity>;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
// #endregion DigitalActuator

// #region DisplaySettings
export interface DisplaySlot {
  pos: number; // 1-indexed
  color: string;
  name: string;

  // Value will be one of these
  tempSensor?: Link;
  setpointSensorPair?: Link;
  actuatorAnalog?: Link;
  pid?: Link;
}

export interface DisplaySettingsBlock extends Block {
  type: 'DisplaySettings';
  data: {
    name: string;
    widgets: DisplaySlot[];
  };
}
// #endregion DisplaySettings

// #region DS2408
export interface DS2408Block extends Block {
  type: 'DS2408';
  data: {
    address: string;
    channels: Readonly<IoChannel[]>;
    connectMode: DS2408ConnectMode;
    connected: Readonly<boolean>;
    oneWireBusId: Readonly<number>;
  };
}
// #endregion DS2408

// #region DS2413
export interface DS2413Block extends Block {
  type: 'DS2413';
  data: {
    address: string;
    channels: Readonly<IoChannel[]>;
    connected: Readonly<boolean>;
    oneWireBusId: Readonly<number>;
  };
}
// #endregion DS2413

// #region FastPwm
export interface FastPwmBlock extends Block {
  type: 'FastPwm';
  data: {
    enabled: boolean;

    hwDevice: Link;
    channel: number;

    storedSetting: number;
    desiredSetting: Readonly<number>;
    setting: Readonly<number>;
    value: Readonly<number>;

    invert: boolean;
    frequency: PwmFrequency;
    constraints?: AnalogConstraints;

    transitionDurationPreset: TransitionDurationPreset;
    transitionDurationSetting: Quantity;
    transitionDurationValue: Readonly<Quantity>;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
// #endregion FastPwm

// #region InactiveObject
export interface InactiveObjectBlock extends Block {
  type: 'InactiveObject';
  data: {
    actualType: BlockType;
  };
}
// #endregion InactiveObject

// #region MockPins
export interface MockPinsBlock extends Block {
  type: 'MockPins';
  data: {
    channels: Readonly<IoChannel[]>;
  };
}
// #endregion MockPins

// #region MotorValve
export interface MotorValveBlock extends Block {
  type: 'MotorValve';
  data: {
    hwDevice: Link;
    channel: number;

    storedState: DigitalState;
    desiredState: Readonly<DigitalState | null>;
    state: Readonly<DigitalState | null>;
    valveState: Readonly<ValveState | null>;

    constraints?: DigitalConstraints;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
// #endregion MotorValve

// #region Mutex
export interface MutexBlock extends Block {
  type: 'Mutex';
  data: {
    waitRemaining: Readonly<Quantity>;
  };
}
// #endregion Mutex

// #region OneWireBus
export interface OneWireBusCommand {
  opcode: number;
  data: number;
}

export interface OneWireBusBlock extends Block {
  type: 'OneWireBus';
  data: {
    command: OneWireBusCommand;
    address: Readonly<string[]>;
  };
}
// #endregion OneWireBus

// #region OneWireGpioModule
export interface GpioModuleChannel extends IoChannel {
  id: number;
  name: string;
  deviceType: GpioDeviceType;
  pinsMask: GpioPins;
  width: number;
}

export interface OneWireGpioModuleBlock extends Block {
  type: 'OneWireGpioModule';
  data: {
    channels: GpioModuleChannel[];
    modulePosition: number;
    moduleStatus: GpioModuleStatus;
    useExternalPower: boolean;

    pullUpDesired: Readonly<GpioPins>;
    pullUpStatus: Readonly<GpioPins>;
    pullUpWhenActive: Readonly<GpioPins>;
    pullUpWhenInactive: Readonly<GpioPins>;
    pullDownDesired: Readonly<GpioPins>;
    pullDownStatus: Readonly<GpioPins>;
    pullDownWhenActive: Readonly<GpioPins>;
    pullDownWhenInactive: Readonly<GpioPins>;
    overCurrent: Readonly<GpioPins>;
    openLoad: Readonly<GpioPins>;
    faultsHistory5m: GpioModuleStatus;
    faultsHistory60m: GpioModuleStatus;
  };
}
// #endregion OneWireGpioModule

// #region Pid
export interface PidBlock extends Block {
  type: 'Pid';
  data: {
    inputId: Link;
    outputId: Link;

    inputValue: Readonly<Quantity>;
    inputSetting: Readonly<Quantity>;
    outputValue: Readonly<number>;
    outputSetting: Readonly<number>;

    enabled: boolean;
    active: Readonly<boolean>;

    kp: Quantity;
    ti: Quantity;
    td: Quantity;

    p: Readonly<number>;
    i: Readonly<number>;
    d: Readonly<number>;

    error: Readonly<Quantity>;
    integral: Readonly<number>;
    derivative: Readonly<number>;
    derivativeFilter: Readonly<FilterChoice>;

    integralReset: number;

    boilPointAdjust: Quantity;
    boilMinOutput: number;
    boilModeActive: Readonly<boolean>;
  };
}
// #endregion Pid

// #region Sequence
export interface SequenceBlock extends Block {
  type: 'Sequence';
  data: {
    enabled: boolean;
    overrideState: boolean;
    activeInstruction: number;
    status: Readonly<SequenceStatus>;
    error: Readonly<SequenceError>;
    elapsed: Readonly<Quantity>;
    instructions: string[];
  };
}
// #endregion Sequence

// #region SetpointProfile
export interface Setpoint {
  time: Quantity; // offset from start
  temperature: Quantity;
}

export interface SetpointProfileBlock extends Block {
  type: 'SetpointProfile';
  data: {
    start: DateString | null;
    points: Setpoint[];
    enabled: boolean;
    targetId: Link;
    setting: Readonly<Quantity>;
  };
}
// #endregion SetpointProfile

// #region SetpointSensorPair
export interface SetpointSensorPairBlock extends Block {
  type: 'SetpointSensorPair';
  data: {
    enabled: boolean;
    sensorId: Link;

    storedSetting: Quantity;
    desiredSetting: Readonly<Quantity>;
    setting: Readonly<Quantity>;
    value: Readonly<Quantity>;
    valueUnfiltered: Readonly<Quantity>;

    filter: FilterChoice;
    filterThreshold: Quantity;
    resetFilter: boolean;

    claimedBy: Readonly<Link>;
    settingMode: SettingMode;
  };
}
// #endregion SetpointSensorPair

// #region Spark2Pins
export interface Spark2PinsBlock extends Block {
  type: 'Spark2Pins';
  data: {
    soundAlarm: boolean;
    channels: Readonly<IoChannel[]>;
    hardware: Readonly<Spark2Hardware>;
  };
}
// #endregion Spark2Pins

// #region Spark3Pins
export interface Spark3PinsBlock extends Block {
  type: 'Spark3Pins';
  data: {
    enableIoSupply5V: boolean;
    enableIoSupply12V: boolean;
    soundAlarm: boolean;
    channels: Readonly<IoChannel[]>;
    voltage5: Readonly<number>;
    voltage12: Readonly<number>;
  };
}
// #endregion Spark3Pins

// #region SysInfo
export interface SysInfoBlock extends Block {
  type: 'SysInfo';
  data: {
    deviceId: Readonly<string>;
    version: Readonly<string>;
    platform: Readonly<SparkPlatform>;
    protocolVersion: Readonly<string>;
    releaseDate: Readonly<string>;
    protocolDate: Readonly<string>;
    ip: Readonly<string>;
    uptime: Readonly<Quantity>;
    updatesPerSecond: Readonly<number>;
    systemTime: DateString;
    timeZone: string;
    tempUnit: DisplayTempUnit;
    displayBrightness: number;
    voltage5: Readonly<number>;
    voltageExternal: Readonly<number>;
    memoryFree: Readonly<number>;
    memoryFreeContiguous: Readonly<number>;
    memoryFreeLowest: Readonly<number>;
  };
}
// #endregion SysInfo

// #region TempSensorCombi
export interface TempSensorCombiBlock extends Block {
  type: 'TempSensorCombi';
  data: {
    value: Readonly<Quantity>;
    combineFunc: SensorCombiFunc;
    sensors: Link[];
  };
}
// #endregion TempSensorCombi

// #region TempSensorMock
export interface Fluctuation {
  amplitude: Quantity;
  period: Quantity;
}

export interface TempSensorMockBlock extends Block {
  type: 'TempSensorMock';
  data: {
    connected: boolean;
    setting: Quantity;
    fluctuations: Fluctuation[];
    value: Readonly<Quantity>;
  };
}
// #endregion TempSensorMock

// #region TempSensorOneWire
export interface TempSensorOneWireBlock extends Block {
  type: 'TempSensorOneWire';
  data: {
    offset: Quantity;
    address: string;
    value: Readonly<Quantity>;
    oneWireBusId: Readonly<Link>;
  };
}
// #endregion TempSensorOneWire

// #region TempSensorExternal
export interface TempSensorExternalBlock extends Block {
  type: 'TempSensorExternal';
  data: {
    enabled: boolean;
    timeout: Quantity;
    setting: Quantity;
    lastUpdated: Readonly<DateString | null>;
    value: Readonly<Quantity>;
  };
}
// #endregion TempSensorExternal

// #region TouchSettings
export interface TouchSettingsBlock extends Block {
  type: 'TouchSettings';
  data: {
    calibrated: TouchCalibrated;
    xOffset: number;
    yOffset: number;
    xBitsPerPixelX16: number;
    yBitsPerPixelX16: number;
  };
}
// #endregion TouchSettings

// #region WiFiSettings
export interface WiFiSettingsBlock extends Block {
  type: 'WiFiSettings';
  data: {
    signal: Readonly<number>; // dBm

    // Write-only values
    ssid: string;
    password: string;
    security: WifiSecurityType;
    cipher: WifiCipherType;
  };
}
// #endregion WiFiSettings

// #region DigitalInput
export interface DigitalInputBlock extends Block {
  type: 'DigitalInput';
  data: {
    hwDevice: Link;
    channel: number;
    state: Readonly<DigitalState | null>;
    invert: boolean;
    behavior: ToggleBehavior;
    minActiveTime: Quantity;
    hwState: Readonly<DigitalState | null>;
  };
}

// #endregion DigitalInput

WiFiSettings

System object

Wifi setting values are write-only, and will always be empty when read. This block is only present on Spark 2 and 3 controllers.

ts
export interface WiFiSettingsBlock extends Block {
  type: 'WiFiSettings';
  data: {
    signal: Readonly<number>; // dBm

    // Write-only values
    ssid: string;
    password: string;
    security: WifiSecurityType;
    cipher: WifiCipherType;
  };
}

Referenced enum values:

ts
export const WifiSecurityType = Enum(
  'WLAN_SEC_UNSEC',
  'WLAN_SEC_WEP',
  'WLAN_SEC_WPA',
  'WLAN_SEC_WPA2',
  'WLAN_SEC_WPA_ENTERPRISE',
  'WLAN_SEC_WPA2_ENTERPRISE',
  'WLAN_SEC_NOT_SET',
);

export const WifiCipherType = Enum(
  'WLAN_CIPHER_NOT_SET',
  'WLAN_CIPHER_AES',
  'WLAN_CIPHER_TKIP',
  'WLAN_CIPHER_AES_OR_TKIP',
);