Skip to content

Power Schedules

A power schedule defines one or more time ranges in which a battery is to charge or discharge with a specific setpoint. Each schedule belongs to a power schedule set, which acts as the container that groups related schedules and defines the rules under which those schedules may operate.

This page walks through the three most common operations:

  • Listing the power schedule sets that are available to you with PowerScheduleSetListRequest.
  • Creating a new power schedule within a set with PowerScheduleCreateRequest.
  • Listing existing power schedules with PowerScheduleListRequest.

Power Schedule Sets

A power schedule set is provisioned per customer by the FlexHome․Energy cloud team. Each customer receives one or more schedule sets that define:

  • Which priority range (priorityMinimumpriorityMaximum) the schedules in the set may use. Priority 0 is reserved for the firmware default schedule and cannot be assigned by the platform.
  • Which control states the schedules in the set may set (a subset of POWER (3), LOCAL (4), and REGULATED (5)). The internal states IDLE (1) and FAILSAFE (2) are set exclusively by the FlexNode and cannot be specified in a schedule.
  • Which nodes the schedules apply to. The mapping between schedule sets and nodes is managed by FlexHome․Energy as part of customer onboarding.
  • Optional groups, tags, and attributes for organising sets, plus the permissions your authentication has on the set.

Every power schedule that you create with PowerScheduleCreateRequest is created inside one specific schedule set, referenced by its scheduleSetId. The constraints of that set are enforced when the schedule is created — for example, a schedule whose priority is outside the set's range, or whose controlState is not allowed for the set, is rejected.

Where do schedule sets come from?

You do not create schedule sets yourself in normal operation. The FlexHome․Energy cloud team creates the schedule set(s) for your customer account when you are onboarded and communicates the resulting scheduleSetId. Use PowerScheduleSetListRequest (see below) at any time to look up the sets and their constraints.

Preparations

List Power Schedule Sets

Use PowerScheduleSetListRequest to discover the power schedule sets that are available to your customer account and to inspect the constraints (priority range, allowed control states) that apply to schedules within each set.

  1. Run the request on app/v1/PowerScheduleSetListRequest.
  2. Set pagination.limit to the number of sets to return per page.
  3. Leave filter.scheduleSetIds empty to retrieve all sets visible to you, or populate it to fetch specific sets by id.
  4. Set detailTypes to control which optional fields are included for each set (see the table below).

Request body

json
{
  "header": {
    "reqId": 1234,
    "timeoutMs": 10000
  },
  "pagination": {
    "limit": 100
  },
  "filter": {
    "scheduleSetIds": []
  },
  "detailTypes": [1]
}

Request fields

FieldDescription
header.reqIdClient-defined identifier for the request. The same value is returned in the response header.
header.timeoutMsMaximum time (in milliseconds) the platform waits for the result before responding with a timeout error.
pagination.limitMaximum number of schedule sets returned in a single response.
pagination.cursorValueCursor value returned in a previous response as cursorNext or cursorPrevious. Use it to iterate through large result sets.
filter.scheduleSetIdsIf non-empty, only schedule sets with these ids are returned. If empty, all schedule sets visible to your authentication are returned.
detailTypesList of optional detail types to include in the response. See detailTypes values.

detailTypes values

ValueCodeDescription
1NAMESInclude the human-readable names of associated groups, tags, and attributes in the response (otherwise only the ids are returned).

Response body

json
{
  "header": {
    "reqId": 1234
  },
  "scheduleSets": [
    {
      "id": 10,
      "name": "Energy-trading schedule-set 1",
      "description": "This set is used for energy trading related power schedules.",
      "constraints": {
        "priorityMinimum": 10,
        "priorityMaximum": 59,
        "controlStates": [3, 4]
      },
      "groups": [{ "id": 1, "name": "Energy-trading" }],
      "tags": [{ "id": 1, "name": "Energy-trading" }],
      "attributes": [
        {
          "id": 1,
          "name": "Energy-trading",
          "value": "This set is used for energy trading related power schedules."
        }
      ],
      "permissions": [{ "permissionTypeId": 1, "permissionCodeId": 1 }]
    }
  ]
}

Response fields

FieldDescription
scheduleSets[].idIdentifier of the schedule set. Use this value as scheduleSetId when creating a power schedule.
scheduleSets[].nameHuman-readable name of the schedule set.
scheduleSets[].descriptionDescription of the schedule set, typically explaining its intended use.
scheduleSets[].constraintsPriority range (priorityMinimum/priorityMaximum) and the list of controlStates allowed for schedules in this set.
scheduleSets[].groupsGroups the schedule set belongs to. Names are only returned when detailTypes includes 1 (NAMES).
scheduleSets[].tagsTags associated with the schedule set. Names are only returned when detailTypes includes 1 (NAMES).
scheduleSets[].attributesAdditional key/value metadata attached to the schedule set. Names are only returned when detailTypes includes 1 (NAMES).
scheduleSets[].permissionsPermissions your authentication has on this schedule set.
pagination.cursorNext / cursorPreviousReturned when the result set is larger than limit. Pass either value as pagination.cursorValue in a follow-up request to paginate.

Read the constraints before creating schedules

Before sending PowerScheduleCreateRequest, read the constraints of your target schedule set: pick a priority inside [priorityMinimum, priorityMaximum], and a controlState that is listed in controlStates. Schedules that violate these constraints are rejected.

Create a Power Schedule

Run the PowerScheduleCreateRequest using the JSON body below.

  1. Run the request on app/v1/PowerScheduleCreateRequest.
  2. Replace scheduleSetId with the identifier of the power schedule set you want to create the schedule in. Use PowerScheduleSetListRequest if you need to look it up.
  3. Adjust the definition to describe the schedule you want to create:
    • priority — a value within the priorityMinimum/priorityMaximum range of the target schedule set. The schedule with the highest priority that has an element matching the current time wins.
    • controlState — the control state to apply (see the table below). Must be one of the control states listed in the constraints.controlStates of the target schedule set.
    • elements — one or more time ranges with a desired power setpoint (or desired energy).

Request body

json
{
  "header": {
    "reqId": 1234,
    "timeoutMs": 10000
  },
  "scheduleSetId": 10,
  "definition": {
    "priority": 35,
    "controlState": 3,
    "elements": [
      {
        "startTime": 1740268800,
        "endTime": 1740285000,
        "desiredPowerSetpoint": {
          "number": 600,
          "scale": 0
        }
      }
    ]
  }
}

Request fields

FieldDescription
header.reqIdClient-defined identifier for the request. The same value is returned in the response header to correlate requests and responses.
header.timeoutMsMaximum time (in milliseconds) the platform waits for the result before responding with a timeout error.
scheduleSetIdIdentifier of the schedule set this schedule belongs to.
definition.priorityPriority of the schedule (1..n). The schedule with the highest priority whose element covers the current time is applied. Priority 0 is reserved for the firmware default schedule.
definition.controlStateThe control state represented by this schedule. See controlState values.
definition.elementsOne or more schedule elements, each with startTime, endTime, and either desiredPowerSetpoint or desiredEnergy.

controlState values

ValueCodeDescription
3POWERPower control state. Charge and discharge commands are defined by the desired power setpoint of the active element.
4LOCALPCC ("Point of Common Coupling") control state.
5REGULATEDThe ESS is controlled by a regulation authority (such as a grid operator).

Not settable externally

The control states IDLE (1) and FAILSAFE (2) cannot be set through PowerScheduleCreateRequest. They are set exclusively by the FlexNode.

Schedule elements

Each element in definition.elements defines a single time range:

FieldDescription
startTimeStart of the element in seconds since epoch, inclusive.
endTimeEnd of the element in seconds since epoch, exclusive.
desiredPowerSetpointDesired power in Watts. Positive values represent charging, negative values represent discharging. Mutually exclusive with desiredEnergy.
desiredEnergyDesired total energy in Watt-hours that the battery should import or export within the time range. Positive values represent charging, negative values represent discharging. Mutually exclusive with desiredPowerSetpoint.

Scaled numbers

desiredPowerSetpoint and desiredEnergy are scaled numbers. The actual value equals number × 10^scale. A missing scale is treated as 0.

Response body

json
{
  "header": {
    "reqId": 1234
  },
  "schedule": {
    "id": 582,
    "scheduleSetId": 10,
    "definition": {
      "priority": 35,
      "controlState": 3,
      "elements": [
        {
          "startTime": 1740268800,
          "endTime": 1740285000,
          "desiredPowerSetpoint": {
            "number": 600,
            "scale": 0
          }
        }
      ]
    }
  }
}

The response contains the created schedule including the server-assigned id. Store this id to reference the schedule in later operations (for example, when applying it to nodes via NodeControlPowerScheduleModifyRequest).

TIP

The scheduleId returned in the powerState of a NodeStateListResponse matches the id returned here. That is how you confirm a schedule is currently in effect on a node.

List Power Schedules

Run the PowerScheduleListRequest using the JSON body below.

  1. Run the request on app/v1/PowerScheduleListRequest.
  2. Set the pagination.limit to the number of schedules you want returned per page.
  3. Use the filter to narrow the result:
    • Leave both arrays empty ([]) to retrieve all schedules visible to you.
    • Populate scheduleIds to fetch a specific subset of schedules by id.
    • Populate scheduleSetIds to fetch all schedules belonging to one or more schedule sets.

Request body

json
{
  "header": {
    "reqId": 1234,
    "timeoutMs": 10000
  },
  "pagination": {
    "limit": 20
  },
  "filter": {
    "scheduleIds": [],
    "scheduleSetIds": []
  }
}

Request fields

FieldDescription
header.reqIdClient-defined identifier for the request.
header.timeoutMsMaximum time (in milliseconds) the platform waits for the result before responding with a timeout error.
pagination.limitMaximum number of schedules returned in a single response.
pagination.cursorValueCursor value returned in a previous response as cursorNext or cursorPrevious. Use it to iterate through large result sets.
filter.scheduleIdsIf non-empty, only schedules with these ids are returned.
filter.scheduleSetIdsIf non-empty, only schedules belonging to these schedule sets are returned.

Response body

json
{
  "header": {
    "reqId": 1234
  },
  "pagination": {
    "cursorNext": "1wsf="
  },
  "schedules": [
    {
      "id": 582,
      "scheduleSetId": 10,
      "definition": {
        "priority": 35,
        "controlState": 3,
        "elements": [
          {
            "startTime": 1740268800,
            "endTime": 1740285000,
            "desiredPowerSetpoint": { "number": 600, "scale": 0 }
          }
        ]
      }
    },
    {
      "id": 583,
      "scheduleSetId": 10,
      "definition": {
        "priority": 35,
        "controlState": 3,
        "elements": [
          {
            "startTime": 1740285000,
            "endTime": 1740301200,
            "desiredEnergy": { "number": -1200, "scale": 0 }
          }
        ]
      }
    }
  ]
}

Response fields

  • schedules — the list of power schedules matching the filter, each one carrying its id, scheduleSetId, and full definition.
  • pagination.cursorNext / pagination.cursorPrevious — present when the result set is larger than the requested limit. Pass the value as pagination.cursorValue in a follow-up request to retrieve the next or previous page.

End-to-end Example

A common workflow combines all three requests:

  1. Send PowerScheduleSetListRequest to discover the schedule sets available to your customer account and pick the id (scheduleSetId) of the set you want to operate in. Note its constraints (priority range and allowed control states).
  2. Send PowerScheduleCreateRequest for that scheduleSetId to create a new schedule, and capture the returned schedule.id.
  3. Send PowerScheduleListRequest (filtered by scheduleSetIds) to verify the schedule is present and inspect its definition.
  4. Apply that id to one or more nodes via NodeControlPowerScheduleModifyRequest (Variant B). Alternatively, you can skip steps 2 and 3 and use Variant A of the same request to create and apply an ad-hoc schedule in a single call.
  5. Send a NodeStateListRequest with detailTypes including POWER_STATE (5) to confirm the scheduleId returned in powerState.state.scheduleId matches the schedule you just applied.

Element ordering and replacement rules

  • No overlapping elements. The backend rejects schedules whose elements overlap in time.
  • Ascending order. The elements of a schedule must be sorted in ascending order by startTime.
  • Replacement by priority. Applying a schedule replaces any existing schedule with the same priority on each target node. To run multiple schedules in parallel on the same node, assign them different priorities.