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 (
priorityMinimum…priorityMaximum) the schedules in the set may use. Priority0is 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), andREGULATED(5)). The internal statesIDLE(1) andFAILSAFE(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
- Launch the development client as described in the FlexConnect API — First Steps.
- Navigate to
http://localhost:8080/ui. - Identify the power schedule set you want to use. If you do not yet know which sets are available to you, start with List Power Schedule Sets below.
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.
- Run the request on
app/v1/PowerScheduleSetListRequest. - Set
pagination.limitto the number of sets to return per page. - Leave
filter.scheduleSetIdsempty to retrieve all sets visible to you, or populate it to fetch specific sets by id. - Set
detailTypesto control which optional fields are included for each set (see the table below).
Request body
{
"header": {
"reqId": 1234,
"timeoutMs": 10000
},
"pagination": {
"limit": 100
},
"filter": {
"scheduleSetIds": []
},
"detailTypes": [1]
}Request fields
| Field | Description |
|---|---|
header.reqId | Client-defined identifier for the request. The same value is returned in the response header. |
header.timeoutMs | Maximum time (in milliseconds) the platform waits for the result before responding with a timeout error. |
pagination.limit | Maximum number of schedule sets returned in a single response. |
pagination.cursorValue | Cursor value returned in a previous response as cursorNext or cursorPrevious. Use it to iterate through large result sets. |
filter.scheduleSetIds | If non-empty, only schedule sets with these ids are returned. If empty, all schedule sets visible to your authentication are returned. |
detailTypes | List of optional detail types to include in the response. See detailTypes values. |
detailTypes values
| Value | Code | Description |
|---|---|---|
| 1 | NAMES | Include the human-readable names of associated groups, tags, and attributes in the response (otherwise only the ids are returned). |
Response body
{
"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
| Field | Description |
|---|---|
scheduleSets[].id | Identifier of the schedule set. Use this value as scheduleSetId when creating a power schedule. |
scheduleSets[].name | Human-readable name of the schedule set. |
scheduleSets[].description | Description of the schedule set, typically explaining its intended use. |
scheduleSets[].constraints | Priority range (priorityMinimum/priorityMaximum) and the list of controlStates allowed for schedules in this set. |
scheduleSets[].groups | Groups the schedule set belongs to. Names are only returned when detailTypes includes 1 (NAMES). |
scheduleSets[].tags | Tags associated with the schedule set. Names are only returned when detailTypes includes 1 (NAMES). |
scheduleSets[].attributes | Additional key/value metadata attached to the schedule set. Names are only returned when detailTypes includes 1 (NAMES). |
scheduleSets[].permissions | Permissions your authentication has on this schedule set. |
pagination.cursorNext / cursorPrevious | Returned 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.
- Run the request on
app/v1/PowerScheduleCreateRequest. - Replace
scheduleSetIdwith the identifier of the power schedule set you want to create the schedule in. UsePowerScheduleSetListRequestif you need to look it up. - Adjust the
definitionto describe the schedule you want to create:priority— a value within thepriorityMinimum/priorityMaximumrange 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 theconstraints.controlStatesof the target schedule set.elements— one or more time ranges with a desired power setpoint (or desired energy).
Request body
{
"header": {
"reqId": 1234,
"timeoutMs": 10000
},
"scheduleSetId": 10,
"definition": {
"priority": 35,
"controlState": 3,
"elements": [
{
"startTime": 1740268800,
"endTime": 1740285000,
"desiredPowerSetpoint": {
"number": 600,
"scale": 0
}
}
]
}
}Request fields
| Field | Description |
|---|---|
header.reqId | Client-defined identifier for the request. The same value is returned in the response header to correlate requests and responses. |
header.timeoutMs | Maximum time (in milliseconds) the platform waits for the result before responding with a timeout error. |
scheduleSetId | Identifier of the schedule set this schedule belongs to. |
definition.priority | Priority 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.controlState | The control state represented by this schedule. See controlState values. |
definition.elements | One or more schedule elements, each with startTime, endTime, and either desiredPowerSetpoint or desiredEnergy. |
controlState values
| Value | Code | Description |
|---|---|---|
| 3 | POWER | Power control state. Charge and discharge commands are defined by the desired power setpoint of the active element. |
| 4 | LOCAL | PCC ("Point of Common Coupling") control state. |
| 5 | REGULATED | The 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:
| Field | Description |
|---|---|
startTime | Start of the element in seconds since epoch, inclusive. |
endTime | End of the element in seconds since epoch, exclusive. |
desiredPowerSetpoint | Desired power in Watts. Positive values represent charging, negative values represent discharging. Mutually exclusive with desiredEnergy. |
desiredEnergy | Desired 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
{
"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.
- Run the request on
app/v1/PowerScheduleListRequest. - Set the
pagination.limitto the number of schedules you want returned per page. - Use the
filterto narrow the result:- Leave both arrays empty (
[]) to retrieve all schedules visible to you. - Populate
scheduleIdsto fetch a specific subset of schedules by id. - Populate
scheduleSetIdsto fetch all schedules belonging to one or more schedule sets.
- Leave both arrays empty (
Request body
{
"header": {
"reqId": 1234,
"timeoutMs": 10000
},
"pagination": {
"limit": 20
},
"filter": {
"scheduleIds": [],
"scheduleSetIds": []
}
}Request fields
| Field | Description |
|---|---|
header.reqId | Client-defined identifier for the request. |
header.timeoutMs | Maximum time (in milliseconds) the platform waits for the result before responding with a timeout error. |
pagination.limit | Maximum number of schedules returned in a single response. |
pagination.cursorValue | Cursor value returned in a previous response as cursorNext or cursorPrevious. Use it to iterate through large result sets. |
filter.scheduleIds | If non-empty, only schedules with these ids are returned. |
filter.scheduleSetIds | If non-empty, only schedules belonging to these schedule sets are returned. |
Response body
{
"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 itsid,scheduleSetId, and fulldefinition.pagination.cursorNext/pagination.cursorPrevious— present when the result set is larger than the requestedlimit. Pass the value aspagination.cursorValuein a follow-up request to retrieve the next or previous page.
End-to-end Example
A common workflow combines all three requests:
- Send
PowerScheduleSetListRequestto discover the schedule sets available to your customer account and pick theid(scheduleSetId) of the set you want to operate in. Note itsconstraints(priority range and allowed control states). - Send
PowerScheduleCreateRequestfor thatscheduleSetIdto create a new schedule, and capture the returnedschedule.id. - Send
PowerScheduleListRequest(filtered byscheduleSetIds) to verify the schedule is present and inspect its definition. - Apply that
idto one or more nodes viaNodeControlPowerScheduleModifyRequest(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. - Send a
NodeStateListRequestwithdetailTypesincludingPOWER_STATE(5) to confirm thescheduleIdreturned inpowerState.state.scheduleIdmatches 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.